Mercurial > hg > orthanc-java
view CodeGeneration/JavaCodeGeneration.py @ 74:0acad1d4eb98
back to mainline
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Fri, 22 Aug 2025 10:25:30 +0200 |
| parents | 156e942b136e |
| children | 1a1ee5a8424c |
line wrap: on
line source
#!/usr/bin/env python3 # SPDX-FileCopyrightText: 2023-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium # SPDX-License-Identifier: GPL-3.0-or-later # Java plugin for Orthanc # Copyright (C) 2023-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium # # 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 3 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, see <http://www.gnu.org/licenses/>. import CodeModel import argparse import json import os import pystache import sys ROOT = os.path.dirname(os.path.realpath(__file__)) ## ## Parse the command-line arguments ## ORTHANC_SDK_DEFAULT_VERSION = CodeModel.ReadOrthancSdkDefaultVersion(os.path.join(ROOT, '..', 'OrthancSDKVersion.cmake')) parser = argparse.ArgumentParser(description = 'Generate C++ native functions to wrap the Orthanc SDK in Java.') parser.add_argument('--sdk', default = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), '../Resources/Orthanc/Sdk-%s/orthanc/OrthancCPlugin.h' % ORTHANC_SDK_DEFAULT_VERSION), help = 'Path to the Orthanc SDK') parser.add_argument('--model', default = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), '../Resources/Orthanc/OrthancPluginCodeModel.json'), help = 'Input code model, as generated by the orthanc project') parser.add_argument('--target', default = '/tmp/OrthancJavaSDK', help = 'Target folder') parser.add_argument('--custom-functions', default = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'CustomFunctions.json'), help = 'Input list of custom global functions') parser.add_argument('--custom-methods', default = os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), 'CustomMethods.json'), help = 'Input list of custom methods') args = parser.parse_args() TARGET = os.path.join(args.target, 'be', 'uclouvain', 'orthanc') try: # "exist_ok = True" is not available on Python 2.7, which is still in use on our CIS for Ubuntu 16.04 os.makedirs(TARGET) except: pass SDK_VERSION = CodeModel.ReadOrthancSdkVersion(args.sdk) renderer = pystache.Renderer( escape = lambda u: u, # No escaping ) model = CodeModel.Load(args.model, customFunctionsPath = args.custom_functions, customMethodsPath = args.custom_methods) print('** Generating the Java classes to wrap Orthanc SDK %d.%d.%d **' % (SDK_VERSION[0], SDK_VERSION[1], SDK_VERSION[2])) with open(os.path.join(ROOT, 'JavaNativeSDK.mustache'), 'r') as f: template = f.read() with open(os.path.join(TARGET, 'NativeSDK.java'), 'w') as g: functions = [] for f in model['native_functions']: if CodeModel.IsPrimitiveAvailable(SDK_VERSION, f): functions.append(f) g.write(renderer.render(template, { 'functions' : functions })) with open(os.path.join(ROOT, 'JavaFunctions.mustache'), 'r') as f: template = f.read() # Export the global functions with open(os.path.join(TARGET, 'Functions.java'), 'w') as g: functions = [] for f in model['native_functions']: if (f['class_name'] == None and f['return'].get('is_object') != True and CodeModel.IsPrimitiveAvailable(SDK_VERSION, f)): functions.append(f) g.write(renderer.render(template, { 'functions' : functions })) for enum in model['enumerations']: if CodeModel.IsPrimitiveAvailable(SDK_VERSION, enum): enum['values'] = list(filter(lambda value: CodeModel.IsPrimitiveAvailable(SDK_VERSION, value, key_prefix = enum['name']), enum['values'])) enum['values'][-1]['last'] = True with open(os.path.join(ROOT, 'JavaEnumeration.mustache'), 'r') as f: template = f.read() with open(os.path.join(TARGET, '%s.java' % enum['short_name']), 'w') as g: g.write(renderer.render(template, enum)) with open(os.path.join(ROOT, 'ClassDocumentation.json'), 'r') as f: classDocumentation = json.loads(f.read()) for cls in model['classes']: if CodeModel.IsPrimitiveAvailable(SDK_VERSION, cls): with open(os.path.join(ROOT, 'JavaClass.mustache'), 'r') as f: template = f.read() constructors = [] for f in model['native_functions']: if (f['class_name'] == None and f['return'].get('is_object') == True and f['return']['class_name'] == cls['name'] and CodeModel.IsPrimitiveAvailable(SDK_VERSION, f)): constructors.append(f) with open(os.path.join(TARGET, '%s.java' % cls['short_name']), 'w') as g: if not cls['name'] in classDocumentation: raise Exception('No global documentation for class: %s' % cls['name']) methods = [] for method in cls['wrapped_methods']: if CodeModel.IsPrimitiveAvailable(SDK_VERSION, method): methods.append(method) g.write(renderer.render(template, { 'destructor' : cls.get('destructor'), 'class_name' : cls['short_name'], 'methods' : methods, 'constructors' : constructors, 'has_documentation' : True, 'documentation' : classDocumentation[cls['name']], }))
