API: Use string type instead of u8.
[vpp.git] / extras / japi / java / jvpp / gen / jvppgen / jvpp_impl_gen.py
1 #!/usr/bin/env python2
2 #
3 # Copyright (c) 2016,2018 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:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
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.
15 #
16 from string import Template
17
18 from jvpp_model import is_request, is_dump, is_event
19
20
21 def generate_java_impl(work_dir, model, logger):
22     logger.debug("Generating JVpp implementation for %s" % model.json_api_files)
23     messages = filter(_jvpp_impl_filter, model.messages)
24     plugin_package = model.plugin_package
25     methods = []
26     for msg in messages:
27         if msg.has_fields:
28             methods.append(_JVPP_IMPL_METHOD_TEMPLATE.substitute(
29                 name=msg.java_name_lower,
30                 plugin_package=plugin_package,
31                 type=msg.java_name_upper))
32         else:
33             methods.append(_JVPP_IMPL_NO_ARG_METHOD_TEMPLATE.substitute(
34                 name=msg.java_name_lower,
35                 type=msg.java_name_upper))
36
37     plugin_name = model.plugin_java_name
38     jvpp_impl = _JVPP_IMPL_TEMPLATE.substitute(
39         plugin_package=plugin_package,
40         json_filename=model.json_api_files,
41         plugin_name=model.plugin_java_name,
42         plugin_name_underscore=model.plugin_name,
43         methods="\n".join(methods))
44
45     with open("%s/JVpp%sImpl.java" % (work_dir, plugin_name), "w") as f:
46         f.write(jvpp_impl)
47
48
49 def _jvpp_impl_filter(msg):
50     return is_request(msg) or is_dump(msg) or is_event(msg)
51
52
53 _JVPP_IMPL_TEMPLATE = Template("""package $plugin_package;
54
55 import java.io.IOException;
56 import java.io.InputStream;
57 import java.nio.file.Files;
58 import java.nio.file.Path;
59 import java.nio.file.StandardCopyOption;
60 import java.nio.file.attribute.PosixFilePermission;
61 import java.nio.file.attribute.PosixFilePermissions;
62 import java.util.Set;
63 import java.util.logging.Logger;
64 import java.util.logging.Level;
65 import io.fd.vpp.jvpp.callback.JVppCallback;
66 import io.fd.vpp.jvpp.VppConnection;
67 import io.fd.vpp.jvpp.JVppRegistry;
68
69 /**
70  * <p>Default implementation of JVpp interface.
71  * <br>It was generated by jvpp_impl_gen.py based on $json_filename.
72  * <br>(python representation of api file generated by vppapigen)
73  */
74 public final class JVpp${plugin_name}Impl implements $plugin_package.JVpp${plugin_name} {
75
76     private final static Logger LOG = Logger.getLogger(JVpp${plugin_name}Impl.class.getName());
77     private static final java.lang.String LIBNAME = "libjvpp_${plugin_name_underscore}.so";
78
79     // FIXME using NativeLibraryLoader makes load fail could not find (WantInterfaceEventsReply).
80     static {
81         try {
82             loadLibrary();
83         } catch (Exception e) {
84             LOG.severe("Can't find jvpp jni library: " + LIBNAME);
85             throw new ExceptionInInitializerError(e);
86         }
87     }
88
89     private static void loadStream(final InputStream is) throws IOException {
90         final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
91         final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms));
92         try {
93             Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
94
95             try {
96                 Runtime.getRuntime().load(p.toString());
97             } catch (UnsatisfiedLinkError e) {
98                 throw new IOException("Failed to load library " + p, e);
99             }
100         } finally {
101             try {
102                 Files.deleteIfExists(p);
103             } catch (IOException e) {
104             }
105         }
106     }
107
108     private static void loadLibrary() throws IOException {
109         try (final InputStream is = JVpp${plugin_name}Impl.class.getResourceAsStream('/' + LIBNAME)) {
110             if (is == null) {
111                 throw new IOException("Failed to open library resource " + LIBNAME);
112             }
113             loadStream(is);
114         }
115     }
116
117     private VppConnection connection;
118     private JVppRegistry registry;
119
120     private static native void init0(final JVppCallback callback, final long queueAddress, final int clientIndex);
121     @Override
122     public void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress, final int clientIndex) {
123         this.registry = java.util.Objects.requireNonNull(registry, "registry should not be null");
124         this.connection = java.util.Objects.requireNonNull(registry.getConnection(), "connection should not be null");
125         connection.checkActive();
126         init0(callback, queueAddress, clientIndex);
127     }
128
129     private static native void close0();
130     @Override
131     public void close() {
132         close0();
133     }
134
135     @Override
136     public int send(io.fd.vpp.jvpp.dto.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException {
137         return request.send(this);
138     }
139
140     @Override
141     public final int controlPing(final io.fd.vpp.jvpp.dto.ControlPing controlPing) throws io.fd.vpp.jvpp.VppInvocationException {
142         return registry.controlPing(JVpp${plugin_name}Impl.class);
143     }
144 $methods
145 }
146 """)
147
148 _JVPP_IMPL_METHOD_TEMPLATE = Template("""
149     private static native int ${name}0($plugin_package.dto.$type request);
150     public final int $name($plugin_package.dto.$type request) throws io.fd.vpp.jvpp.VppInvocationException {
151         java.util.Objects.requireNonNull(request, "Null request object");
152         connection.checkActive();
153         if (LOG.isLoggable(Level.FINE)) {
154             LOG.fine(java.lang.String.format("Sending $type event message: %s", request));
155         }
156         int result=${name}0(request);
157         if (result<0){
158             throw new io.fd.vpp.jvpp.VppInvocationException("${name}", result);
159         }
160         return result;
161     }""")
162
163 _JVPP_IMPL_NO_ARG_METHOD_TEMPLATE = Template("""
164     private static native int ${name}0() throws io.fd.vpp.jvpp.VppInvocationException;
165     public final int $name() throws io.fd.vpp.jvpp.VppInvocationException {
166         connection.checkActive();
167         LOG.fine("Sending $type event message");
168         int result=${name}0();
169         if(result<0){
170             throw new io.fd.vpp.jvpp.VppInvocationException("${name}", result);
171         }
172         return result;
173     }""")