Repair Doxygen build infrastructure
[vpp.git] / src / vpp-api / java / jvpp / gen / jvppgen / jvpp_impl_gen.py
1 #!/usr/bin/env python
2 #
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:
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 import os, util
17 from string import Template
18
19 jvpp_ifc_template = Template("""
20 package $plugin_package;
21
22 /**
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).
26  */
27 public interface JVpp${plugin_name} extends $base_package.JVpp {
28
29     /**
30      * Generic dispatch method for sending requests to VPP
31      *
32      * @throws io.fd.vpp.jvpp.VppInvocationException if send request had failed
33      */
34     int send($base_package.$dto_package.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException;
35
36 $methods
37 }
38 """)
39
40 jvpp_impl_template = Template("""
41 package $plugin_package;
42
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;
50 import java.util.Set;
51 import java.util.logging.Logger;
52 import $base_package.callback.JVppCallback;
53 import $base_package.VppConnection;
54 import $base_package.JVppRegistry;
55
56 /**
57  * <p>Default implementation of JVpp interface.
58  * <br>It was generated by jvpp_impl_gen.py based on $inputfile
59  * <br>(python representation of api file generated by vppapigen).
60  */
61 public final class JVpp${plugin_name}Impl implements $plugin_package.JVpp${plugin_name} {
62
63     private final static Logger LOG = Logger.getLogger(JVpp${plugin_name}Impl.class.getName());
64     private static final String LIBNAME = "libjvpp_${plugin_name_underscore}.so";
65
66     // FIXME using NativeLibraryLoader makes load fail could not find (WantInterfaceEventsReply).
67     static {
68         try {
69             loadLibrary();
70         } catch (Exception e) {
71             LOG.severe("Can't find jvpp jni library: " + LIBNAME);
72             throw new ExceptionInInitializerError(e);
73         }
74     }
75
76     private static void loadStream(final InputStream is) throws IOException {
77         final Set<PosixFilePermission> perms = PosixFilePermissions.fromString("rwxr-x---");
78         final Path p = Files.createTempFile(LIBNAME, null, PosixFilePermissions.asFileAttribute(perms));
79         try {
80             Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING);
81
82             try {
83                 Runtime.getRuntime().load(p.toString());
84             } catch (UnsatisfiedLinkError e) {
85                 throw new IOException("Failed to load library " + p, e);
86             }
87         } finally {
88             try {
89                 Files.deleteIfExists(p);
90             } catch (IOException e) {
91             }
92         }
93     }
94
95     private static void loadLibrary() throws IOException {
96         try (final InputStream is = JVpp${plugin_name}Impl.class.getResourceAsStream('/' + LIBNAME)) {
97             if (is == null) {
98                 throw new IOException("Failed to open library resource " + LIBNAME);
99             }
100             loadStream(is);
101         }
102     }
103
104     private VppConnection connection;
105     private JVppRegistry registry;
106
107     private static native void init0(final JVppCallback callback, final long queueAddress, final int clientIndex);
108     @Override
109     public void init(final JVppRegistry registry, final JVppCallback callback, final long queueAddress, final int clientIndex) {
110         this.registry = java.util.Objects.requireNonNull(registry, "registry should not be null");
111         this.connection = java.util.Objects.requireNonNull(registry.getConnection(), "connection should not be null");
112         connection.checkActive();
113         init0(callback, queueAddress, clientIndex);
114     }
115
116     private static native void close0();
117     @Override
118     public void close() {
119         close0();
120     }
121
122     @Override
123     public int send($base_package.$dto_package.JVppRequest request) throws io.fd.vpp.jvpp.VppInvocationException {
124         return request.send(this);
125     }
126
127     @Override
128     public final int controlPing(final io.fd.vpp.jvpp.dto.ControlPing controlPing) throws io.fd.vpp.jvpp.VppInvocationException {
129         return registry.controlPing(JVpp${plugin_name}Impl.class);
130     }
131
132 $methods
133 }
134 """)
135
136 method_template = Template("""    int $name($plugin_package.$dto_package.$request request) throws io.fd.vpp.jvpp.VppInvocationException;""")
137 method_native_template = Template(
138     """    private static native int ${name}0($plugin_package.$dto_package.$request request);""")
139 method_impl_template = Template("""    public final int $name($plugin_package.$dto_package.$request request) throws io.fd.vpp.jvpp.VppInvocationException {
140         java.util.Objects.requireNonNull(request,"Null request object");
141         connection.checkActive();
142         int result=${name}0(request);
143         if(result<0){
144             throw new io.fd.vpp.jvpp.VppInvocationException("${name}",result);
145         }
146         return result;
147     }
148 """)
149
150 no_arg_method_template = Template("""    int $name() throws io.fd.vpp.jvpp.VppInvocationException;""")
151 no_arg_method_native_template = Template("""    private static native int ${name}0() throws io.fd.vpp.jvpp.VppInvocationException;""")
152 no_arg_method_impl_template = Template("""    public final int $name() throws io.fd.vpp.jvpp.VppInvocationException {
153         connection.checkActive();
154         int result=${name}0();
155         if(result<0){
156             throw new io.fd.vpp.jvpp.VppInvocationException("${name}",result);
157         }
158         return result;
159     }
160 """)
161
162
163 def generate_jvpp(func_list, base_package, plugin_package, plugin_name_underscore, dto_package, inputfile):
164     """ Generates JVpp interface and JNI implementation """
165     print "Generating JVpp"
166     plugin_name = util.underscore_to_camelcase_upper(plugin_name_underscore)
167
168     methods = []
169     methods_impl = []
170     for func in func_list:
171
172         # Skip structures that are used only as notifications
173         if util.is_just_notification(func['name']) or util.is_ignored(func['name']):
174             continue
175
176         camel_case_name = util.underscore_to_camelcase(func['name'])
177         camel_case_name_upper = util.underscore_to_camelcase_upper(func['name'])
178         if util.is_reply(camel_case_name):
179             continue
180
181         if len(func['args']) == 0:
182             methods.append(no_arg_method_template.substitute(name=camel_case_name))
183             methods_impl.append(no_arg_method_native_template.substitute(name=camel_case_name))
184             methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name))
185         else:
186             methods.append(method_template.substitute(name=camel_case_name,
187                                                       request=camel_case_name_upper,
188                                                       plugin_package=plugin_package,
189                                                       dto_package=dto_package))
190             methods_impl.append(method_native_template.substitute(name=camel_case_name,
191                                                                   request=camel_case_name_upper,
192                                                                   plugin_package=plugin_package,
193                                                                   dto_package=dto_package))
194             methods_impl.append(method_impl_template.substitute(name=camel_case_name,
195                                                                 request=camel_case_name_upper,
196                                                                 plugin_package=plugin_package,
197                                                                 dto_package=dto_package))
198
199     jvpp_file = open("JVpp%s.java" % plugin_name, 'w')
200     jvpp_file.write(
201         jvpp_ifc_template.substitute(inputfile=inputfile,
202                                      methods="\n".join(methods),
203                                      base_package=base_package,
204                                      plugin_package=plugin_package,
205                                      plugin_name=plugin_name,
206                                      dto_package=dto_package))
207     jvpp_file.flush()
208     jvpp_file.close()
209
210     jvpp_file = open("JVpp%sImpl.java" % plugin_name, 'w')
211     jvpp_file.write(jvpp_impl_template.substitute(inputfile=inputfile,
212                                                   methods="\n".join(methods_impl),
213                                                   base_package=base_package,
214                                                   plugin_package=plugin_package,
215                                                   plugin_name=plugin_name,
216                                                   plugin_name_underscore=plugin_name_underscore,
217                                                   dto_package=dto_package))
218     jvpp_file.flush()
219     jvpp_file.close()