731bd894cee35ffb314f74a7d590d12351ee89f1
[vpp.git] / vpp-api / java / jvpp / gen / jvpp_callback_facade_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 import callback_gen
20 import dto_gen
21
22 jvpp_ifc_template = Template("""
23 package $base_package.$callback_facade_package;
24
25 public interface CallbackJVpp extends java.lang.AutoCloseable {
26
27     @Override
28     void close();
29
30     // TODO add send
31
32 $methods
33 }
34 """)
35
36 jvpp_impl_template = Template("""
37 package $base_package.$callback_facade_package;
38
39 public final class CallbackJVppFacade implements $base_package.$callback_facade_package.CallbackJVpp {
40
41     private final $base_package.JVpp jvpp;
42     private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> callbacks;
43
44     public CallbackJVppFacade(final $base_package.JVpp jvpp,
45                               java.util.Map<Integer, $base_package.$callback_package.JVppCallback> callbacks) {
46         if(jvpp == null) {
47             throw new java.lang.NullPointerException("jvpp is null");
48         }
49         this.jvpp = jvpp;
50         this.callbacks = callbacks;
51     }
52
53     @Override
54     public void close() {
55     }
56
57     // TODO add send()
58
59 $methods
60 }
61 """)
62
63 method_template = Template(
64     """    void $name($base_package.$dto_package.$request request, $base_package.$callback_package.$callback callback);""")
65 method_impl_template = Template("""    public final void $name($base_package.$dto_package.$request request, $base_package.$callback_package.$callback callback) {
66         synchronized (callbacks) {
67             callbacks.put(jvpp.$name(request), callback);
68         }
69     }
70 """)
71
72 no_arg_method_template = Template("""    void $name($base_package.$callback_package.$callback callback);""")
73 no_arg_method_impl_template = Template("""    public final void $name($base_package.$callback_package.$callback callback) {
74         synchronized (callbacks) {
75             callbacks.put(jvpp.$name(), callback);
76         }
77     }
78 """)
79
80
81 def generate_jvpp(func_list, base_package, dto_package, callback_package, callback_facade_package):
82     """ Generates callback facade """
83     print "Generating JVpp callback facade"
84
85     if os.path.exists(callback_facade_package):
86         util.remove_folder(callback_facade_package)
87
88     os.mkdir(callback_facade_package)
89
90     methods = []
91     methods_impl = []
92     for func in func_list:
93
94         if util.is_notification(func['name']) or util.is_ignored(func['name']):
95             # TODO handle notifications
96             continue
97
98         camel_case_name = util.underscore_to_camelcase(func['name'])
99         camel_case_name_upper = util.underscore_to_camelcase_upper(func['name'])
100         if util.is_reply(camel_case_name):
101             continue
102
103         # Strip suffix for dump calls
104         callback_type = get_request_name(camel_case_name_upper, func['name']) + callback_gen.callback_suffix
105
106         if len(func['args']) == 0:
107             methods.append(no_arg_method_template.substitute(name=camel_case_name,
108                                                              base_package=base_package,
109                                                              dto_package=dto_package,
110                                                              callback_package=callback_package,
111                                                              callback=callback_type))
112             methods_impl.append(no_arg_method_impl_template.substitute(name=camel_case_name,
113                                                                        base_package=base_package,
114                                                                        dto_package=dto_package,
115                                                                        callback_package=callback_package,
116                                                                        callback=callback_type))
117         else:
118             methods.append(method_template.substitute(name=camel_case_name,
119                                                       request=camel_case_name_upper,
120                                                       base_package=base_package,
121                                                       dto_package=dto_package,
122                                                       callback_package=callback_package,
123                                                       callback=callback_type))
124             methods_impl.append(method_impl_template.substitute(name=camel_case_name,
125                                                                 request=camel_case_name_upper,
126                                                                 base_package=base_package,
127                                                                 dto_package=dto_package,
128                                                                 callback_package=callback_package,
129                                                                 callback=callback_type))
130
131     join = os.path.join(callback_facade_package, "CallbackJVpp.java")
132     jvpp_file = open(join, 'w')
133     jvpp_file.write(
134         jvpp_ifc_template.substitute(methods="\n".join(methods),
135                                      base_package=base_package,
136                                      dto_package=dto_package,
137                                      callback_facade_package=callback_facade_package))
138     jvpp_file.flush()
139     jvpp_file.close()
140
141     jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacade.java"), 'w')
142     jvpp_file.write(jvpp_impl_template.substitute(methods="\n".join(methods_impl),
143                                                   base_package=base_package,
144                                                   dto_package=dto_package,
145                                                   callback_package=callback_package,
146                                                   callback_facade_package=callback_facade_package))
147     jvpp_file.flush()
148     jvpp_file.close()
149
150     generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package)
151
152
153 jvpp_facade_callback_template = Template("""
154 package $base_package.$callback_facade_package;
155
156 /**
157  * Async facade callback setting values to future objects
158  */
159 public final class CallbackJVppFacadeCallback implements $base_package.$callback_package.JVppGlobalCallback {
160
161     private final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requests;
162
163     public CallbackJVppFacadeCallback(final java.util.Map<Integer, $base_package.$callback_package.JVppCallback> requestMap) {
164         this.requests = requestMap;
165     }
166
167 $methods
168 }
169 """)
170
171 jvpp_facade_callback_method_template = Template("""
172     @Override
173     @SuppressWarnings("unchecked")
174     public void on$callback_dto($base_package.$dto_package.$callback_dto reply) {
175
176         $base_package.$callback_package.$callback callback;
177         synchronized(requests) {
178             callback = ($base_package.$callback_package.$callback) requests.remove(reply.context);
179         }
180
181         if(callback != null) {
182             callback.on$callback_dto(reply);
183         }
184     }
185 """)
186
187
188 def generate_callback(func_list, base_package, dto_package, callback_package, callback_facade_package):
189     callbacks = []
190     for func in func_list:
191
192         if util.is_notification(func['name']) or util.is_ignored(func['name']):
193             # TODO handle notifications
194             continue
195
196         camel_case_name_with_suffix = util.underscore_to_camelcase_upper(func['name'])
197         if not util.is_reply(camel_case_name_with_suffix):
198             continue
199
200         callbacks.append(jvpp_facade_callback_method_template.substitute(base_package=base_package,
201                                                                          dto_package=dto_package,
202                                                                          callback_package=callback_package,
203                                                                          callback=util.remove_reply_suffix(camel_case_name_with_suffix) + callback_gen.callback_suffix,
204                                                                          callback_dto=camel_case_name_with_suffix))
205
206     jvpp_file = open(os.path.join(callback_facade_package, "CallbackJVppFacadeCallback.java"), 'w')
207     jvpp_file.write(jvpp_facade_callback_template.substitute(base_package=base_package,
208                                                              dto_package=dto_package,
209                                                              callback_package=callback_package,
210                                                              methods="".join(callbacks),
211                                                              callback_facade_package=callback_facade_package))
212     jvpp_file.flush()
213     jvpp_file.close()
214
215
216 # Returns request name or special one from unconventional_naming_rep_req map
217 def get_request_name(camel_case_dto_name, func_name):
218     if func_name in reverse_dict(util.unconventional_naming_rep_req):
219         request_name = util.underscore_to_camelcase_upper(reverse_dict(util.unconventional_naming_rep_req)[func_name])
220     else:
221         request_name = camel_case_dto_name
222     return remove_suffix(request_name)
223
224
225 def reverse_dict(map):
226     return dict((v, k) for k, v in map.iteritems())
227
228
229 def remove_suffix(name):
230     if util.is_reply(name):
231         return util.remove_reply_suffix(name)
232     else:
233         if util.is_dump(name):
234             return util.remove_suffix(name, util.dump_suffix)
235         else:
236             return name