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
19 jvpp_ifc_template = Template("""
20 package $plugin_package;
23 * <p>Java representation of plugin's api file.
24 * <br>It was generated by jvpp_impl_gen.py based on $inputfile
25 * <br>(python representation of api file generated by vppapigen).
27 public interface JVpp${plugin_name} extends $base_package.JVpp {
30 * Generic dispatch method for sending requests to VPP
32 * @throws io.fd.vpp.jvpp.VppInvocationException if send request had failed
34 int send($base_package.$dto_package.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException;
40 jvpp_impl_template = Template("""
41 package $plugin_package;
43 import java.io.IOException;
44 import java.io.InputStream;
45 import java.nio.file.Files;
46 import java.nio.file.Path;
47 import java.nio.file.StandardCopyOption;
48 import java.nio.file.attribute.PosixFilePermission;
49 import java.nio.file.attribute.PosixFilePermissions;
51 import java.util.logging.Logger;
52 import java.util.logging.Level;
53 import $base_package.callback.JVppCallback;
54 import $base_package.VppConnection;
55 import $base_package.JVppRegistry;
58 * <p>Default implementation of JVpp interface.
59 * <br>It was generated by jvpp_impl_gen.py based on $inputfile
60 * <br>(python representation of api file generated by vppapigen).
62 public final class JVpp${plugin_name}Impl implements $plugin_package.JVpp${plugin_name} {
64 private final static Logger LOG = Logger.getLogger(JVpp${plugin_name}Impl.class.getName());
65 private static final String LIBNAME = "libjvpp_${plugin_name_underscore}.so";
67 // FIXME using NativeLibraryLoader makes load fail could not find (WantInterfaceEventsReply).
71 } catch (Exception e) {
72 LOG.severe("Can't find jvpp jni library: " + LIBNAME);
73 throw new ExceptionInInitializerError(e);
77 private static void loadStream(final InputStream is) throws IOException {
78 final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
79 final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms));
81 Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
84 Runtime.getRuntime().load(p.toString());
85 } catch (UnsatisfiedLinkError e) {
86 throw new IOException("Failed to load library " + p, e);
90 Files.deleteIfExists(p);
91 } catch (IOException e) {
96 private static void loadLibrary() throws IOException {
97 try (final InputStream is = JVpp${plugin_name}Impl.class.getResourceAsStream('/' + LIBNAME)) {
99 throw new IOException("Failed to open library resource " + LIBNAME);
105 private VppConnection connection;
106 private JVppRegistry registry;
108 private static native void init0(final JVppCallback callback, final long queueAddress, final int clientIndex);
110 public void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress, final int clientIndex) {
111 this.registry = java.util.Objects.requireNonNull(registry, "registry should not be null");
112 this.connection = java.util.Objects.requireNonNull(registry.getConnection(), "connection should not be null");
113 connection.checkActive();
114 init0(callback, queueAddress, clientIndex);
117 private static native void close0();
119 public void close() {
124 public int send($base_package.$dto_package.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException {
125 return request.send(this);
129 public final int controlPing(final io.fd.vpp.jvpp.dto.ControlPing controlPing) throws io.fd.vpp.jvpp.VppInvocationException {
130 return registry.controlPing(JVpp${plugin_name}Impl.class);
137 method_template = Template(""" int $name($plugin_package.$dto_package.$request request) throws io.fd.vpp.jvpp.VppInvocationException;""")
138 method_native_template = Template(
139 """ private static native int ${name}0($plugin_package.$dto_package.$request request);""")
140 method_impl_template = Template(""" public final int $name($plugin_package.$dto_package.$request request) throws io.fd.vpp.jvpp.VppInvocationException {
141 java.util.Objects.requireNonNull(request,"Null request object");
142 connection.checkActive();
143 if(LOG.isLoggable(Level.FINE)) {
144 LOG.fine(String.format("Sending $name event message: %s", request));
146 int result=${name}0(request);
148 throw new io.fd.vpp.jvpp.VppInvocationException("${name}",result);
154 no_arg_method_template = Template(""" int $name() throws io.fd.vpp.jvpp.VppInvocationException;""")
155 no_arg_method_native_template = Template(""" private static native int ${name}0() throws io.fd.vpp.jvpp.VppInvocationException;""")
156 no_arg_method_impl_template = Template(""" public final int $name() throws io.fd.vpp.jvpp.VppInvocationException {
157 connection.checkActive();
158 LOG.fine("Sending $name event message");
159 int result=${name}0();
161 throw new io.fd.vpp.jvpp.VppInvocationException("${name}",result);
168 def generate_jvpp(func_list, base_package, plugin_package, plugin_name_underscore, dto_package, inputfile):
169 """ Generates JVpp interface and JNI implementation """
170 print "Generating JVpp"
171 plugin_name = util.underscore_to_camelcase_upper(plugin_name_underscore)
175 for func in func_list:
177 # Skip structures that are used only as notifications
178 if util.is_ignored(func['name']):
181 camel_case_name = util.underscore_to_camelcase(func['name'])
182 camel_case_name_upper = util.underscore_to_camelcase_upper(func['name'])
183 if util.is_reply(camel_case_name):
186 if len(func['args']) == 0:
187 methods.append(no_arg_method_template.substitute(name=camel_case_name))
188 methods_impl.append(no_arg_method_native_template.substitute(name=camel_case_name))
189 methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name))
191 methods.append(method_template.substitute(name=camel_case_name,
192 request=camel_case_name_upper,
193 plugin_package=plugin_package,
194 dto_package=dto_package))
195 methods_impl.append(method_native_template.substitute(name=camel_case_name,
196 request=camel_case_name_upper,
197 plugin_package=plugin_package,
198 dto_package=dto_package))
199 methods_impl.append(method_impl_template.substitute(name=camel_case_name,
200 request=camel_case_name_upper,
201 plugin_package=plugin_package,
202 dto_package=dto_package))
204 jvpp_file = open("JVpp%s.java" % plugin_name, 'w')
206 jvpp_ifc_template.substitute(inputfile=inputfile,
207 methods="\n".join(methods),
208 base_package=base_package,
209 plugin_package=plugin_package,
210 plugin_name=plugin_name,
211 dto_package=dto_package))
215 jvpp_file = open("JVpp%sImpl.java" % plugin_name, 'w')
216 jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
217 methods="\n".join(methods_impl),
218 base_package=base_package,
219 plugin_package=plugin_package,
220 plugin_name=plugin_name,
221 plugin_name_underscore=plugin_name_underscore,
222 dto_package=dto_package))