From fb8632903100150835a93d7c811fb50ca97c84b9 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Mon, 9 Oct 2017 17:50:45 +0200 Subject: [PATCH] Started JAVA wrapper --- tools/metadoc.py | 5 + wrappers/csharp/genwrapper.py | 2 +- wrappers/java/CMakeLists.txt | 38 ++ wrappers/java/genwrapper.py | 400 +++++++++++++++++++++ wrappers/java/java_class.mustache | 156 ++++++++ wrappers/java/java_enum.mustache | 60 ++++ wrappers/java/java_enum_old.mustache | 65 ++++ wrappers/java/java_interface.mustache | 46 +++ wrappers/java/java_interface_stub.mustache | 34 ++ wrappers/java/jni.mustache | 38 ++ 10 files changed, 843 insertions(+), 1 deletion(-) create mode 100644 wrappers/java/CMakeLists.txt create mode 100644 wrappers/java/genwrapper.py create mode 100644 wrappers/java/java_class.mustache create mode 100644 wrappers/java/java_enum.mustache create mode 100644 wrappers/java/java_enum_old.mustache create mode 100644 wrappers/java/java_interface.mustache create mode 100644 wrappers/java/java_interface_stub.mustache create mode 100644 wrappers/java/jni.mustache diff --git a/tools/metadoc.py b/tools/metadoc.py index 1cf932daf..fd985a11f 100644 --- a/tools/metadoc.py +++ b/tools/metadoc.py @@ -191,3 +191,8 @@ class SandcastleCSharpTranslator(Translator): if len(lines) > 0: lines.insert(0, '') lines.append('') + + +class SandcastleJavaTranslator(Translator): + def _tag_as_brief(self, lines): + pass diff --git a/wrappers/csharp/genwrapper.py b/wrappers/csharp/genwrapper.py index e5aad72a7..f83c68361 100644 --- a/wrappers/csharp/genwrapper.py +++ b/wrappers/csharp/genwrapper.py @@ -566,7 +566,7 @@ def render(renderer, item, path): os.unlink(tmppath) def main(): - argparser = argparse.ArgumentParser(description='Generate source files for the C++ wrapper') + argparser = argparse.ArgumentParser(description='Generate source files for the C# wrapper') argparser.add_argument('xmldir', type=str, help='Directory where the XML documentation of the Linphone\'s API generated by Doxygen is placed') argparser.add_argument('-o --output', type=str, help='the directory where to generate the source files', dest='outputdir', default='.') argparser.add_argument('-n --name', type=str, help='the name of the genarated source file', dest='outputfile', default='LinphoneWrapper.cs') diff --git a/wrappers/java/CMakeLists.txt b/wrappers/java/CMakeLists.txt new file mode 100644 index 000000000..66b01ea38 --- /dev/null +++ b/wrappers/java/CMakeLists.txt @@ -0,0 +1,38 @@ +############################################################################ +# CMakeLists.txt +# Copyright (C) 2017 Belledonne Communications, Grenoble France +# +############################################################################ +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +############################################################################ + +add_custom_command(OUTPUT linphone_jni.cc + COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genwrapper.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/doxygen/xml" + DEPENDS ${PROJECT_SOURCE_DIR}/tools/genapixml.py + ${PROJECT_SOURCE_DIR}/tools/metadoc.py + ${PROJECT_SOURCE_DIR}/tools/abstractapi.py + genwrapper.py + wrapper_impl.mustache + linphone-doc + "${PROJECT_BINARY_DIR}/coreapi/help/doc/doxygen/xml/index.xml" +) + +add_custom_target(linphonej ALL DEPENDS linphone_jni.cc) + +#install(FILES ${CMAKE_CURRENT_BINARY_DIR}/linphone_jni.cc +# DESTINATION ${CMAKE_INSTALL_DATADIR}/linphonej +#) diff --git a/wrappers/java/genwrapper.py b/wrappers/java/genwrapper.py new file mode 100644 index 000000000..ca85ed3c0 --- /dev/null +++ b/wrappers/java/genwrapper.py @@ -0,0 +1,400 @@ +#!/usr/bin/python + +# Copyright (C) 2017 Belledonne Communications SARL +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301, USA. + +import argparse +import os +import sys +import pystache +import errno + +sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'tools')) +print(sys.path) +import genapixml as CApi +import abstractapi as AbsApi +import metadoc + +########################################################################## + +class JavaTranslator(object): + def __init__(self): + self.docTranslator = metadoc.SandcastleJavaTranslator() + + def throws_exception(self, _type): + if type(_type) is AbsApi.BaseType: + if _type.name == 'status': + return True + return False + + def translate_argument_name(self, _argName): + return _argName.to_snake_case() + + def translate_type(self, _type, native=False): + if type(_type) is AbsApi.ListType: + ptrtype = '' + if type(_type.containedTypeDesc) is AbsApi.ClassType: + ptrtype = self.translate_type(_type.containedTypeDesc, native) + elif type(_type.containedTypeDesc) is AbsApi.BaseType: + ptrtype = self.translate_type(_type.containedTypeDesc, native) + elif type(_type.containedTypeDesc) is AbsApi.EnumType: + ptrtype = self.translate_type(_type.containedTypeDesc, native) + else: + if _type.containedTypeDesc: + raise AbsApi.Error('translation of bctbx_list_t of ' + _type.containedTypeDesc.name) + else: + raise AbsApi.Error('translation of bctbx_list_t of unknow type !') + return ptrtype + '[]' + + elif type(_type) is AbsApi.ClassType: + if native: + return 'long' + return _type.desc.name.to_camel_case() + elif type(_type) is AbsApi.EnumType: + if native: + return 'int' + return _type.desc.name.to_camel_case() + elif type(_type) is AbsApi.BaseType: + if _type.name == 'string': + return 'String' + elif _type.name == 'integer': + return 'int' + elif _type.name == 'floatant': + return 'float' + elif _type.name == 'size': + return 'int' + return _type.name + + def translate_argument(self, _arg, native=False): + return '{0} {1}'.format(self.translate_type(_arg.type, native), self.translate_argument_name(_arg.name)) + + def translate_property(self, _property): + properties = [] + if _property.getter is not None: + properties.append(self.translate_method(_property.getter)) + if _property.setter is not None: + properties.append(self.translate_method(_property.setter)) + return properties + + def translate_method(self, _method): + methodDict = {} + + methodDict['return'] = self.translate_type(_method.returnType) + methodDict['return_native'] = self.translate_type(_method.returnType, True) + methodDict['return_keyword'] = '' if methodDict['return'] == 'void' else 'return ' + + methodDict['convertInputClassArrayToLongArray'] = False + methodDict['convertOutputClassArrayToLongArray'] = type(_method.returnType) is AbsApi.ListType and type(_method.returnType.containedTypeDesc) is AbsApi.ClassType + if methodDict['convertOutputClassArrayToLongArray']: + methodDict['native_params_impl_list_param_name'] = 'classArray' + methodDict['native_params_impl_list_param_type'] = self.translate_type(_method.returnType.containedTypeDesc) + + methodDict['name'] = _method.name.to_camel_case(lower=True) + methodDict['exception'] = self.throws_exception(_method.returnType) + + methodDict['params'] = '' + methodDict['native_params'] = 'long nativePtr' + methodDict['static_native_params'] = '' + methodDict['native_params_impl'] = '' + for arg in _method.args: + if arg is not _method.args[0]: + methodDict['params'] += ', ' + methodDict['native_params'] += ', ' + methodDict['native_params_impl'] += ', ' + + methodDict['params'] += self.translate_argument(arg) + methodDict['native_params'] += self.translate_argument(arg, True) + methodDict['static_native_params'] += self.translate_argument(arg, True) + if type(arg.type) is AbsApi.ClassType: + methodDict['native_params_impl'] += '((' + self.translate_type(arg.type) + ')' + self.translate_argument_name(arg.name) + ').nativePtr' + elif type(arg.type) is AbsApi.ListType: + if type(arg.type.containedTypeDesc) is AbsApi.ClassType: + methodDict['convertInputClassArrayToLongArray'] = True + methodDict['native_params_impl_list_param_name'] = self.translate_argument_name(arg.name) + methodDict['native_params_impl_list_param_type'] = self.translate_type(arg.type.containedTypeDesc) + 'Impl' + methodDict['native_params_impl'] += 'longArray' + else: + methodDict['native_params_impl'] += self.translate_argument_name(arg.name) + else: + methodDict['native_params_impl'] += self.translate_argument_name(arg.name) + + methodDict['classicMethod'] = not methodDict['convertInputClassArrayToLongArray'] and not methodDict['convertOutputClassArrayToLongArray'] + methodDict['deprecated'] = _method.deprecated + methodDict['doc'] = self.docTranslator.translate(_method.briefDescription) if _method.briefDescription is not None else None + + return methodDict + + def translate_class(self, _class): + classDict = { + 'methods' : [], + 'staticMethods' : [], + } + + classDict['isLinphoneFactory'] = _class.name.to_camel_case() == "Factory" + classDict['doc'] = self.docTranslator.translate(_class.briefDescription) if _class.briefDescription is not None else None + + for _property in _class.properties: + try: + classDict['methods'] += self.translate_property(_property) + except AbsApi.Error as e: + print('error while translating {0} property: {1}'.format(_property.name.to_snake_case(), e.args[0])) + + for method in _class.instanceMethods: + try: + methodDict = self.translate_method(method) + classDict['methods'].append(methodDict) + except AbsApi.Error as e: + print('Could not translate {0}: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) + + for method in _class.classMethods: + try: + methodDict = self.translate_method(method) + classDict['staticMethods'].append(methodDict) + except AbsApi.Error as e: + print('Could not translate {0}: {1}'.format(method.name.to_snake_case(fullName=True), e.args[0])) + + return classDict + + def translate_interface(self, _class): + interfaceDict = { + 'methods' : [], + } + + interfaceDict['doc'] = self.docTranslator.translate(_class.briefDescription) + + for method in _class.methods: + interfaceDict['methods'].append(self.translate_method(method)) + + return interfaceDict + + def translate_enum(self, _class): + enumDict = {} + + enumDict['name'] = _class.name.to_camel_case() + enumDict['doc'] = self.docTranslator.translate(_class.briefDescription) + enumDict['values'] = [] + i = 0 + lastValue = None + + for enumValue in _class.values: + enumValDict = {} + enumValDict['name'] = enumValue.name.to_camel_case() + enumValDict['doc'] = self.docTranslator.translate(enumValue.briefDescription) + if type(enumValue.value) is int: + lastValue = enumValue.value + enumValDict['value'] = str(enumValue.value) + elif type(enumValue.value) is AbsApi.Flag: + enumValDict['value'] = '1<<' + str(enumValue.value.position) + else: + if lastValue is not None: + enumValDict['value'] = lastValue + 1 + lastValue += 1 + else: + enumValDict['value'] = i + i += 1 + enumValDict['commarorsemicolon'] = ';' if i == len(_class.values) else ',' + enumDict['values'].append(enumValDict) + + return enumDict + +########################################################################## + +class JavaEnum(object): + def __init__(self, _enum, translator): + self._class = translator.translate_enum(_enum) + self.packageName = "org.linphone" + self.className = _enum.name.to_camel_case() + self.filename = self.className + ".java" + self.values = self._class['values'] + self.doc = self._class['doc'] + self.jniMethods = [] + +class JavaInterface(object): + def __init__(self, _interface, translator): + self._class = translator.translate_interface(_interface) + self.packageName = "org.linphone" + self.className = _interface.name.to_camel_case() + self.filename = self.className + ".java" + self.imports = [] + self.methods = self._class['methods'] + self.doc = self._class['doc'] + self.jniMethods = [] + +class JavaInterfaceStub(object): + def __init__(self, _interface): + self.packageName = _interface.packageName + self.className = _interface.className + self.classNameStub = self.className + "Stub" + self.filename = self.className + "Stub.java" + self.methods = _interface.methods + +class JavaClass(object): + def __init__(self, _class, translator): + self._class = translator.translate_class(_class) + self.isLinphoneFactory = self._class['isLinphoneFactory'] + self.packageName = "org.linphone" + self.className = _class.name.to_camel_case() + self.classImplName = self.className + "Impl" + self.filename = self.className + ".java" + self.imports = [] + self.methods = self._class['methods'] + self.staticMethods = self._class['staticMethods'] + self.doc = self._class['doc'] + self.jniMethods = [] + self.enums = [] + + def add_enum(self, enum): + if enum.className.startswith(self.className): + enum.className = enum.className[len(self.className):] + self.enums.append(enum) + +class Jni(object): + def __init__(self): + self.methods = {} + + def add_methods(self, name, methods): + self.methods[name] = methods + +########################################################################## + +class GenWrapper(object): + def __init__(self, srcdir, javadir, xmldir): + self.srcdir = srcdir + self.javadir = javadir + + project = CApi.Project() + project.initFromDir(xmldir) + project.check() + + self.parser = AbsApi.CParser(project) + self.parser.parse_all() + self.translator = JavaTranslator() + self.renderer = pystache.Renderer() + self.jni = Jni() + + self.enums = {} + self.interfaces = {} + self.classes = {} + self.enums_list = { + 'CallState': 'Call', + 'ChatMessageState': 'ChatMessage', + 'ConfiguringState': 'Core', + 'CoreLogCollectionUploadState': 'Core', + 'GlobalState': 'Core', + 'RegistrationState': 'Core', + } + self.enums_to_remove = [] + + def render_all(self): + for _interface in self.parser.interfacesIndex.values(): + self.render_java_interface(_interface) + for _class in self.parser.classesIndex.values(): + self.render_java_class(_class) + for _enum in self.parser.enumsIndex.items(): + if _enum[1] is not None: + self.render_java_enum(_enum[1]) + + for name, value in self.enums.iteritems(): + if name in self.enums_list: + className = self.enums_list[name] + print 'Enum ' + name + ' belongs to class ' + className + self.classes[className].add_enum(value) + self.enums_to_remove.append(name) + + for enum in self.enums_to_remove: + self.enums.pop(enum, None) + + for name, value in self.enums.iteritems(): + self.render(value, self.javadir + '/' + value.filename) + for name, value in self.interfaces.iteritems(): + self.render(value, self.javadir + '/' + value.filename) + for name, value in self.classes.iteritems(): + self.render(value, self.javadir + '/' + value.filename) + + self.render(self.jni, self.srcdir + '/linphone_jni.cc') + + def render(self, item, path): + tmppath = path + '.tmp' + content = '' + with open(tmppath, mode='w') as f: + f.write(self.renderer.render(item)) + with open(tmppath, mode='rU') as f: + content = f.read() + with open(path, mode='w') as f: + f.write(content) + os.unlink(tmppath) + + def render_java_enum(self, _class): + if _class is not None: + try: + javaenum = JavaEnum(_class, self.translator) + self.enums[javaenum.className] = javaenum + except AbsApi.Error as e: + print('Could not translate {0}: {1}'.format(_class.name.to_camel_case(fullName=True), e.args[0])) + self.jni.add_methods(javaenum.className, javaenum.jniMethods) + + def render_java_interface(self, _class): + if _class is not None: + try: + javainterface = JavaInterface(_class, self.translator) + self.interfaces[javainterface.className] = javainterface + javaInterfaceStub = JavaInterfaceStub(javainterface) + self.interfaces[javaInterfaceStub.className] = javaInterfaceStub + except AbsApi.Error as e: + print('Could not translate {0}: {1}'.format(_class.name.to_camel_case(fullName=True), e.args[0])) + self.jni.add_methods(javainterface.className, javainterface.jniMethods) + + def render_java_class(self, _class): + if _class is not None: + try: + javaclass = JavaClass(_class, self.translator) + self.classes[javaclass.className] = javaclass + except AbsApi.Error as e: + print('Could not translate {0}: {1}'.format(_class.name.to_camel_case(fullName=True), e.args[0])) + self.jni.add_methods(javaclass.className, javaclass.jniMethods) + +########################################################################## + +def main(): + argparser = argparse.ArgumentParser(description='Generate source files for the Java wrapper') + argparser.add_argument('xmldir', type=str, help='Directory where the XML documentation of the Linphone\'s API generated by Doxygen is placed') + argparser.add_argument('-o --output', type=str, help='the directory where to generate the source files', dest='outputdir', default='.') + argparser.add_argument('-n --name', type=str, help='the name of the genarated source file', dest='outputfile', default='linphone_jni.cc') + args = argparser.parse_args() + + srcdir = args.outputdir + '/src' + javadir = args.outputdir + '/java' + + try: + os.makedirs(srcdir) + except OSError as e: + if e.errno != errno.EEXIST: + print("Cannot create '{0}' dircetory: {1}".format(srcdir, e.strerror)) + sys.exit(1) + + try: + os.makedirs(javadir) + except OSError as e: + if e.errno != errno.EEXIST: + print("Cannot create '{0}' dircetory: {1}".format(javadir, e.strerror)) + sys.exit(1) + + genwrapper = GenWrapper(srcdir, javadir, args.xmldir) + genwrapper.render_all() + +if __name__ == '__main__': + main() diff --git a/wrappers/java/java_class.mustache b/wrappers/java/java_class.mustache new file mode 100644 index 000000000..cd8284ea9 --- /dev/null +++ b/wrappers/java/java_class.mustache @@ -0,0 +1,156 @@ +/* +{{className}}.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package {{packageName}} + +{{#imports}} +import {{import}} +{{/imports}} +{{#isLinphoneFactory}} +import org.linphone.mediastream.Version; +{{/isLinphoneFactory}} + +{{#doc}} +/** + {{#lines}} + * {{line}} + {{/lines}} + */ +{{/doc}} +public interface {{className}} { +{{#enums}} + enum {{className}} { + {{#values}} + {{#doc}} + /** + {{#lines}} + * {{line}} + {{/lines}} + */ + {{/doc}} + {{name}}({{value}}){{commarorsemicolon}} + + {{/values}} + protected final int mValue; + + private {{className}} (int value) { + mValue = value; + } + + static protected {{className}} fromInt(int value) throws CoreException { + switch(value) { + {{#values}} + case {{value}}: return {{name}}; + {{/values}} + default: + throw new CoreException("Unhandled enum value " + value + " for {{className}}"); + } + } + }; + +{{/enums}} +{{#isLinphoneFactory}} + +{{/isLinphoneFactory}} +{{#methods}} + {{#doc}} + /** + {{#lines}} + * {{line}} + {{/lines}} + */ + {{/doc}} + {{#deprecated}}@deprecated + {{/deprecated}}public {{return}} {{name}}({{params}}){{#exception}} throws CoreException{{/exception}}; + +{{/methods}} + +{{#staticMethods}} + {{#doc}} + /** + {{#lines}} + * {{line}} + {{/lines}} + */ + {{/doc}} + public {{return}} {{name}}({{params}}){{#exception}} throws CoreException{{/exception}}; + +{{/staticMethods}} +} + +class {{classImplName}} implements {{className}} { + + protected long nativePtr = 0; + +{{#isLinphoneFactory}} + private static boolean loadOptionalLibrary(String s) { + try { + System.loadLibrary(s); + return true; + } catch (Throwable e) { + android.util.Log.w("LinphoneCoreFactoryImpl", "Unable to load optional library " + s + ": " +e.getMessage()); + } + return false; + } + + static { + System.loadLibrary("gnustl_shared"); + loadOptionalLibrary("ffmpeg-linphone"); + System.loadLibrary("bctoolbox"); + System.loadLibrary("ortp"); + System.loadLibrary("mediastreamer_base"); + System.loadLibrary("mediastreamer_voip"); + System.loadLibrary("linphone"); + Version.dumpCapabilities(); + } +{{/isLinphoneFactory}} + +{{#methods}} + private native {{return_native}} {{name}}({{native_params}}); + public {{return}} {{name}}({{params}}) {{#exception}}throws CoreException{{/exception}} { + {{#convertInputClassArrayToLongArray}} + long[] longArray = new long[{{native_params_impl_list_param_name}}.length]; + for (int i=0; i < {{native_params_impl_list_param_name}}.length; i++) { + longArray[i] = (({{native_params_impl_list_param_type}}){{native_params_impl_list_param_name}}[i]).nativePtr; + } + {{name}}(nativePtr{{native_params_impl}}); + {{/convertInputClassArrayToLongArray}} + {{#convertOutputClassArrayToLongArray}} + long[] longArray = {{name}}(nativePtr{{native_params_impl}}); + if (longArray == null) return null; + + {{native_params_impl_list_param_type}}[] classArray = new {{native_params_impl_list_param_type}}[longArray.length]; + for (int i=0; i < longArray.length; i++) { + classArray[i] = new {{native_params_impl_list_param_type}}Impl(longArray[i]); + } + return classArray; + {{/convertOutputClassArrayToLongArray}} + {{#classicMethod}} + {{return_keyword}}{{name}}(nativePtr{{native_params_impl}}); + {{/classicMethod}} + } + +{{/methods}} + +{{#staticMethods}} + @Override + private native {{return_native}} {{name}}({{static_native_params}}); + +{{/staticMethods}} +} \ No newline at end of file diff --git a/wrappers/java/java_enum.mustache b/wrappers/java/java_enum.mustache new file mode 100644 index 000000000..a890ff72e --- /dev/null +++ b/wrappers/java/java_enum.mustache @@ -0,0 +1,60 @@ +/* +{{className}}.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package {{packageName}} + +{{#imports}} +import {{import}} +{{/imports}} + +{{#doc}} +/** + {{#lines}} + * {{line}} + {{/lines}} + */ +{{/doc}} +public enum {{className}} { +{{#values}} + {{#doc}} + /** + {{#lines}} + * {{line}} + {{/lines}} + */ + {{/doc}} + {{name}}({{value}}){{commarorsemicolon}} + +{{/values}} + protected final int mValue; + + private {{className}} (int value) { + mValue = value; + } + + static protected {{className}} fromInt(int value) throws CoreException { + switch(value) { + {{#values}} + case {{value}}: return {{name}}; + {{/values}} + default: + throw new CoreException("Unhandled enum value " + value + " for {{className}}"); + } + } +} \ No newline at end of file diff --git a/wrappers/java/java_enum_old.mustache b/wrappers/java/java_enum_old.mustache new file mode 100644 index 000000000..81f01e1bb --- /dev/null +++ b/wrappers/java/java_enum_old.mustache @@ -0,0 +1,65 @@ +/* +{{className}}.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package {{packageName}} + +{{#imports}} +import {{import}} +{{/imports}} + +{{#doc}} +/** + {{#lines}} + * {{line}} + {{/lines}} + */ +{{/doc}} +static public class {{className}} { + static private Vector<{{className}}> values = new Vector<{{className}}>(); +{{#values}} + + {{#doc}} + /** + {{#lines}} + * {{line}} + {{/lines}} + */ + {{/doc}} + static public {{className}} {{name}} = new {{className}}({{value}}, {{name}}); +{{/values}} + + protected final int mValue; + private final String mStringValue; + + private {{className}}(int value, String stringValue) { + mValue = value; + values.addElement(this); + mStringValue = stringValue; + } + public static {{className}} fromInt(int value) { + for (int i = 0; i < values.size(); i++) { + {{className}} mstate = ({{className}}) values.elementAt(i); + if (mstate.mValue == value) return mstate; + } + throw new RuntimeException("{{className}} not found [" + value + "]"); + } + public String toString() { + return mStringValue; + } +} \ No newline at end of file diff --git a/wrappers/java/java_interface.mustache b/wrappers/java/java_interface.mustache new file mode 100644 index 000000000..9832f7a8d --- /dev/null +++ b/wrappers/java/java_interface.mustache @@ -0,0 +1,46 @@ +/* +{{className}}.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package {{packageName}} + +{{#imports}} +import {{import}} +{{/imports}} + +{{#doc}} +/** + {{#lines}} + * {{line}} + {{/lines}} + */ +{{/doc}} +public interface {{className}} { +{{#methods}} + {{#doc}} + /** + {{#lines}} + * {{line}} + {{/lines}} + */ + {{/doc}} + {{#deprecated}}@deprecated + {{/deprecated}}public {{return}} {{name}}({{params}}){{#exception}} throws CoreException{{/exception}}; + +{{/methods}} +} \ No newline at end of file diff --git a/wrappers/java/java_interface_stub.mustache b/wrappers/java/java_interface_stub.mustache new file mode 100644 index 000000000..afb401674 --- /dev/null +++ b/wrappers/java/java_interface_stub.mustache @@ -0,0 +1,34 @@ +/* +{{classNameStub}}.java +Copyright (C) 2010 Belledonne Communications, Grenoble, France + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +package {{packageName}} + +{{#imports}} +import {{import}} +{{/imports}} + +public class {{classNameStub}} implements {{className}} { +{{#methods}} + @Override + public {{return}} {{name}}({{params}}){{#exception}} throws CoreException{{/exception}} { + // Auto-generated method stub + } + +{{/methods}} +} \ No newline at end of file diff --git a/wrappers/java/jni.mustache b/wrappers/java/jni.mustache new file mode 100644 index 000000000..7c5b17133 --- /dev/null +++ b/wrappers/java/jni.mustache @@ -0,0 +1,38 @@ +/* +linphone_jni.cc +Copyright (C) 2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include +#include + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *ajvm, void *reserved) { +#ifdef __ANDROID__ + ms_set_jvm(ajvm); +#endif /* __ANDROID__ */ + jvm=ajvm; + return JNI_VERSION_1_2; +} + +static const char* GetStringUTFChars(JNIEnv* env, jstring string) { + const char *cstring = string ? env->GetStringUTFChars(string, NULL) : NULL; + return cstring; +} + +static void ReleaseStringUTFChars(JNIEnv* env, jstring string, const char *cstring) { + if (string) env->ReleaseStringUTFChars(string, cstring); +} \ No newline at end of file