summaryrefslogtreecommitdiffstats
path: root/vpp-api/java/jvpp/gen
diff options
context:
space:
mode:
Diffstat (limited to 'vpp-api/java/jvpp/gen')
-rw-r--r--vpp-api/java/jvpp/gen/callback_gen.py19
-rw-r--r--vpp-api/java/jvpp/gen/dto_gen.py93
-rw-r--r--vpp-api/java/jvpp/gen/jvpp_c_gen.py36
-rw-r--r--vpp-api/java/jvpp/gen/jvpp_callback_facade_gen.py52
-rw-r--r--vpp-api/java/jvpp/gen/jvpp_future_facade_gen.py128
-rwxr-xr-xvpp-api/java/jvpp/gen/jvpp_gen.py9
-rw-r--r--vpp-api/java/jvpp/gen/jvpp_impl_gen.py4
-rw-r--r--vpp-api/java/jvpp/gen/notification_gen.py164
-rw-r--r--vpp-api/java/jvpp/gen/util.py22
9 files changed, 392 insertions, 135 deletions
diff --git a/vpp-api/java/jvpp/gen/callback_gen.py b/vpp-api/java/jvpp/gen/callback_gen.py
index 8a0d20124ae..eadf3b5c50d 100644
--- a/vpp-api/java/jvpp/gen/callback_gen.py
+++ b/vpp-api/java/jvpp/gen/callback_gen.py
@@ -31,7 +31,7 @@ package $base_package.$callback_package;
$docs
* </pre>
*/
-public interface $cls_name extends $base_package.$callback_package.JVppCallback {
+public interface $cls_name extends $base_package.$callback_package.$callback_type {
$callback_method
@@ -61,15 +61,21 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package, i
callbacks = []
for func in func_list:
- if util.is_notification(func['name']) or util.is_ignored(func['name']):
- # FIXME handle notifications
+ if util.is_ignored(func['name']):
continue
camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
- if not util.is_reply(camel_case_name_with_suffix):
+ if not util.is_reply(camel_case_name_with_suffix) and not util.is_notification(func['name']):
continue
- camel_case_name = util.remove_reply_suffix(camel_case_name_with_suffix)
+ if util.is_reply(camel_case_name_with_suffix):
+ camel_case_name = util.remove_reply_suffix(camel_case_name_with_suffix)
+ callback_type = "JVppCallback"
+ else:
+ camel_case_name_with_suffix = util.add_notification_suffix(camel_case_name_with_suffix)
+ camel_case_name = camel_case_name_with_suffix
+ callback_type = "JVppNotificationCallback"
+
callbacks.append("{0}.{1}.{2}".format(base_package, callback_package, camel_case_name + callback_suffix))
callback_path = os.path.join(callback_package, camel_case_name + callback_suffix + ".java")
callback_file = open(callback_path, 'w')
@@ -82,7 +88,8 @@ def generate_callbacks(func_list, base_package, callback_package, dto_package, i
cls_name=camel_case_name + callback_suffix,
callback_method=method,
base_package=base_package,
- callback_package=callback_package))
+ callback_package=callback_package,
+ callback_type=callback_type))
callback_file.flush()
callback_file.close()
diff --git a/vpp-api/java/jvpp/gen/dto_gen.py b/vpp-api/java/jvpp/gen/dto_gen.py
index 05859dbe83a..426cd96b2ac 100644
--- a/vpp-api/java/jvpp/gen/dto_gen.py
+++ b/vpp-api/java/jvpp/gen/dto_gen.py
@@ -13,9 +13,11 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import os, util
+import os
from string import Template
+import util
+
dto_template = Template("""
package $base_package.$dto_package;
@@ -40,6 +42,7 @@ send_template = Template(""" @Override
return jvpp.$method_name($args);
}\n""")
+
def generate_dtos(func_list, base_package, dto_package, inputfile):
""" Generates dto objects in a dedicated package """
print "Generating DTOs"
@@ -52,8 +55,7 @@ def generate_dtos(func_list, base_package, dto_package, inputfile):
camel_case_method_name = util.underscore_to_camelcase(func['name'])
dto_path = os.path.join(dto_package, camel_case_dto_name + ".java")
- if util.is_notification(func['name']) or util.is_ignored(func['name']):
- # TODO handle notifications
+ if util.is_ignored(func['name']):
continue
fields = ""
@@ -66,44 +68,63 @@ def generate_dtos(func_list, base_package, dto_package, inputfile):
name=field_name)
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
- base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name + "Dump")
- generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_case_dto_name,
- camel_case_method_name, func)
- else:
- base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name)
- else:
- args = "" if fields is "" else "this"
- methods = send_template.substitute(method_name=camel_case_method_name,
- base_package=base_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(inputfile=inputfile,
- description=description,
- docs=util.api_message_to_javadoc(func),
- cls_name=camel_case_dto_name,
- fields=fields,
- methods=methods,
- base_package=base_package,
- base_type=base_type,
- dto_package=dto_package))
- dto_file.flush()
- dto_file.close()
+ # Generate request/reply or dump/dumpReply even if structure can be used as notification
+ if not util.is_just_notification(func["name"]):
+ 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
+ base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name + "Dump")
+ generate_dump_reply_dto(request_dto_name, base_package, dto_package, camel_case_dto_name,
+ camel_case_method_name, func)
+ else:
+ base_type += "JVppReply<%s.%s.%s>" % (base_package, dto_package, request_dto_name)
+ else:
+ args = "" if fields is "" else "this"
+ methods = send_template.substitute(method_name=camel_case_method_name,
+ base_package=base_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"
+
+ write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func,
+ inputfile, methods)
+
+ # for structures that are also used as notifications, generate dedicated notification DTO
+ if util.is_notification(func["name"]):
+ base_type = "JVppNotification"
+ description = "vpe.api notification DTO"
+ camel_case_dto_name = util.add_notification_suffix(camel_case_dto_name)
+ methods = ""
+ dto_path = os.path.join(dto_package, camel_case_dto_name + ".java")
+ write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func,
+ inputfile, methods)
flush_dump_reply_dtos(inputfile)
+def write_dto_file(base_package, base_type, camel_case_dto_name, description, dto_package, dto_path, fields, func,
+ inputfile, methods):
+ dto_file = open(dto_path, 'w')
+ 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,
+ base_package=base_package,
+ base_type=base_type,
+ dto_package=dto_package))
+ dto_file.flush()
+ dto_file.close()
+
+
dump_dto_suffix = "ReplyDump"
dump_reply_artificial_dtos = {}
diff --git a/vpp-api/java/jvpp/gen/jvpp_c_gen.py b/vpp-api/java/jvpp/gen/jvpp_c_gen.py
index 082fd5d73ae..c006c34103b 100644
--- a/vpp-api/java/jvpp/gen/jvpp_c_gen.py
+++ b/vpp-api/java/jvpp/gen/jvpp_c_gen.py
@@ -53,16 +53,21 @@ def generate_class_cache(func_list):
class_name = util.underscore_to_camelcase_upper(c_name)
ref_name = util.underscore_to_camelcase(c_name)
- if not util.is_reply(class_name) or util.is_ignored(c_name) or util.is_notification(c_name):
- # TODO handle notifications
+ if util.is_ignored(c_name):
continue
- class_references.append(class_reference_template.substitute(
+ if util.is_reply(class_name):
+ class_references.append(class_reference_template.substitute(
ref_name=ref_name))
-
- find_class_invocations.append(find_class_invocation_template.substitute(
+ find_class_invocations.append(find_class_invocation_template.substitute(
ref_name=ref_name,
class_name=class_name))
+ elif util.is_notification(c_name):
+ class_references.append(class_reference_template.substitute(
+ ref_name=util.add_notification_suffix(ref_name)))
+ find_class_invocations.append(find_class_invocation_template.substitute(
+ ref_name=util.add_notification_suffix(ref_name),
+ class_name=util.add_notification_suffix(class_name)))
# add exception class to class cache
ref_name = 'callbackException'
@@ -73,7 +78,7 @@ def generate_class_cache(func_list):
ref_name=ref_name,
class_name=class_name))
return class_cache_template.substitute(
- class_references="".join(class_references), find_class_invocations="".join(find_class_invocations))
+ class_references="".join(class_references), find_class_invocations="".join(find_class_invocations))
# TODO: cache method and field identifiers to achieve better performance
@@ -174,7 +179,7 @@ def generate_jni_impl(func_list, inputfile):
f_name = f['name']
camel_case_function_name = util.underscore_to_camelcase(f_name)
if is_manually_generated(f_name) or util.is_reply(camel_case_function_name) \
- or util.is_ignored(f_name) or util.is_notification(f_name):
+ or util.is_ignored(f_name) or util.is_just_notification(f_name):
continue
arguments = ''
@@ -331,10 +336,16 @@ def generate_msg_handlers(func_list, inputfile):
dto_name = util.underscore_to_camelcase_upper(handler_name)
ref_name = util.underscore_to_camelcase(handler_name)
- if is_manually_generated(handler_name) or not util.is_reply(dto_name) or util.is_ignored(handler_name) or util.is_notification(handler_name):
- # TODO handle notifications
+ if is_manually_generated(handler_name) or util.is_ignored(handler_name):
+ continue
+
+ if not util.is_reply(dto_name) and not util.is_notification(handler_name):
continue
+ if util.is_notification(handler_name):
+ dto_name = util.add_notification_suffix(dto_name)
+ ref_name = util.add_notification_suffix(ref_name)
+
dto_setters = ''
err_handler = ''
# dto setters
@@ -391,13 +402,12 @@ def generate_handler_registration(func_list):
name = f['name']
camelcase_name = util.underscore_to_camelcase(f['name'])
- if not util.is_reply(camelcase_name) or util.is_ignored(name) or util.is_notification(name):
- # TODO handle notifications
+ if (not util.is_reply(camelcase_name) and not util.is_notification(name)) or util.is_ignored(name):
continue
handler_registration.append(handler_registration_template.substitute(
- name=name,
- upercase_name=name.upper()))
+ name=name,
+ upercase_name=name.upper()))
return "".join(handler_registration)
diff --git a/vpp-api/java/jvpp/gen/jvpp_callback_facade_gen.py b/vpp-api/java/jvpp/gen/jvpp_callback_facade_gen.py
index acf29eb85b8..7df17486a60 100644
--- a/vpp-api/java/jvpp/gen/jvpp_callback_facade_gen.py
+++ b/vpp-api/java/jvpp/gen/jvpp_callback_facade_gen.py
@@ -27,7 +27,7 @@ package $base_package.$callback_facade_package;
* <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 {
+public interface CallbackJVpp extends $base_package.$notification_package.NotificationRegistryProvider, java.lang.AutoCloseable {
@Override
void close();
@@ -46,7 +46,7 @@ package $base_package.$callback_facade_package;
* <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 {
+public final class CallbackJVppFacade extends $base_package.$notification_package.NotificationRegistryProviderContext implements $base_package.$callback_facade_package.CallbackJVpp {
private final $base_package.JVpp jvpp;
private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> callbacks;
@@ -63,7 +63,7 @@ public final class CallbackJVppFacade implements $base_package.$callback_facade_
public CallbackJVppFacade(final $base_package.JVpp jvpp) throws java.io.IOException {
this.jvpp = java.util.Objects.requireNonNull(jvpp,"jvpp is null");
this.callbacks = new java.util.HashMap<>();
- this.jvpp.connect(new CallbackJVppFacadeCallback(this.callbacks));
+ this.jvpp.connect(new CallbackJVppFacadeCallback(this.callbacks, getNotificationCallback()));
}
@Override
@@ -95,7 +95,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, inputfile):
+def generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile):
""" Generates callback facade """
print "Generating JVpp callback facade"
@@ -152,6 +152,7 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
methods="\n".join(methods),
base_package=base_package,
dto_package=dto_package,
+ notification_package=notification_package,
callback_facade_package=callback_facade_package))
jvpp_file.flush()
jvpp_file.close()
@@ -161,12 +162,13 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, callba
methods="\n".join(methods_impl),
base_package=base_package,
dto_package=dto_package,
+ notification_package=notification_package,
callback_package=callback_package,
callback_facade_package=callback_facade_package))
jvpp_file.flush()
jvpp_file.close()
- generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile)
+ generate_callback(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile)
jvpp_facade_callback_template = Template("""
@@ -180,10 +182,13 @@ package $base_package.$callback_facade_package;
public final class CallbackJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requests;
+ private final $base_package.$notification_package.GlobalNotificationCallback notificationCallback;
private static final java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(CallbackJVppFacadeCallback.class.getName());
- public CallbackJVppFacadeCallback(final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requestMap) {
+ public CallbackJVppFacadeCallback(final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requestMap,
+ final $base_package.$notification_package.GlobalNotificationCallback notificationCallback) {
this.requests = requestMap;
+ this.notificationCallback = notificationCallback;
}
@Override
@@ -224,29 +229,44 @@ jvpp_facade_callback_method_template = Template("""
}
""")
+jvpp_facade_callback_notification_method_template = Template("""
+ @Override
+ @SuppressWarnings("unchecked")
+ public void on$callback_dto($base_package.$dto_package.$callback_dto notification) {
+ notificationCallback.on$callback_dto(notification);
+ }
+""")
-def generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package, inputfile):
+
+def generate_callback(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, inputfile):
callbacks = []
for func in func_list:
- if util.is_notification(func['name']) or util.is_ignored(func['name']):
- # TODO handle notifications
+ if util.is_ignored(func['name']):
continue
camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
- if not util.is_reply(camel_case_name_with_suffix):
- continue
- callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
- dto_package=dto_package,
- callback_package=callback_package,
- callback=util.remove_reply_suffix(camel_case_name_with_suffix) + callback_gen.callback_suffix,
- callback_dto=camel_case_name_with_suffix))
+ if util.is_reply(camel_case_name_with_suffix):
+ callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ callback_package=callback_package,
+ callback=util.remove_reply_suffix(camel_case_name_with_suffix) + callback_gen.callback_suffix,
+ callback_dto=camel_case_name_with_suffix))
+
+ if util.is_notification(func["name"]):
+ with_notification_suffix = util.add_notification_suffix(camel_case_name_with_suffix)
+ callbacks.append(jvpp_facade_callback_notification_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ callback_package=callback_package,
+ callback=with_notification_suffix + callback_gen.callback_suffix,
+ callback_dto=with_notification_suffix))
jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacadeCallback.java"), 'w')
jvpp_file.write(jvpp_facade_callback_template.substitute(inputfile=inputfile,
base_package=base_package,
dto_package=dto_package,
+ notification_package=notification_package,
callback_package=callback_package,
methods="".join(callbacks),
callback_facade_package=callback_facade_package))
diff --git a/vpp-api/java/jvpp/gen/jvpp_future_facade_gen.py b/vpp-api/java/jvpp/gen/jvpp_future_facade_gen.py
index 7a5a166733c..e1ca4d022e0 100644
--- a/vpp-api/java/jvpp/gen/jvpp_future_facade_gen.py
+++ b/vpp-api/java/jvpp/gen/jvpp_future_facade_gen.py
@@ -30,12 +30,16 @@ package $base_package.$future_package;
public final class FutureJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
private final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requests;
+ private final $base_package.$notification_package.GlobalNotificationCallback notificationCallback;
- public FutureJVppFacadeCallback(final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requestMap) {
+ public FutureJVppFacadeCallback(final java.util.Map<java.lang.Integer, java.util.concurrent.CompletableFuture<? extends $base_package.$dto_package.JVppReply<?>>> requestMap,
+ final $base_package.$notification_package.GlobalNotificationCallback notificationCallback) {
this.requests = requestMap;
+ this.notificationCallback = notificationCallback;
}
@Override
+ @SuppressWarnings("unchecked")
public void onError(org.openvpp.jvpp.VppCallbackException reply) {
final java.util.concurrent.CompletableFuture<$base_package.$dto_package.JVppReply<?>> completableFuture;
@@ -76,6 +80,13 @@ jvpp_facade_callback_method_template = Template("""
}
""")
+jvpp_facade_callback_notification_method_template = Template("""
+ @Override
+ public void on$callback_dto($base_package.$dto_package.$callback_dto notification) {
+ notificationCallback.on$callback_dto(notification);
+ }
+""")
+
# TODO reuse common parts with generic method callback
jvpp_facade_control_ping_method_template = Template("""
@Override
@@ -129,7 +140,7 @@ jvpp_facade_details_callback_method_template = Template("""
""")
-def generate_jvpp(func_list, base_package, dto_package, callback_package, future_facade_package, inputfile):
+def generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, future_facade_package, inputfile):
""" Generates JVpp interface and JNI implementation """
print "Generating JVpp future facade"
@@ -141,70 +152,77 @@ def generate_jvpp(func_list, base_package, dto_package, callback_package, future
callbacks = []
for func in func_list:
- if util.is_notification(func['name']) or util.is_ignored(func['name']):
- # TODO handle notifications
+ if util.is_ignored(func['name']):
continue
camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
- if not util.is_reply(camel_case_name_with_suffix):
+ if not util.is_reply(camel_case_name_with_suffix) and not util.is_notification(func['name']):
continue
camel_case_method_name = util.underscore_to_camelcase(func['name'])
- camel_case_request_method_name = util.remove_reply_suffix(util.underscore_to_camelcase(func['name']))
- if util.is_details(camel_case_name_with_suffix):
- camel_case_reply_name = get_standard_dump_reply_name(util.underscore_to_camelcase_upper(func['name']),
- func['name'])
- callbacks.append(jvpp_facade_details_callback_method_template.substitute(base_package=base_package,
- dto_package=dto_package,
- callback_dto=camel_case_name_with_suffix,
- callback_dto_field=camel_case_method_name,
- callback_dto_reply_dump=camel_case_reply_name + dto_gen.dump_dto_suffix,
- future_package=future_facade_package))
-
- methods.append(future_jvpp_method_template.substitute(base_package=base_package,
- dto_package=dto_package,
- method_name=camel_case_request_method_name +
- util.underscore_to_camelcase_upper(util.dump_suffix),
- reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix,
- request_name=util.remove_reply_suffix(camel_case_reply_name) +
- util.underscore_to_camelcase_upper(util.dump_suffix)))
- methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package,
- dto_package=dto_package,
- method_name=camel_case_request_method_name +
- util.underscore_to_camelcase_upper(util.dump_suffix),
- reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix,
- request_name=util.remove_reply_suffix(camel_case_reply_name) +
- util.underscore_to_camelcase_upper(util.dump_suffix)))
- else:
- request_name = util.underscore_to_camelcase_upper(util.unconventional_naming_rep_req[func['name']]) \
- if func['name'] in util.unconventional_naming_rep_req else util.remove_reply_suffix(camel_case_name_with_suffix)
-
- methods.append(future_jvpp_method_template.substitute(base_package=base_package,
- dto_package=dto_package,
- method_name=camel_case_request_method_name,
- reply_name=camel_case_name_with_suffix,
- request_name=request_name))
- methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package,
- dto_package=dto_package,
- method_name=camel_case_request_method_name,
- reply_name=camel_case_name_with_suffix,
- request_name=request_name))
-
- # Callback handler is a bit special and a different template has to be used
- if util.is_control_ping(camel_case_name_with_suffix):
- callbacks.append(jvpp_facade_control_ping_method_template.substitute(base_package=base_package,
- dto_package=dto_package,
- callback_dto=camel_case_name_with_suffix,
- future_package=future_facade_package))
+
+ if not util.is_notification(func["name"]):
+ camel_case_request_method_name = util.remove_reply_suffix(util.underscore_to_camelcase(func['name']))
+ if util.is_details(camel_case_name_with_suffix):
+ camel_case_reply_name = get_standard_dump_reply_name(util.underscore_to_camelcase_upper(func['name']),
+ func['name'])
+ callbacks.append(jvpp_facade_details_callback_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ callback_dto=camel_case_name_with_suffix,
+ callback_dto_field=camel_case_method_name,
+ callback_dto_reply_dump=camel_case_reply_name + dto_gen.dump_dto_suffix,
+ future_package=future_facade_package))
+
+ methods.append(future_jvpp_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ method_name=camel_case_request_method_name +
+ util.underscore_to_camelcase_upper(util.dump_suffix),
+ reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix,
+ request_name=util.remove_reply_suffix(camel_case_reply_name) +
+ util.underscore_to_camelcase_upper(util.dump_suffix)))
+ methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ method_name=camel_case_request_method_name +
+ util.underscore_to_camelcase_upper(util.dump_suffix),
+ reply_name=camel_case_reply_name + dto_gen.dump_dto_suffix,
+ request_name=util.remove_reply_suffix(camel_case_reply_name) +
+ util.underscore_to_camelcase_upper(util.dump_suffix)))
else:
- callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
- dto_package=dto_package,
- callback_dto=camel_case_name_with_suffix))
+ request_name = util.underscore_to_camelcase_upper(util.unconventional_naming_rep_req[func['name']]) \
+ if func['name'] in util.unconventional_naming_rep_req else util.remove_reply_suffix(camel_case_name_with_suffix)
+
+ methods.append(future_jvpp_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ method_name=camel_case_request_method_name,
+ reply_name=camel_case_name_with_suffix,
+ request_name=request_name))
+ methods_impl.append(future_jvpp_method_impl_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ method_name=camel_case_request_method_name,
+ reply_name=camel_case_name_with_suffix,
+ request_name=request_name))
+
+ # Callback handler is a bit special and a different template has to be used
+ if util.is_control_ping(camel_case_name_with_suffix):
+ callbacks.append(jvpp_facade_control_ping_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ callback_dto=camel_case_name_with_suffix,
+ future_package=future_facade_package))
+ else:
+ callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ callback_dto=camel_case_name_with_suffix))
+
+ if util.is_notification(func["name"]):
+ callbacks.append(jvpp_facade_callback_notification_method_template.substitute(base_package=base_package,
+ dto_package=dto_package,
+ callback_dto=util.add_notification_suffix(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(inputfile=inputfile,
base_package=base_package,
dto_package=dto_package,
+ notification_package=notification_package,
callback_package=callback_package,
methods="".join(callbacks),
future_package=future_facade_package))
@@ -268,7 +286,7 @@ public class FutureJVppFacade extends FutureJVppInvokerFacade implements FutureJ
*/
public FutureJVppFacade(final $base_package.JVpp jvpp) throws java.io.IOException {
super(jvpp, new java.util.HashMap<>());
- jvpp.connect(new FutureJVppFacadeCallback(getRequests()));
+ jvpp.connect(new FutureJVppFacadeCallback(getRequests(), getNotificationCallback()));
}
$methods
}
diff --git a/vpp-api/java/jvpp/gen/jvpp_gen.py b/vpp-api/java/jvpp/gen/jvpp_gen.py
index e2ff2adcf14..c08593e180f 100755
--- a/vpp-api/java/jvpp/gen/jvpp_gen.py
+++ b/vpp-api/java/jvpp/gen/jvpp_gen.py
@@ -19,6 +19,7 @@ import importlib
import sys
import callback_gen
+import notification_gen
import dto_gen
import jvpp_callback_facade_gen
import jvpp_future_facade_gen
@@ -32,7 +33,7 @@ import util
#
# 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
@@ -122,6 +123,7 @@ func_list, func_name = get_definitions()
base_package = 'org.openvpp.jvpp'
dto_package = 'dto'
callback_package = 'callback'
+notification_package = 'notification'
future_package = 'future'
# TODO find better package name
callback_facade_package = 'callfacade'
@@ -129,6 +131,7 @@ 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)
+notification_gen.generate_notification_registry(func_list, base_package, notification_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)
+jvpp_future_facade_gen.generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, future_package, args.inputfile)
+jvpp_callback_facade_gen.generate_jvpp(func_list, base_package, dto_package, callback_package, notification_package, callback_facade_package, args.inputfile)
diff --git a/vpp-api/java/jvpp/gen/jvpp_impl_gen.py b/vpp-api/java/jvpp/gen/jvpp_impl_gen.py
index dfec6a743de..93ffd0fb359 100644
--- a/vpp-api/java/jvpp/gen/jvpp_impl_gen.py
+++ b/vpp-api/java/jvpp/gen/jvpp_impl_gen.py
@@ -121,8 +121,8 @@ def generate_jvpp(func_list, base_package, dto_package, inputfile):
methods_impl = []
for func in func_list:
- if util.is_notification(func['name']) or util.is_ignored(func['name']):
- # TODO handle notifications
+ # Skip structures that are used only as notifications
+ if util.is_just_notification(func['name']) or util.is_ignored(func['name']):
continue
camel_case_name = util.underscore_to_camelcase(func['name'])
diff --git a/vpp-api/java/jvpp/gen/notification_gen.py b/vpp-api/java/jvpp/gen/notification_gen.py
new file mode 100644
index 00000000000..4ca3c070431
--- /dev/null
+++ b/vpp-api/java/jvpp/gen/notification_gen.py
@@ -0,0 +1,164 @@
+#!/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
+#
+# 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 os
+
+import callback_gen
+import util
+from string import Template
+
+from util import remove_suffix
+
+notification_registry_template = Template("""
+package $base_package.$notification_package;
+
+/**
+ * <p>Registry for notification callbacks.
+ * <br>It was generated by notification_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface NotificationRegistry extends java.lang.AutoCloseable {
+
+ $register_callback_methods
+
+ @Override
+ void close();
+}
+""")
+
+global_notification_callback_template = Template("""
+package $base_package.$notification_package;
+
+/**
+ * <p>Aggregated callback interface for notifications only.
+ * <br>It was generated by notification_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public interface GlobalNotificationCallback extends $callbacks {
+
+}
+""")
+
+notification_registry_impl_template = Template("""
+package $base_package.$notification_package;
+
+/**
+ * <p>Notification registry delegating notification processing to registered callbacks.
+ * <br>It was generated by notification_gen.py based on $inputfile
+ * <br>(python representation of vpe.api generated by vppapigen).
+ */
+public final class NotificationRegistryImpl implements NotificationRegistry, GlobalNotificationCallback {
+
+ // TODO add a special NotificationCallback interface and only allow those to be registered
+ private final java.util.concurrent.ConcurrentMap<Class<? extends $base_package.$dto_package.JVppNotification>, $base_package.$callback_package.JVppNotificationCallback> registeredCallbacks =
+ new java.util.concurrent.ConcurrentHashMap<>();
+
+ $register_callback_methods
+ $handler_methods
+
+ @Override
+ public void close() {
+ registeredCallbacks.clear();
+ }
+}
+""")
+
+register_callback_impl_template = Template("""
+ public java.lang.AutoCloseable register$callback(final $base_package.$callback_package.$callback callback){
+ if(null != registeredCallbacks.putIfAbsent($base_package.$dto_package.$notification.class, callback)){
+ throw new IllegalArgumentException("Callback for " + $base_package.$dto_package.$notification.class +
+ "notification already registered");
+ }
+ return () -> registeredCallbacks.remove($base_package.$dto_package.$notification.class);
+ }
+""")
+
+handler_impl_template = Template("""
+ @Override
+ public void on$notification(
+ final $base_package.$dto_package.$notification notification) {
+ final $base_package.$callback_package.JVppNotificationCallback JVppNotificationCallback = registeredCallbacks.get($base_package.$dto_package.$notification.class);
+ if (null != JVppNotificationCallback) {
+ (($base_package.$callback_package.$callback) registeredCallbacks
+ .get($base_package.$dto_package.$notification.class))
+ .on$notification(notification);
+ }
+ }
+""")
+
+
+def generate_notification_registry(func_list, base_package, notification_package, callback_package, dto_package, inputfile):
+ """ Generates notification registry interface and implementation """
+ print "Generating Notification interfaces and implementation"
+
+ if not os.path.exists(notification_package):
+ raise Exception("%s folder is missing" % notification_package)
+
+ callbacks = []
+ register_callback_methods = []
+ register_callback_methods_impl = []
+ handler_methods = []
+ for func in func_list:
+
+ if not util.is_notification(func['name']):
+ continue
+
+ camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
+ notification_dto = util.add_notification_suffix(camel_case_name_with_suffix)
+ callback_ifc = notification_dto + callback_gen.callback_suffix
+ fully_qualified_callback_ifc = "{0}.{1}.{2}".format(base_package, callback_package, callback_ifc)
+ callbacks.append(fully_qualified_callback_ifc)
+
+ # TODO create NotificationListenerRegistration and return that instead of AutoCloseable to better indicate
+ # that the registration should be closed
+ register_callback_methods.append("java.lang.AutoCloseable register{0}({1} callback);"
+ .format(callback_ifc, fully_qualified_callback_ifc))
+ register_callback_methods_impl.append(register_callback_impl_template.substitute(base_package=base_package,
+ callback_package=callback_package,
+ dto_package=dto_package,
+ notification=notification_dto,
+ callback=callback_ifc))
+ handler_methods.append(handler_impl_template.substitute(base_package=base_package,
+ callback_package=callback_package,
+ dto_package=dto_package,
+ notification=notification_dto,
+ callback=callback_ifc))
+
+ callback_file = open(os.path.join(notification_package, "NotificationRegistry.java"), 'w')
+ callback_file.write(notification_registry_template.substitute(inputfile=inputfile,
+ register_callback_methods="\n ".join(register_callback_methods),
+ base_package=base_package,
+ notification_package=notification_package))
+ callback_file.flush()
+ callback_file.close()
+
+ callback_file = open(os.path.join(notification_package, "GlobalNotificationCallback.java"), 'w')
+ callback_file.write(global_notification_callback_template.substitute(inputfile=inputfile,
+ callbacks=", ".join(callbacks),
+ base_package=base_package,
+ notification_package=notification_package))
+ callback_file.flush()
+ callback_file.close()
+
+ callback_file = open(os.path.join(notification_package, "NotificationRegistryImpl.java"), 'w')
+ callback_file.write(notification_registry_impl_template.substitute(inputfile=inputfile,
+ callback_package=callback_package,
+ dto_package=dto_package,
+ register_callback_methods="".join(register_callback_methods_impl),
+ handler_methods="".join(handler_methods),
+ base_package=base_package,
+ notification_package=notification_package))
+ callback_file.flush()
+ callback_file.close()
diff --git a/vpp-api/java/jvpp/gen/util.py b/vpp-api/java/jvpp/gen/util.py
index 072c9d592f2..12c8bc3170f 100644
--- a/vpp-api/java/jvpp/gen/util.py
+++ b/vpp-api/java/jvpp/gen/util.py
@@ -148,15 +148,21 @@ unconventional_naming_rep_req = {
#
# FIXME no convention in the naming of events (notifications) in vpe.api
notifications_message_suffixes = ("event", "counters")
-notification_messages = ["from_netconf_client", "from_netconf_server", "to_netconf_client", "to_netconf_server"]
+notification_messages_reused = ["sw_interface_set_flags"]
# messages that must be ignored. These messages are INSUFFICIENTLY marked as disabled in vpe.api
# FIXME
ignored_messages = ["is_address_reachable"]
-def is_notification(param):
- return param.lower().endswith(notifications_message_suffixes) or param.lower() in notification_messages
+def is_notification(name):
+ """ Returns true if the structure is a notification regardless of its no other use """
+ return is_just_notification(name) or name.lower() in notification_messages_reused
+
+
+def is_just_notification(name):
+ """ Returns true if the structure is just a notification and has no other use """
+ return name.lower().endswith(notifications_message_suffixes)
def is_ignored(param):
@@ -178,4 +184,12 @@ def is_control_ping(camel_case_name_with_suffix):
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 * ") \ No newline at end of file
+ return " * " + str.replace("\n", "\n * ")
+
+
+notification_dto_suffix = "Notification"
+
+
+def add_notification_suffix(camel_case_dto_name):
+ camel_case_dto_name += notification_dto_suffix
+ return camel_case_dto_name \ No newline at end of file