From 362625bfa9471c0b4bcb88b34ea287c11765179a Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 7 Jan 2018 11:44:20 +0100 Subject: [PATCH] [Ada] Add Ada support for server code generator #6680 (#7256) * Add Ada client petstore samples - Add script to generate Ada client support with swagger-codegen - Add files to build the Ada sample - Add main program to use the generated client samples API and connect to the server to perform some operations * Add some description for the samples * Update the documentation to explain how to build, how to use the generated Ada client code * Add server support for path parameters - Update postProcessOperations to scan each path parameter and emit a x-path-index vendor attribute to tell the index of the path parameter * Add and fix Ada server code package declaration - fix declaration of operations - generate a generic package that must be instantiated with the target server implementation and which provides the skeleton (deserialization and serialization of data) * Implement the Ada server side operations - extract body, query parameters, path parameters - serialize the result - register operations to the server according to the path/routes * Update the code generation to generate server Ada implementation code * Improvement of Ada server support: generate the swagger.json template file * Define toModelName operation to the creation of a model identifier * Add support for server permission generation - collect the security scopes in postProcessAuthMethod() method and make sure these scopes have unique identifiers. Some scopes correspond to URLs but others correspond to pseudo identifiers. * Use the #lambdaAdaComment filter to indent correctly a multi-line description * Fix model generation to support arrays * Update the generated GNAT project file * Refactoring and improvement of server code generation - Change the server generated code to pass a Context_Type object to allow the server implementation to get/set headers in the request/response and control what is put in some responses - Generate the security permissions based on the scopes that have been collected * Server code generation improvement - Fix generation of GNAT project - Generate the intermediate Ada packages if necessary - Generate the server main * Ada server main template * Ada server code improvement - Add support to generate server permission verification - Fix the GNAT project definition - Templates for Ada intermediate packages * Skeleton for the server side implementation * Generate an empty Ada server implementation * Templates for the Ada server implementation * Add a README.md file and a GNAT config.gpr file * New templates to document the generated Ada server * Add server configuration file for the Ada server * Fix the log message in the Ada server to report the correct URI to connect to * Generate the Ada server configuration file * Improvement of Ada code model to support nullable types * Update the Ada server templates * Refactor the Ada code generator - separate the Ada client and Ada server code generators - register the Ada server code generator under the name 'ada-server' keep 'ada' for the client Ada code generator - moved the common Ada code operation supports to the AbstractAdaCodegen * Improvement and cleanup of Ada client and server code - new template for the client main program - fix the GNAT project template for client or server programs - remove unused options to better use the --model-package option * Fix the GNAT project file name to use a lower case name Fix the default GNAT config Fix the headers of intermediate Ada package files * Regenerate the model and client Ada files * Update the Ada client sample to take into account the Nullable types * Regenerate some files with Ada Swagger Codegen * Ignore generation of petstore.gpr --- .../codegen/languages/AbstractAdaCodegen.java | 461 +++++++++++++++++- .../swagger/codegen/languages/AdaCodegen.java | 346 ++----------- .../codegen/languages/AdaServerCodegen.java | 111 +++++ .../src/main/resources/Ada/README.mustache | 102 ++++ .../main/resources/Ada/client-body.mustache | 7 +- .../main/resources/Ada/client-spec.mustache | 2 +- .../src/main/resources/Ada/client.mustache | 43 ++ .../src/main/resources/Ada/config.gpr | 88 ++++ .../main/resources/Ada/gnat-project.mustache | 11 +- .../main/resources/Ada/model-body.mustache | 4 +- .../main/resources/Ada/model-spec.mustache | 14 +- .../Ada/package-spec-level1.mustache | 14 + .../Ada/package-spec-level2.mustache | 14 + .../main/resources/Ada/server-body.mustache | 27 +- .../resources/Ada/server-properties.mustache | 22 + .../Ada/server-skeleton-body.mustache | 231 +++++++++ .../Ada/server-skeleton-spec.mustache | 115 +++++ .../main/resources/Ada/server-spec.mustache | 35 +- .../src/main/resources/Ada/server.mustache | 43 ++ .../src/main/resources/Ada/swagger.mustache | 1 + .../services/io.swagger.codegen.CodegenConfig | 1 + .../petstore/ada/.swagger-codegen-ignore | 1 + samples/client/petstore/ada/petstore.gpr | 16 +- .../src/client/samples-petstore-clients.adb | 22 +- .../src/client/samples-petstore-clients.ads | 22 +- .../samples-petstore-models.adb | 14 +- .../samples-petstore-models.ads | 56 ++- samples/client/petstore/ada/src/petstore.adb | 66 +-- .../petstore/ada/src/samples-petstore.ads | 14 +- samples/client/petstore/ada/src/samples.ads | 14 +- 30 files changed, 1498 insertions(+), 419 deletions(-) create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaServerCodegen.java create mode 100644 modules/swagger-codegen/src/main/resources/Ada/README.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/client.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/config.gpr create mode 100644 modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/server-skeleton-body.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/server-skeleton-spec.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/server.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/swagger.mustache rename samples/client/petstore/ada/src/{client => model}/samples-petstore-models.adb (99%) rename samples/client/petstore/ada/src/{client => model}/samples-petstore-models.ads (86%) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractAdaCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractAdaCodegen.java index eb6e0263ac9..9b3cf2132ef 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractAdaCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AbstractAdaCodegen.java @@ -1,13 +1,26 @@ package io.swagger.codegen.languages; -import io.swagger.codegen.CodegenConfig; -import io.swagger.codegen.CodegenProperty; -import io.swagger.codegen.DefaultCodegen; -import io.swagger.models.properties.Property; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.samskivert.mustache.Escapers; +import com.samskivert.mustache.Mustache; +import io.swagger.codegen.*; +import io.swagger.models.Model; +import io.swagger.models.Operation; +import io.swagger.models.Response; +import io.swagger.models.Swagger; +import io.swagger.models.properties.*; +import io.swagger.util.Json; -import java.util.Arrays; +import java.util.*; abstract public class AbstractAdaCodegen extends DefaultCodegen implements CodegenConfig { + protected String packageName = "swagger"; + protected String projectName = "Swagger"; + protected List> orderedModels; + protected Map> modelDepends; + protected Map nullableTypeMapping; + protected HashMap operationsScopes; + protected int scopeIndex = 0; public AbstractAdaCodegen() { super(); @@ -90,6 +103,56 @@ public AbstractAdaCodegen() { "with", "xor") ); + + typeMapping = new HashMap(); + typeMapping.put("date", "Swagger.Date"); + typeMapping.put("DateTime", "Swagger.Datetime"); + typeMapping.put("string", "Swagger.UString"); + typeMapping.put("integer", "Integer"); + typeMapping.put("long", "Swagger.Long"); + typeMapping.put("boolean", "Boolean"); + typeMapping.put("array", "Swagger.Vector"); + typeMapping.put("map", "Swagger.Map"); + typeMapping.put("object", "Swagger.Object"); + typeMapping.put("number", "Swagger.Number"); + typeMapping.put("UUID", "Swagger.UString"); + typeMapping.put("file", "Swagger.Http_Content_Type"); + typeMapping.put("binary", "Swagger.Binary"); + + nullableTypeMapping = new HashMap(); + nullableTypeMapping.put("date", "Swagger.Nullable_Date"); + nullableTypeMapping.put("DateTime", "Swagger.Nullable_Date"); + nullableTypeMapping.put("string", "Swagger.Nullable_UString"); + nullableTypeMapping.put("integer", "Swagger.Nullable_Integer"); + nullableTypeMapping.put("long", "Swagger.Nullable_Long"); + nullableTypeMapping.put("boolean", "Swagger.Nullable_Boolean"); + nullableTypeMapping.put("object", "Swagger.Object"); + + modelDepends = new HashMap>(); + orderedModels = new ArrayList>(); + operationsScopes = new HashMap(); + super.importMapping = new HashMap(); + + // CLI options + addOption(CodegenConstants.PROJECT_NAME, "GNAT project name", + this.projectName); + + modelNameSuffix = "_Type"; + embeddedTemplateDir = templateDir = "Ada"; + + languageSpecificPrimitives = new HashSet( + Arrays.asList("integer", "boolean", "Integer", "Character", "Boolean", "long", "float", "double")); + } + + protected void addOption(String key, String description, String defaultValue) { + CliOption option = new CliOption(key, description); + if (defaultValue != null) + option.defaultValue(defaultValue); + cliOptions.add(option); + } + + public String toFilename(String name) { + return name.replace(".", "-").toLowerCase(); } /** @@ -152,12 +215,394 @@ public String toParamName(String name) { return toAdaIdentifier(super.toParamName(name), "P_"); } + /** + * Output the proper model name (capitalized). + * In case the name belongs to the TypeSystem it won't be renamed. + * + * @param name the name of the model + * @return capitalized model name + */ + public String toModelName(final String name) { + String result = super.toModelName(name); + if (result.matches("^\\d.*") || result.startsWith("_")) { + result = "Model_" + result; + } + return result.replaceAll("[\\.-]", "_").replaceAll("__+", "_"); + } + @Override public CodegenProperty fromProperty(String name, Property p) { CodegenProperty property = super.fromProperty(name, p); - String nameInCamelCase = property.nameInCamelCase; - nameInCamelCase = sanitizeName(nameInCamelCase); - property.nameInCamelCase = nameInCamelCase; + if (property != null) { + String nameInCamelCase = property.nameInCamelCase; + nameInCamelCase = sanitizeName(nameInCamelCase); + property.nameInCamelCase = nameInCamelCase; + } return property; } + + /** + * Escapes a reserved word as defined in the `reservedWords` array. Handle + * escaping those terms here. This logic is only called if a variable + * matches the reserved words + * + * @return the escaped term + */ + @Override + public String escapeReservedWord(String name) { + return "p_" + name; // add an underscore to the name + } + + @Override + public String escapeQuotationMark(String input) { + // remove " to avoid code injection + return input.replace("\"", ""); + } + + @Override + public String escapeUnsafeCharacters(String input) { + return input.replace("*/", "*_/").replace("/*", "/_*").replace("-", "_"); + } + + /** + * Override the Mustache compiler configuration. + * + * We don't want to have special characters escaped + * + * @param compiler the compiler. + * @return the compiler to use. + */ + @Override + public Mustache.Compiler processCompiler(Mustache.Compiler compiler) { + compiler = super.processCompiler(compiler).emptyStringIsFalse(true); + + return compiler.withEscaper(Escapers.NONE); + } + + /** + * Optional - type declaration. This is a String which is used by the + * templates to instantiate your types. There is typically special handling + * for different property types + * + * @return a string value used as the `dataType` field for model templates, + * `returnType` for api templates + */ + @Override + public String getTypeDeclaration(Property p) { + String swaggerType = getSwaggerType(p); + + if (swaggerType != null) { + swaggerType = swaggerType.replace("-", "_"); + } + + if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + Property inner = ap.getItems(); + return getTypeDeclaration(inner) + "_Vectors.Vector"; + } + if (p instanceof MapProperty) { + MapProperty mp = (MapProperty) p; + Property inner = mp.getAdditionalProperties(); + String name = getTypeDeclaration(inner) + "_Map"; + if (name.startsWith("Swagger.")) { + return name; + } else { + return "Swagger." + name; + } + } + if (typeMapping.containsKey(swaggerType)) { + if (p.getRequired()) { + return typeMapping.get(swaggerType); + } else { + return nullableTypeMapping.get(swaggerType); + } + } + // LOGGER.info("Swagger type " + swaggerType); + if (languageSpecificPrimitives.contains(swaggerType)) { + return swaggerType; + } + String modelType = toModelName(swaggerType).replace("-", "_"); + if (p instanceof StringProperty || p instanceof DateProperty + || p instanceof DateTimeProperty || p instanceof FileProperty + || languageSpecificPrimitives.contains(modelType)) { + return modelType; + } + + return modelPackage + ".Models." + modelType; + } + + /** + * Overrides postProcessParameter to add a vendor extension "x-is-model-type". + * This boolean indicates that the parameter comes from the model package. + * + * @param parameter CodegenParameter object to be processed. + */ + @Override + public void postProcessParameter(CodegenParameter parameter){ + // Give the base class a chance to process + super.postProcessParameter(parameter); + + if (parameter.dataType == null) { + return; + } + boolean isModel = parameter.dataType.startsWith(modelPackage); + if (!isModel && !parameter.isPrimitiveType && !parameter.isDate + && !parameter.isString && !parameter.isContainer && !parameter.isFile) { + isModel = true; + } + parameter.vendorExtensions.put("x-is-model-type", isModel); + } + + /** + * Post process the media types (produces and consumes) for Ada code generator. + * + * For each media type, add a adaMediaType member that gives the Ada enum constant + * for the corresponding type. + * + * @param types the list of media types. + * @return the number of media types. + */ + protected int postProcessMediaTypes(List> types) { + int count = 0; + if (types != null) { + for (Map media : types) { + String mt = media.get("mediaType"); + if (mt != null) { + mt = mt.replace('/', '_'); + media.put("adaMediaType", mt.toUpperCase()); + count++; + } + } + } + return count; + } + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, + Map definitions, Swagger swagger) { + CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger); + + if (operation.getResponses() != null && !operation.getResponses().isEmpty()) { + Response methodResponse = findMethodResponse(operation.getResponses()); + + if (methodResponse != null) { + if (methodResponse.getSchema() != null) { + CodegenProperty cm = fromProperty("response", methodResponse.getSchema()); + op.vendorExtensions.put("x-codegen-response", cm); + if(cm.datatype == "HttpContent") { + op.vendorExtensions.put("x-codegen-response-ishttpcontent", true); + } + } + } + } + return op; + } + + @SuppressWarnings("unchecked") + @Override + public Map postProcessOperations(Map objs) { + Map operations = (Map) objs.get("operations"); + List operationList = (List) operations.get("operation"); + + for (CodegenOperation op1 : operationList) { + if (op1.summary != null) { + op1.summary = op1.summary.trim(); + } + if (op1.notes != null) { + op1.notes = op1.notes.trim(); + } + op1.vendorExtensions.put("x-has-uniq-produces", postProcessMediaTypes(op1.produces) == 1); + op1.vendorExtensions.put("x-has-uniq-consumes", postProcessMediaTypes(op1.consumes) == 1); + op1.vendorExtensions.put("x-has-notes", op1.notes != null && op1.notes.length() > 0); + + // Set the file parameter type for both allParams and formParams. + for (CodegenParameter p : op1.allParams) { + if (p.isFormParam && p.isFile) { + p.dataType = "Swagger.File_Part_Type"; + } + } + for (CodegenParameter p : op1.formParams) { + if (p.isFile) { + p.dataType = "Swagger.File_Part_Type"; + } + } + postProcessAuthMethod(op1.authMethods); + + /* + * Scan the path parameter to construct a x-path-index that tells the index of + * the path parameter. + */ + for (CodegenParameter p : op1.pathParams) { + String path = op1.path; + int pos = 0; + int index = 0; + while (pos >= 0 && pos < path.length()) { + int last; + pos = path.indexOf('{', pos); + if (pos < 0) { + break; + } + pos++; + last = path.indexOf('}', pos); + index++; + if (last < 0) { + break; + } + if (path.substring(pos, last - 1) == p.baseName) { + break; + } + pos = last + 1; + } + p.vendorExtensions.put("x-path-index", index); + } + } + return objs; + } + + @Override + public Map postProcessModels(Map objs) { + // Collect the model dependencies. + List> models = (List>) objs.get("models"); + for (Map model : models) { + Object v = model.get("model"); + if (v instanceof CodegenModel) { + CodegenModel m = (CodegenModel) v; + List d = new ArrayList(); + for (CodegenProperty p : m.allVars) { + boolean isModel = false; + CodegenProperty item = p; + if (p.isContainer) { + item = p.items; + } + if (item != null && !item.isString && !item.isPrimitiveType && !item.isContainer && !item.isInteger) { + if (!d.contains(item.datatype)) { + // LOGGER.info("Model " + m.name + " uses " + p.datatype); + d.add(item.datatype); + isModel = true; + } + } + p.vendorExtensions.put("x-is-model-type", isModel); + } + modelDepends.put(m.name, d); + orderedModels.add(model); + } + } + + // Sort the models according to dependencies so that model that depend + // on others appear at end of the list. + final Map> deps = modelDepends; + Collections.sort(orderedModels, new Comparator>() { + @Override + public int compare(Map lhs, Map rhs) { + Object v = lhs.get("model"); + String lhsName = ((CodegenModel) v).name; + v = rhs.get("model"); + String rhsName = ((CodegenModel) v).name; + List lhsList = deps.get(lhsName); + List rhsList = deps.get(rhsName); + if (lhsList == rhsList) { + // LOGGER.info("First compare " + lhsName + "<" + rhsName); + return lhsName.compareTo(rhsName); + } + // Put models without dependencies first. + if (lhsList == null) { + // LOGGER.info(" Empty " + lhsName + ", no check " + rhsName); + return -1; + } + if (rhsList == null) { + // LOGGER.info(" No check " + lhsName + ", empty " + rhsName); + return 1; + } + // Put models that depend on another after. + if (lhsList.contains(rhsName)) { + // LOGGER.info(" LSH " + lhsName + " uses " + rhsName); + return 1; + } + if (rhsList.contains(lhsName)) { + // LOGGER.info(" RHS " + rhsName + " uses " + lhsName); + return -1; + } + // Put models with less dependencies first. + if (lhsList.size() < rhsList.size()) { + // LOGGER.info(" LSH size " + lhsName + " < RHS size " + rhsName); + return -1; + } + if (lhsList.size() > rhsList.size()) { + // LOGGER.info(" LSH size " + lhsName + " > RHS size " + rhsName); + return 1; + } + // Sort models on their name. + // LOGGER.info("Compare " + lhsName + "<" + rhsName); + return lhsName.compareTo(rhsName); + } + }); + /* for (Map model : orderedModels) { + Object v = model.get("model"); + if (v instanceof CodegenModel) { + CodegenModel m = (CodegenModel) v; + LOGGER.info("Order: " + m.name); + } + }*/ + return postProcessModelsEnum(objs); + } + + @Override + public Map postProcessSupportingFileData(Map objs) { + objs.put("orderedModels", orderedModels); + Swagger swagger = (Swagger)objs.get("swagger"); + if(swagger != null) { + String host = swagger.getBasePath(); + try { + swagger.setHost("SWAGGER_HOST"); + objs.put("swagger-json", Json.pretty().writeValueAsString(swagger).replace("\r\n", "\n")); + } catch (JsonProcessingException e) { + LOGGER.error(e.getMessage(), e); + } + swagger.setHost(host); + } + + /** + * Collect the scopes to generate unique identifiers for each of them. + */ + List authMethods = (List) objs.get("authMethods"); + postProcessAuthMethod(authMethods); + + return super.postProcessSupportingFileData(objs); + } + + /** + * Collect the scopes to generate a unique identifier for each of them. + * + * @param authMethods the auth methods with their scopes. + */ + private void postProcessAuthMethod(List authMethods) { + if (authMethods != null) { + for (CodegenSecurity authMethod : authMethods) { + if (authMethod.scopes != null) { + for (Map scope : authMethod.scopes) { + String name = (String) scope.get("scope"); + if (operationsScopes.containsKey(name)) { + scope.put("ident", operationsScopes.get(name)); + } else { + String ident; + if (name.startsWith("https://")) { + int pos = name.lastIndexOf('/'); + ident = name.substring(pos + 1); + } else { + ident = name; + } + scopeIndex++; + ident = toAdaIdentifier(sanitizeName(ident.replaceAll(":", "_")), "S_"); + if (operationsScopes.containsValue(ident)) { + ident = ident + "_" + scopeIndex; + } + operationsScopes.put(name, ident); + scope.put("ident", ident); + } + } + } + authMethod.name = camelize(sanitizeName(authMethod.name), true); + } + } + } } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaCodegen.java index 309f9a2bada..84e5443ce6c 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaCodegen.java @@ -1,58 +1,17 @@ package io.swagger.codegen.languages; import java.io.File; -import java.util.*; +import java.io.IOException; +import java.io.Writer; +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; import io.swagger.codegen.*; -import io.swagger.models.Model; -import io.swagger.models.Operation; -import io.swagger.models.Response; -import io.swagger.models.Swagger; -import io.swagger.models.properties.*; public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig { - protected String packageName = "swagger"; - protected String projectName = "Swagger"; - protected List> orderedModels; - protected Map> modelDepends; public AdaCodegen() { super(); - - modelNameSuffix = "_Type"; - orderedModels = new ArrayList>(); - modelDepends = new HashMap>(); - embeddedTemplateDir = templateDir = "Ada"; - - // CLI options - addOption(CodegenConstants.PROJECT_NAME, "GNAT project name", - this.projectName); - addOption(CodegenConstants.PACKAGE_NAME, "Ada package name (convention: name.space.model).", - this.modelPackage); - addOption(CodegenConstants.MODEL_PACKAGE, "Ada package for models (convention: name.space.model).", - this.modelPackage); - addOption(CodegenConstants.API_PACKAGE, "Ada package for apis (convention: name.space.api).", - this.apiPackage); - - languageSpecificPrimitives = new HashSet( - Arrays.asList("integer", "boolean", "Integer", "Character", "Boolean", "long", "float", "double", "int32_t", "int64_t")); - - typeMapping = new HashMap(); - typeMapping.put("date", "Swagger.Date"); - typeMapping.put("DateTime", "Swagger.Datetime"); - typeMapping.put("string", "Swagger.UString"); - typeMapping.put("integer", "Integer"); - typeMapping.put("long", "Swagger.Long"); - typeMapping.put("boolean", "Boolean"); - typeMapping.put("array", "Swagger.Vector"); - typeMapping.put("map", "Swagger.Map"); - typeMapping.put("object", "Swagger.Object"); - typeMapping.put("number", "Swagger.Number"); - typeMapping.put("UUID", "Swagger.UString"); - typeMapping.put("file", "Swagger.Http_Content_Type"); - typeMapping.put("binary", "Swagger.Binary"); - - super.importMapping = new HashMap(); } @Override @@ -70,36 +29,22 @@ public String getHelp() { return "Generates an Ada client implementation (beta)."; } - protected void addOption(String key, String description, String defaultValue) { - CliOption option = new CliOption(key, description); - if (defaultValue != null) - option.defaultValue(defaultValue); - cliOptions.add(option); - } - - public String toFilename(String name) { - return name.replace(".", "-").toLowerCase(); - } - @Override public void processOpts() { super.processOpts(); if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { packageName = (String) additionalProperties.get(CodegenConstants.PACKAGE_NAME); } - String serverPrefix = "src" + File.separator + "server" + File.separator + toFilename(modelPackage); - String clientPrefix = "src" + File.separator + "client" + File.separator + toFilename(modelPackage); - supportingFiles.add(new SupportingFile("model-spec.mustache", null, clientPrefix + "-models.ads")); - supportingFiles.add(new SupportingFile("model-body.mustache", null, clientPrefix + "-models.adb")); - supportingFiles.add(new SupportingFile("model-spec.mustache", null, serverPrefix + "-models.ads")); - supportingFiles.add(new SupportingFile("model-body.mustache", null, serverPrefix + "-models.adb")); + if (packageName == "") { + packageName = modelPackage; + } + String srcPrefix = "src" + File.separator; + String modelPrefix = srcPrefix + "model" + File.separator + toFilename(modelPackage); + String clientPrefix = srcPrefix + "client" + File.separator + toFilename(modelPackage); + supportingFiles.add(new SupportingFile("model-spec.mustache", null, modelPrefix + "-models.ads")); + supportingFiles.add(new SupportingFile("model-body.mustache", null, modelPrefix + "-models.adb")); supportingFiles.add(new SupportingFile("client-spec.mustache", null, clientPrefix + "-clients.ads")); supportingFiles.add(new SupportingFile("client-body.mustache", null, clientPrefix + "-clients.adb")); - supportingFiles.add(new SupportingFile("server-spec.mustache", null, serverPrefix + "-servers.ads")); - supportingFiles.add(new SupportingFile("server-body.mustache", null, serverPrefix + "-servers.adb")); - - // String title = swagger.getInfo().getTitle(); - supportingFiles.add(new SupportingFile("gnat-project.mustache", "", "project.gpr")); if (additionalProperties.containsKey(CodegenConstants.PROJECT_NAME)) { projectName = (String) additionalProperties.get(CodegenConstants.PROJECT_NAME); @@ -108,255 +53,56 @@ public void processOpts() { // e.g. petstore.api (package name) => petstore_api (project name) projectName = packageName.replaceAll("\\.", "_"); } + String configBaseName = modelPackage.toLowerCase(); + supportingFiles.add(new SupportingFile("gnat-project.mustache", "", toFilename(projectName) + ".gpr")); + // supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("config.gpr", "", "config.gpr")); /* * Additional Properties. These values can be passed to the templates and * are available in models, apis, and supporting files */ additionalProperties.put("package", this.modelPackage); + additionalProperties.put("packageConfig", configBaseName); + additionalProperties.put("packageDir", "client"); + additionalProperties.put("mainName", "client"); additionalProperties.put(CodegenConstants.PROJECT_NAME, projectName); - } - - @Override - public String apiFileFolder() { - return outputFolder + "/" + apiPackage().replace('.', File.separatorChar); - } - - @Override - public String modelFileFolder() { - return outputFolder + "/model/" + modelPackage().replace('.', File.separatorChar); - } - - /** - * Escapes a reserved word as defined in the `reservedWords` array. Handle - * escaping those terms here. This logic is only called if a variable - * matches the reserved words - * - * @return the escaped term - */ - @Override - public String escapeReservedWord(String name) { - return "p_" + name; // add an underscore to the name - } - - @Override - public String escapeQuotationMark(String input) { - // remove " to avoid code injection - return input.replace("\"", ""); - } - - @Override - public String escapeUnsafeCharacters(String input) { - return input.replace("*/", "*_/").replace("/*", "/_*"); - } - - /** - * Optional - type declaration. This is a String which is used by the - * templates to instantiate your types. There is typically special handling - * for different property types - * - * @return a string value used as the `dataType` field for model templates, - * `returnType` for api templates - */ - @Override - public String getTypeDeclaration(Property p) { - String swaggerType = getSwaggerType(p); - - if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - Property inner = ap.getItems(); - return getTypeDeclaration(inner) + "_Vectors.Vector"; - } - if (p instanceof MapProperty) { - MapProperty mp = (MapProperty) p; - Property inner = mp.getAdditionalProperties(); - return "Swagger." + getTypeDeclaration(inner) + "_Map"; - } - if (typeMapping.containsKey(swaggerType)) { - return typeMapping.get(swaggerType); - } - // LOGGER.info("Swagger type " + swaggerType); - if (languageSpecificPrimitives.contains(swaggerType)) { - return swaggerType; - } - String modelType = toModelName(swaggerType); - if (p instanceof StringProperty || p instanceof DateProperty - || p instanceof DateTimeProperty || p instanceof FileProperty - || languageSpecificPrimitives.contains(modelType)) { - return modelType; - } - - return modelPackage + ".Models." + modelType; - } - - /** - * Overrides postProcessParameter to add a vendor extension "x-is-model-type". - * This boolean indicates that the parameter comes from the model package. - * - * @param parameter CodegenParameter object to be processed. - */ - @Override - public void postProcessParameter(CodegenParameter parameter){ - // Give the base class a chance to process - super.postProcessParameter(parameter); - - boolean isModel = parameter.dataType.startsWith(modelPackage); - if (!isModel && !parameter.isPrimitiveType && !parameter.isDate - && !parameter.isString && !parameter.isContainer && !parameter.isFile) { - isModel = true; - } - parameter.vendorExtensions.put("x-is-model-type", isModel); - } - /** - * Post process the media types (produces and consumes) for Ada code generator. - * - * For each media type, add a adaMediaType member that gives the Ada enum constant - * for the corresponding type. - * - * @param types the list of media types. - * @return the number of media types. - */ - protected int postProcessMediaTypes(List> types) { - int count = 0; - if (types != null) { - for (Map media : types) { - String mt = media.get("mediaType"); - if (mt != null) { - mt = mt.replace('/', '_'); - media.put("adaMediaType", mt.toUpperCase()); - count++; - } - } + String names[] = this.modelPackage.split("\\."); + String pkgName = names[0]; + additionalProperties.put("packageLevel1", pkgName); + supportingFiles.add(new SupportingFile("package-spec-level1.mustache", null, + "src" + File.separator + toFilename(names[0]) + ".ads")); + if (names.length > 1) { + String fileName = toFilename(names[0]) + "-" + toFilename(names[1]) + ".ads"; + pkgName = names[0] + "." + names[1]; + additionalProperties.put("packageLevel2", pkgName); + supportingFiles.add(new SupportingFile("package-spec-level2.mustache", null, + "src" + File.separator + fileName)); } - return count; - } + pkgName = this.modelPackage; + supportingFiles.add(new SupportingFile("client.mustache", null, + "src" + File.separator + toFilename(pkgName) + "-client.adb")); + additionalProperties.put("packageName", toFilename(pkgName)); - @Override - public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, - Map definitions, Swagger swagger) { - CodegenOperation op = super.fromOperation(path, httpMethod, operation, definitions, swagger); - - if (operation.getResponses() != null && !operation.getResponses().isEmpty()) { - Response methodResponse = findMethodResponse(operation.getResponses()); - - if (methodResponse != null) { - if (methodResponse.getSchema() != null) { - CodegenProperty cm = fromProperty("response", methodResponse.getSchema()); - op.vendorExtensions.put("x-codegen-response", cm); - if(cm.datatype == "HttpContent") { - op.vendorExtensions.put("x-codegen-response-ishttpcontent", true); - } - } + // add lambda for mustache templates + additionalProperties.put("lambdaAdaComment", new Mustache.Lambda() { + @Override + public void execute(Template.Fragment fragment, Writer writer) throws IOException { + String content = fragment.execute(); + content = content.trim().replaceAll("\n$", ""); + writer.write(content.replaceAll("\n", "\n -- ")); } - } - return op; - } - - @SuppressWarnings("unchecked") - @Override - public Map postProcessOperations(Map objs) { - Map operations = (Map) objs.get("operations"); - List operationList = (List) operations.get("operation"); - - for (CodegenOperation op1 : operationList) { - op1.vendorExtensions.put("x-has-uniq-produces", postProcessMediaTypes(op1.produces) == 1); - op1.vendorExtensions.put("x-has-uniq-consumes", postProcessMediaTypes(op1.consumes) == 1); - op1.vendorExtensions.put("x-has-notes", op1.notes.length() > 0); - } - return objs; + }); } @Override - public Map postProcessModels(Map objs) { - // Collect the model dependencies. - List> models = (List>) objs.get("models"); - for (Map model : models) { - Object v = model.get("model"); - if (v instanceof CodegenModel) { - CodegenModel m = (CodegenModel) v; - List d = new ArrayList(); - for (CodegenProperty p : m.allVars) { - boolean isModel = false; - CodegenProperty item = p; - if (p.isContainer) { - item = p.items; - } - if (item != null && !item.isString && !item.isPrimitiveType && !item.isContainer && !item.isInteger) { - if (!d.contains(item.datatype)) { - // LOGGER.info("Model " + m.name + " uses " + p.datatype); - d.add(item.datatype); - isModel = true; - } - } - p.vendorExtensions.put("x-is-model-type", isModel); - } - modelDepends.put(m.name, d); - orderedModels.add(model); - } - } - - // Sort the models according to dependencies so that model that depend - // on others appear at end of the list. - final Map> deps = modelDepends; - Collections.sort(orderedModels, new Comparator>() { - @Override - public int compare(Map lhs, Map rhs) { - Object v = lhs.get("model"); - String lhsName = ((CodegenModel) v).name; - v = rhs.get("model"); - String rhsName = ((CodegenModel) v).name; - List lhsList = deps.get(lhsName); - List rhsList = deps.get(rhsName); - if (lhsList == rhsList) { - // LOGGER.info("First compare " + lhsName + "<" + rhsName); - return lhsName.compareTo(rhsName); - } - // Put models without dependencies first. - if (lhsList == null) { - // LOGGER.info(" Empty " + lhsName + ", no check " + rhsName); - return -1; - } - if (rhsList == null) { - // LOGGER.info(" No check " + lhsName + ", empty " + rhsName); - return 1; - } - // Put models that depend on another after. - if (lhsList.contains(rhsName)) { - // LOGGER.info(" LSH " + lhsName + " uses " + rhsName); - return 1; - } - if (rhsList.contains(lhsName)) { - // LOGGER.info(" RHS " + rhsName + " uses " + lhsName); - return -1; - } - // Put models with less dependencies first. - if (lhsList.size() < rhsList.size()) { - // LOGGER.info(" LSH size " + lhsName + " < RHS size " + rhsName); - return -1; - } - if (lhsList.size() > rhsList.size()) { - // LOGGER.info(" LSH size " + lhsName + " > RHS size " + rhsName); - return 1; - } - // Sort models on their name. - // LOGGER.info("Compare " + lhsName + "<" + rhsName); - return lhsName.compareTo(rhsName); - } - }); - /* for (Map model : orderedModels) { - Object v = model.get("model"); - if (v instanceof CodegenModel) { - CodegenModel m = (CodegenModel) v; - LOGGER.info("Order: " + m.name); - } - }*/ - return postProcessModelsEnum(objs); + public String apiFileFolder() { + return outputFolder + "/" + apiPackage().replace('.', File.separatorChar); } @Override - public Map postProcessSupportingFileData(Map objs) { - objs.put("orderedModels", orderedModels); - return super.postProcessSupportingFileData(objs); + public String modelFileFolder() { + return outputFolder + "/model/" + modelPackage().replace('.', File.separatorChar); } } diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaServerCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaServerCodegen.java new file mode 100644 index 00000000000..951ebec0f6c --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaServerCodegen.java @@ -0,0 +1,111 @@ +package io.swagger.codegen.languages; + +import java.io.File; +import java.io.IOException; +import java.io.Writer; + +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; +import io.swagger.codegen.*; + +public class AdaServerCodegen extends AbstractAdaCodegen implements CodegenConfig { + + public AdaServerCodegen() { + super(); + } + + @Override + public CodegenType getTag() { + return CodegenType.SERVER; + } + + @Override + public String getName() { + return "ada-server"; + } + + @Override + public String getHelp() { + return "Generates an Ada server implementation (beta)."; + } + + @Override + public void processOpts() { + super.processOpts(); + if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { + packageName = (String) additionalProperties.get(CodegenConstants.PACKAGE_NAME); + } + String srcPrefix = "src" + File.separator; + String serverPrefix = srcPrefix + "server" + File.separator + toFilename(modelPackage); + String modelPrefix = srcPrefix + "model" + File.separator + toFilename(modelPackage); + String implPrefix = srcPrefix + toFilename(modelPackage); + supportingFiles.add(new SupportingFile("model-spec.mustache", null, modelPrefix + "-models.ads")); + supportingFiles.add(new SupportingFile("model-body.mustache", null, modelPrefix + "-models.adb")); + supportingFiles.add(new SupportingFile("server-skeleton-spec.mustache", null, serverPrefix + "-skeletons.ads")); + supportingFiles.add(new SupportingFile("server-skeleton-body.mustache", null, serverPrefix + "-skeletons.adb")); + supportingFiles.add(new SupportingFile("server-spec.mustache", null, implPrefix + "-servers.ads")); + supportingFiles.add(new SupportingFile("server-body.mustache", null, implPrefix + "-servers.adb")); + + supportingFiles.add(new SupportingFile("swagger.mustache", "web" + File.separator + "swagger", "swagger.json")); + + if (additionalProperties.containsKey(CodegenConstants.PROJECT_NAME)) { + projectName = (String) additionalProperties.get(CodegenConstants.PROJECT_NAME); + } else { + // default: set project based on package name + // e.g. petstore.api (package name) => petstore_api (project name) + projectName = packageName.replaceAll("\\.", "_"); + } + String configBaseName = modelPackage.toLowerCase(); + supportingFiles.add(new SupportingFile("gnat-project.mustache", "", toFilename(projectName) + ".gpr")); + supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + supportingFiles.add(new SupportingFile("config.gpr", "", "config.gpr")); + supportingFiles.add(new SupportingFile("server-properties.mustache", "", configBaseName + ".properties")); + + /* + * Additional Properties. These values can be passed to the templates and + * are available in models, apis, and supporting files + */ + additionalProperties.put("package", this.modelPackage); + additionalProperties.put("packageConfig", configBaseName); + additionalProperties.put("packageDir", "server"); + additionalProperties.put("mainName", "server"); + additionalProperties.put(CodegenConstants.PROJECT_NAME, projectName); + + String names[] = this.modelPackage.split("\\."); + String pkgName = names[0]; + additionalProperties.put("packageLevel1", pkgName); + supportingFiles.add(new SupportingFile("package-spec-level1.mustache", null, + "src" + File.separator + toFilename(names[0]) + ".ads")); + if (names.length > 1) { + String fileName = toFilename(names[0]) + "-" + toFilename(names[1]) + ".ads"; + pkgName = names[0] + "." + names[1]; + additionalProperties.put("packageLevel2", pkgName); + supportingFiles.add(new SupportingFile("package-spec-level2.mustache", null, + "src" + File.separator + fileName)); + } + pkgName = this.modelPackage; + supportingFiles.add(new SupportingFile("server.mustache", null, + "src" + File.separator + toFilename(pkgName) + "-server.adb")); + additionalProperties.put("packageName", toFilename(pkgName)); + + // add lambda for mustache templates + additionalProperties.put("lambdaAdaComment", new Mustache.Lambda() { + @Override + public void execute(Template.Fragment fragment, Writer writer) throws IOException { + String content = fragment.execute(); + content = content.trim().replaceAll("\n$", ""); + writer.write(content.replaceAll("\n", "\n -- ")); + } + }); + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + apiPackage().replace('.', File.separatorChar); + } + + @Override + public String modelFileFolder() { + return outputFolder + "/model/" + modelPackage().replace('.', File.separatorChar); + } +} diff --git a/modules/swagger-codegen/src/main/resources/Ada/README.mustache b/modules/swagger-codegen/src/main/resources/Ada/README.mustache new file mode 100644 index 00000000000..e6f363236b7 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/README.mustache @@ -0,0 +1,102 @@ +# {{appDescription}} - Swagger Ada Server + +## Overview + +This Ada server was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. +By using the [OpenAPI-Spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, +you can easily generate a server stub. + +## Building + +To build the server you will need the GNAT Ada compiler as well as +the [Swagger Ada library](https://github.com/stcarrez/swagger-ada). + +When the GNAT Ada compiler and Swagger Ada libraries are installed, +run the following command: + +``` + gprbuild -p -P{{projectName}} +``` + +After the build is successfull, you will get the server binary +in bin/{{packageName}}-server and you can start it as follows: +``` + ./bin/{{packageName}}-server +``` + +## Structure of the server + +The server consists of several Ada packages that are generated from +the OpenAPI specification. + +Source file | Package | Description +------------ | ------------- | ------------- +src/{{packageName}}.ads|{{package}}|The server root package declaration +src/{{packageName}}-servers.ads|{{package}}.Servers|The server declaration and instantiation +src/{{packageName}}-servers.adb|{{package}}.Servers|The server implementation (empty stubs) +src/server/{{packageName}}-skeletons.ads|{{package}}.Skeletons|The server skeleton declaration +src/server/{{packageName}}-skeletons.adb|{{package}}.Skeletons|The server skeleton implementation +src/server/{{packageName}}-models.ads|{{package}}.Skeletons|The server model types declaration +src/server/{{packageName}}-models.adb|{{package}}.Skeletons|The server model types implementation +src/{{packageName}}-server.adb|{{package}}.Server|The server main procedure + +Files generated in **src/server** should not be modified. The server implementation +files (**src/{{packageName}}-server.ads** and **src/{{packageName}}-server.adb**) should +be modified to implement the server operations. You can also customize the server +main procedure according to your needs. + +## Server model + +The server instance is represented by the **{{package}}.Servers.Server_Type** Ada type. +The REST API will need an instance of it to make the operation call. Two server model +exists: + +* The instance per request model creates an instance of the server type for each request. +* The shared instance model shares the same instance across all concurrent REST requests. This instance is protected using an Ada protected object which holds the server instance. + +The choice of the server model is made at the compilation time by instantiating either +the **{{package}}.Skeletons.Skeleton** package or the **{{package}}.Skeletons.Shared_Instance** +package. Such instantiation is done in **src/{{packageName}}-server.ads** and the default +is to use the **Shared_Instance**. + +## Implementing a server operation + +All you have to do is implement the server operation in the **src/{{packageName}}-servers.adb** file. +The package already contains the operation with its parameters and you only have to replace +the **null** instruction by real code. + +# Documentation + +## API Documentation + +All URIs are relative to *{{basePath}}* + +Method | HTTP request | Description +------------- | ------------- | ------------- +{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}[**{{nickname}}**]({{apiDocPath}}{{classname}}.md#{{nickname}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}} +{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}} + +## Models +{{#models}}{{#model}} - [{{package}}.Models.{{classname}}]({{modelDocPath}}{{classname}}.md) +{{/model}}{{/models}} + +## Authorization +{{^authMethods}} All endpoints do not require authorization. +{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}} +{{#authMethods}}## {{{name}}} + +{{#isApiKey}}- **Type**: API key +- **API key parameter name**: {{{keyParamName}}} +- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}} +{{/isApiKey}} +{{#isBasic}}- **Type**: HTTP basic authentication +{{/isBasic}} +{{#isOAuth}}- **Type**: OAuth +- **Flow**: {{{flow}}} +- **Authorization URL**: {{{authorizationUrl}}} +- **Scopes**: {{^scopes}}N/A{{/scopes}} +{{#scopes}} - **{{{scope}}}**: {{{description}}} +{{/scopes}} +{{/isOAuth}} + +{{/authMethods}} diff --git a/modules/swagger-codegen/src/main/resources/Ada/client-body.mustache b/modules/swagger-codegen/src/main/resources/Ada/client-body.mustache index 0aa184749af..bd2632e1d6e 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/client-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/client-body.mustache @@ -7,7 +7,7 @@ package body {{package}}.Clients is {{#operation}} -- {{summary}}{{#vendorExtensions.x-has-notes}} - -- {{unescapedNotes}}{{/vendorExtensions.x-has-notes}} + -- {{#lambdaAdaComment}}{{unescapedNotes}}{{/lambdaAdaComment}}{{/vendorExtensions.x-has-notes}} procedure {{operationId}} (Client : in out Client_Type{{#hasParams}};{{/hasParams}}{{#allParams}} {{paramName}} : in {{^isFile}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}{{package}}.Models.{{/isContainer}}{{/isPrimitiveType}}{{/isString}}{{/isFile}}{{dataType}}{{#hasMore}};{{/hasMore}}{{/allParams}}{{#returnType}}; @@ -19,8 +19,9 @@ package body {{package}}.Clients is Reply : Swagger.Value_Type; {{/returnType}} begin - Client.Set_Accept (({{#hasProduces}}{{#produces}}{{#vendorExtensions.x-has-uniq-produces}}1 => {{/vendorExtensions.x-has-uniq-produces}}Swagger.Clients.{{adaMediaType}}{{#hasMore}}, - {{/hasMore}}{{/produces}}{{/hasProduces}}));{{#hasBodyParam}} +{{#hasProduces}} + Client.Set_Accept (({{#produces}}{{#vendorExtensions.x-has-uniq-produces}}1 => {{/vendorExtensions.x-has-uniq-produces}}Swagger.Clients.{{adaMediaType}}{{#hasMore}}, + {{/hasMore}}{{/produces}}));{{/hasProduces}}{{#hasBodyParam}} Client.Initialize (Req, ({{#hasConsumes}}{{#consumes}}{{#vendorExtensions.x-has-uniq-consumes}}1 -> {{/vendorExtensions.x-has-uniq-consumes}}Swagger.Clients.{{adaMediaType}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{/hasConsumes}}{{^hasConsumes}}1 => Swagger.Clients.APPLICATION_JSON{{/hasConsumes}}));{{#bodyParams}}{{#vendorExtensions.x-is-model-type}} {{package}}.Models.Serialize (Req.Stream, "{{baseName}}", {{paramName}});{{/vendorExtensions.x-is-model-type}}{{^vendorExtensions.x-is-model-type}}{{#isFile}} diff --git a/modules/swagger-codegen/src/main/resources/Ada/client-spec.mustache b/modules/swagger-codegen/src/main/resources/Ada/client-spec.mustache index 67ca7d08c22..097356ffa89 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/client-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/client-spec.mustache @@ -12,7 +12,7 @@ package {{package}}.Clients is {{#operations}} {{#operation}} -- {{summary}}{{#vendorExtensions.x-has-notes}} - -- {{unescapedNotes}}{{/vendorExtensions.x-has-notes}} + -- {{#lambdaAdaComment}}{{unescapedNotes}}{{/lambdaAdaComment}}{{/vendorExtensions.x-has-notes}} procedure {{operationId}} (Client : in out Client_Type{{#hasParams}};{{/hasParams}}{{#allParams}} {{paramName}} : in {{^isFile}}{{^isString}}{{^isPrimitiveType}}{{^isContainer}}{{package}}.Models.{{/isContainer}}{{/isPrimitiveType}}{{/isString}}{{/isFile}}{{dataType}}{{#hasMore}};{{/hasMore}}{{/allParams}}{{#returnType}}; diff --git a/modules/swagger-codegen/src/main/resources/Ada/client.mustache b/modules/swagger-codegen/src/main/resources/Ada/client.mustache new file mode 100644 index 00000000000..501bad4ec7c --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/client.mustache @@ -0,0 +1,43 @@ +with {{package}}.Clients; +with {{package}}.Models; +with Swagger; +with Util.Http.Clients.Curl; +with Ada.Text_IO; +with Ada.Command_Line; +with Ada.Calendar.Formatting; +with Ada.Exceptions; +procedure {{package}}.Client is + + use Ada.Text_IO; + + procedure Usage; + + Server : constant Swagger.UString := Swagger.To_UString ("http://localhost:8080/v2"); + Arg_Count : constant Natural := Ada.Command_Line.Argument_Count; + Arg : Positive := 1; + + procedure Usage is + begin + Put_Line ("Usage: {{projectName}} {params}..."); + end Usage; + +begin + if Arg_Count <= 1 then + Usage; + return; + end if; + Util.Http.Clients.Curl.Register; + declare + Command : constant String := Ada.Command_Line.Argument (Arg); + Item : constant String := Ada.Command_Line.Argument (Arg + 1); + C : {{package}}.Clients.Client_Type; + begin + C.Set_Server (Server); + Arg := Arg + 2; + + exception + when E : Constraint_Error => + Put_Line ("Constraint error raised: " & Ada.Exceptions.Exception_Message (E)); + + end; +end {{package}}.Client; diff --git a/modules/swagger-codegen/src/main/resources/Ada/config.gpr b/modules/swagger-codegen/src/main/resources/Ada/config.gpr new file mode 100644 index 00000000000..d3533ef3398 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/config.gpr @@ -0,0 +1,88 @@ +abstract project Config is + for Source_Dirs use (); + + type Yes_No is ("yes", "no"); + + type Library_Type_Type is ("relocatable", "static"); + + type Mode_Type is ("distrib", "debug", "optimize", "profile"); + Mode : Mode_Type := external ("MODE", "debug"); + + Coverage : Yes_No := External ("COVERAGE", "no"); + Processors := External ("PROCESSORS", "1"); + + package Builder is + case Mode is + when "debug" => + for Default_Switches ("Ada") use ("-g", "-j" & Processors); + when others => + for Default_Switches ("Ada") use ("-g", "-O2", "-j" & Processors); + end case; + end Builder; + + package compiler is + warnings := ("-gnatwua"); + defaults := ("-gnat2012"); + case Mode is + when "distrib" => + for Default_Switches ("Ada") use defaults & ("-gnatafno", "-gnatVa", "-gnatwa"); + + when "debug" => + for Default_Switches ("Ada") use defaults & warnings + & ("-gnata", "-gnatVaMI", "-gnaty3abcefhiklmnprstxM99"); + + when "optimize" => + for Default_Switches ("Ada") use defaults & warnings + & ("-gnatn", "-gnatp", "-fdata-sections", "-ffunction-sections"); + + when "profile" => + for Default_Switches ("Ada") use defaults & warnings & ("-pg"); + end case; + + case Coverage is + when "yes" => + for Default_Switches ("ada") use Compiler'Default_Switches ("Ada") & + ("-fprofile-arcs", "-ftest-coverage"); + when others => + end case; + end compiler; + + package binder is + case Mode is + when "debug" => + for Default_Switches ("Ada") use ("-E"); + + when others => + for Default_Switches ("Ada") use ("-E"); + + end case; + end binder; + + package linker is + case Mode is + when "profile" => + for Default_Switches ("Ada") use ("-pg"); + + when "distrib" => + for Default_Switches ("Ada") use ("-s"); + + when "optimize" => + for Default_Switches ("Ada") use ("-Wl,--gc-sections"); + + when others => + null; + end case; + + case Coverage is + when "yes" => + for Default_Switches ("ada") use Linker'Default_Switches ("ada") & + ("-fprofile-arcs"); + when others => + end case; + end linker; + + package Ide is + for VCS_Kind use "git"; + end Ide; + +end Config; diff --git a/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache b/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache index f07f3006cc8..5bc6621e968 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache @@ -1,18 +1,21 @@ --- {{{appName}}} +-- {{{appName}}} -- {{{appDescription}}} -- OpenAPI spec version: 1.0.0 -- -- https://github.com/swagger-api/swagger-codegen.git -- - -- NOTE: Auto generated by the swagger code generator program. +-- NOTE: Auto generated by the swagger code generator program. with "config"; with "util"; +with "util_http"; with "asf"; +with "security"; +with "swagger"; project {{{projectName}}} is - Mains := ("{{{appName}}}-server.adb"); + Mains := ("{{{packageName}}}-{{{mainName}}}.adb"); for Main use Mains; - for Source_Dirs use ("src", "src/client", "src/server"); + for Source_Dirs use ("src", "src/model", "src/{{{packageDir}}}"); for Object_Dir use "./" & Config'Exec_Dir & "/bin"; package Binder renames Config.Binder; diff --git a/modules/swagger-codegen/src/main/resources/Ada/model-body.mustache b/modules/swagger-codegen/src/main/resources/Ada/model-body.mustache index 120de7b25cd..cec88232ad9 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/model-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/model-body.mustache @@ -5,7 +5,7 @@ package body {{package}}.Models is use Swagger.Streams; {{#orderedModels}} -{{#model}} +{{#model}}{{^isArrayModel}} procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; @@ -56,7 +56,7 @@ package body {{package}}.Models is end loop; end Deserialize; -{{/model}} +{{/isArrayModel}}{{/model}} {{/orderedModels}} end {{package}}.Models; diff --git a/modules/swagger-codegen/src/main/resources/Ada/model-spec.mustache b/modules/swagger-codegen/src/main/resources/Ada/model-spec.mustache index bed1aa4207d..d994ca2c798 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/model-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/model-spec.mustache @@ -5,11 +5,11 @@ with Swagger.Streams; with Ada.Containers.Vectors; package {{package}}.Models is -{{#orderedModels}}{{#model}} - -- ------------------------------ - -- {{title}} - -- {{description}} - -- ------------------------------ +{{#orderedModels}}{{#model}}{{^isArrayModel}} +{{#title}} -- ------------------------------ + -- {{title}}{{#description}} + -- {{#lambdaAdaComment}}{{description}}{{/lambdaAdaComment}}{{/description}} + -- ------------------------------{{/title}} type {{classname}} is record {{#vars}} @@ -37,7 +37,9 @@ package {{package}}.Models is Name : in String; Value : out {{classname}}_Vectors.Vector); -{{/model}} +{{/isArrayModel}}{{#isArrayModel}} + subtype {{classname}} is {{arrayModelType}}_Type_Vectors.Vector; +{{/isArrayModel}}{{/model}} {{/orderedModels}} end {{package}}.Models; diff --git a/modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache new file mode 100644 index 00000000000..3d9f3029d14 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache @@ -0,0 +1,14 @@ +-- {{{appName}}} +-- {{{appDescription}}} +-- ------------ EDIT NOTE ------------ +-- This file was generated with swagger-codegen. You can modify it to implement +-- the server. After you modify this file, you should add the following line +-- to the .swagger-codegen-ignore file: +-- +-- src/{{packageName}}.ads +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ +package {{packageLevel1}} is + +end {{packageLevel1}}; diff --git a/modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache new file mode 100644 index 00000000000..70c0f494f08 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache @@ -0,0 +1,14 @@ +-- {{{appName}}} +-- {{{appDescription}}} +-- ------------ EDIT NOTE ------------ +-- This file was generated with swagger-codegen. You can modify it to implement +-- the server. After you modify this file, you should add the following line +-- to the .swagger-codegen-ignore file: +-- +-- src/{{packageName}}.ads +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ +package {{packageLevel2}} is + +end {{packageLevel2}}; diff --git a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache index dc1ac8c7528..9804e347728 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache @@ -1,14 +1,30 @@ -{{>licenseInfo}} +-- {{{appName}}} +-- {{{appDescription}}} +-- ------------ EDIT NOTE ------------ +-- This file was generated with swagger-codegen. You can modify it to implement +-- the server. After you modify this file, you should add the following line +-- to the .swagger-codegen-ignore file: +-- +-- src/{{packageName}}-servers.adb +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ package body {{package}}.Servers is + {{#apiInfo}} {{#apis}} {{#operations}} {{#operation}} - -- {{summary}} - -- {{notes}} - procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; - {{/hasMore}}{{/allParams}}) is + -- {{summary}}{{#vendorExtensions.x-has-notes}} + -- {{#lambdaAdaComment}}{{unescapedNotes}}{{/lambdaAdaComment}}{{/vendorExtensions.x-has-notes}} + overriding + procedure {{operationId}} + (Server : in out Server_Type{{#hasParams}};{{/hasParams}} + {{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; + {{/hasMore}}{{/allParams}}{{#returnType}}; + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type) is begin null; end {{operationId}}; @@ -16,4 +32,5 @@ package body {{package}}.Servers is {{/operations}} {{/apis}} {{/apiInfo}} + end {{package}}.Servers; diff --git a/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache b/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache new file mode 100644 index 00000000000..654383c72f3 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache @@ -0,0 +1,22 @@ +swagger.dir=web +swagger.web.enable=false +swagger.ui.enable=true + +# Configuration for log4j +log4j.rootCategory=DEBUG,console,result +log4j.appender.console=Console +log4j.appender.console.level=DEBUG +log4j.appender.console.layout=level-message +log4j.appender.result=File +log4j.appender.result.File={{projectName}}.log + +# Logger configuration +log4j.logger.log=WARN +log4j.logger.Util.Properties=DEBUG +log4j.logger.Util.Log=WARN +log4j.logger.Util=DEBUG +log4j.logger.ASF=DEBUG +log4j.logger.Util.Serialize.Mappers=WARN +log4j.logger.Util.Serialize.IO=INFO + + diff --git a/modules/swagger-codegen/src/main/resources/Ada/server-skeleton-body.mustache b/modules/swagger-codegen/src/main/resources/Ada/server-skeleton-body.mustache new file mode 100644 index 00000000000..3af43f5c9f1 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/server-skeleton-body.mustache @@ -0,0 +1,231 @@ +{{>licenseInfo}} +with Swagger.Streams; +with Swagger.Servers.Operation; +package body {{package}}.Skeletons is + + package body Skeleton is + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + + package API_{{operationId}} is + new Swagger.Servers.Operation (Handler => {{operationId}}, + Method => Swagger.Servers.{{httpMethod}}, + URI => "{{path}}"); + + -- {{summary}} + procedure {{operationId}} + (Req : in out Swagger.Servers.Request'Class; + Reply : in out Swagger.Servers.Response'Class; + Stream : in out Swagger.Servers.Output_Stream'Class; + Context : in out Swagger.Servers.Context_Type) is + {{#hasBodyParam}} + Input : Swagger.Value_Type; + {{/hasBodyParam}} + Impl : Implementation_Type; + {{#allParams}} + {{paramName}} : {{dataType}}; + {{/allParams}} + {{#returnType}} + Result : {{returnType}}; + {{/returnType}} + begin + {{#authMethods}} + {{#scopes}} + if not Context.Has_Permission (ACL_{{ident}}.Permission) then + Context.Set_Error (403, "Permission denied"); + return; + end if; + {{/scopes}} + {{/authMethods}} + {{#queryParams}} + Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}}); + {{/queryParams}} + {{#pathParams}} + Swagger.Servers.Get_Path_Parameter (Req, {{vendorExtensions.x-path-index}}, {{paramName}}); + {{/pathParams}} + {{#hasFormParams}} + {{#formParams}} + Swagger.Servers.Get_Parameter (Req, "{{baseName}}", {{paramName}}); + {{/formParams}} + {{/hasFormParams}} + {{#hasParams}} + {{#hasBodyParam}} + Swagger.Servers.Read (Req, Input); + {{#bodyParams}}{{#vendorExtensions.x-is-model-type}} + {{package}}.Models.Deserialize (Input, "{{baseName}}", {{paramName}});{{/vendorExtensions.x-is-model-type}}{{^vendorExtensions.x-is-model-type}}{{#isFile}} + -- TODO: Serialize (Input.Stream, "{{basename}}", {{paramName}});{{/isFile}}{{^isFile}}{{^isLong}} + Deserialize (Input, "{{baseName}}", {{paramName}});{{/isLong}}{{#isLong}} + Deserialize (Input, "{{baseName}}", {{paramName}});{{/isLong}}{{/isFile}}{{/vendorExtensions.x-is-model-type}}{{/bodyParams}} + {{/hasBodyParam}} + Impl.{{operationId}} + ({{#allParams}}{{paramName}}{{#hasMore}}, + {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result{{/returnType}}, Context); + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + Impl.{{operationId}} (Result, Context); + {{/returnType}} + {{^returnType}} + Impl.{{operationId}} (Context); + {{/returnType}} + {{/hasParams}} + {{#returnType}} + Stream.Start_Document;{{#vendorExtensions.x-codegen-response.isString}} + Swagger.Streams.Serialize (Stream, "", Result);{{/vendorExtensions.x-codegen-response.isString}}{{^vendorExtensions.x-codegen-response.isString}}{{#returnTypeIsPrimitive}} + Swagger.Streams.Serialize (Stream, "", Result);{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}} + {{package}}.Models.Serialize (Stream, "", Result);{{/returnTypeIsPrimitive}}{{/vendorExtensions.x-codegen-response.isString}} + Stream.End_Document;{{/returnType}} + end {{operationId}}; +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + procedure Register (Server : in out Swagger.Servers.Application_Type'Class) is + begin +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + Swagger.Servers.Register (Server, API_{{operationId}}.Definition); +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + end Register; + + end Skeleton; + + package body Shared_Instance is + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + + -- {{summary}} + procedure {{operationId}} + (Req : in out Swagger.Servers.Request'Class; + Reply : in out Swagger.Servers.Response'Class; + Stream : in out Swagger.Servers.Output_Stream'Class; + Context : in out Swagger.Servers.Context_Type) is + {{#hasBodyParam}} + Input : Swagger.Value_Type; + {{/hasBodyParam}} + {{#allParams}} + {{paramName}} : {{dataType}}; + {{/allParams}} + {{#returnType}} + Result : {{returnType}}; + {{/returnType}} + begin + {{#queryParams}} + Swagger.Servers.Get_Query_Parameter (Req, "{{baseName}}", {{paramName}}); + {{/queryParams}} + {{#pathParams}} + Swagger.Servers.Get_Path_Parameter (Req, {{vendorExtensions.x-path-index}}, {{paramName}}); + {{/pathParams}} + {{#hasFormParams}} + {{#formParams}} + Swagger.Servers.Get_Parameter (Req, "{{baseName}}", {{paramName}}); + {{/formParams}} + {{/hasFormParams}} + {{#hasParams}} + {{#hasBodyParam}} + Swagger.Servers.Read (Req, Input); + {{#bodyParams}}{{#vendorExtensions.x-is-model-type}} + {{package}}.Models.Deserialize (Input, "{{baseName}}", {{paramName}});{{/vendorExtensions.x-is-model-type}}{{^vendorExtensions.x-is-model-type}}{{#isFile}} + -- TODO: Serialize (Input.Stream, "{{basename}}", {{paramName}});{{/isFile}}{{^isFile}}{{^isLong}} + Deserialize (Input, "{{baseName}}", {{paramName}});{{/isLong}}{{#isLong}} + Deserialize (Input, "{{baseName}}", {{paramName}});{{/isLong}}{{/isFile}}{{/vendorExtensions.x-is-model-type}}{{/bodyParams}} + {{/hasBodyParam}} + Server.{{operationId}} + ({{#allParams}}{{paramName}}{{#hasMore}}, + {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result{{/returnType}}, Context); + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + Server.{{operationId}} (Result, Context); + {{/returnType}} + {{^returnType}} + Server.{{operationId}} (Context); + {{/returnType}} + {{/hasParams}} + {{#returnType}} + Stream.Start_Document;{{#vendorExtensions.x-codegen-response.isString}} + Swagger.Streams.Serialize (Stream, "", Result);{{/vendorExtensions.x-codegen-response.isString}}{{^vendorExtensions.x-codegen-response.isString}}{{#returnTypeIsPrimitive}} + Swagger.Streams.Serialize (Stream, "", Result);{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}} + {{package}}.Models.Serialize (Stream, "", Result);{{/returnTypeIsPrimitive}}{{/vendorExtensions.x-codegen-response.isString}} + Stream.End_Document;{{/returnType}} + end {{operationId}}; + + package API_{{operationId}} is + new Swagger.Servers.Operation (Handler => {{operationId}}, + Method => Swagger.Servers.{{httpMethod}}, + URI => "{{path}}"); +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + procedure Register (Server : in out Swagger.Servers.Application_Type'Class) is + begin +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + Swagger.Servers.Register (Server, API_{{operationId}}.Definition); +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + end Register; + + protected body Server is +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + -- {{summary}} + {{#hasParams}} + procedure {{operationId}} + ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; + {{/hasMore}}{{/allParams}}{{#returnType}}; + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type) is + begin + Impl.{{operationId}} + ({{#allParams}}{{paramName}}{{#hasMore}}, + {{/hasMore}}{{/allParams}}{{#returnType}}, + Result{{/returnType}}, + Context); + end {{operationId}}; + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + procedure {{operationId}} (Result : out {{returnType}}; + Context : in out Swagger.Servers.Context_Type) is + begin + Impl.{{operationId}} (Result, Context); + end {{operationId}}; + {{/returnType}} + {{^returnType}} + procedure {{operationId}} (Context : in out Swagger.Servers.Context_Type) is + begin + Impl.{{operationId}} (Context); + end {{operationId}}; + {{/returnType}} + {{/hasParams}} + +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + end Server; + + end Shared_Instance; + +end {{package}}.Skeletons; diff --git a/modules/swagger-codegen/src/main/resources/Ada/server-skeleton-spec.mustache b/modules/swagger-codegen/src/main/resources/Ada/server-skeleton-spec.mustache new file mode 100644 index 00000000000..e14600dff7b --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/server-skeleton-spec.mustache @@ -0,0 +1,115 @@ +{{>licenseInfo}} +{{#imports}}with {{import}}; +{{/imports}} +with Swagger.Servers; +with {{package}}.Models; +with Security.Permissions; +package {{package}}.Skeletons is + use {{package}}.Models; + type Server_Type is limited interface; +{{#authMethods}}{{#scopes}} + -- {{description}} + package ACL_{{ident}} is new Security.Permissions.Definition ("{{scope}}"); +{{/scopes}}{{/authMethods}} + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + + -- {{summary}}{{#vendorExtensions.x-has-notes}} + -- {{#lambdaAdaComment}}{{unescapedNotes}}{{/lambdaAdaComment}}{{/vendorExtensions.x-has-notes}} + procedure {{operationId}} + (Server : in out Server_Type{{#hasParams}};{{/hasParams}} + {{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; + {{/hasMore}}{{/allParams}}{{#returnType}}; + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type) is abstract; +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + generic + type Implementation_Type is limited new Server_Type with private; + package Skeleton is + + procedure Register (Server : in out Swagger.Servers.Application_Type'Class); + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + + -- {{summary}} + procedure {{operationId}} + (Req : in out Swagger.Servers.Request'Class; + Reply : in out Swagger.Servers.Response'Class; + Stream : in out Swagger.Servers.Output_Stream'Class; + Context : in out Swagger.Servers.Context_Type); + +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + end Skeleton; + + generic + type Implementation_Type is limited new Server_Type with private; + package Shared_Instance is + + procedure Register (Server : in out Swagger.Servers.Application_Type'Class); + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + + -- {{summary}} + procedure {{operationId}} + (Req : in out Swagger.Servers.Request'Class; + Reply : in out Swagger.Servers.Response'Class; + Stream : in out Swagger.Servers.Output_Stream'Class; + Context : in out Swagger.Servers.Context_Type); + +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + private + protected Server is + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + -- {{summary}} + {{#hasParams}} + procedure {{operationId}} + ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; + {{/hasMore}}{{/allParams}}{{#returnType}}; + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type); + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + procedure {{operationId}} + (Result : out {{returnType}}; + Context : in out Swagger.Servers.Context_Type); + {{/returnType}} + {{^returnType}} + procedure {{operationId}} (Context : in out Swagger.Servers.Context_Type); + {{/returnType}} + {{/hasParams}} + +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + private + Impl : Implementation_Type; + end Server; + end Shared_Instance; + +end {{package}}.Skeletons; diff --git a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache index 0d887b15d36..c57f229f383 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache @@ -1,20 +1,43 @@ -{{>licenseInfo}} +-- {{{appName}}} +-- {{{appDescription}}} +-- ------------ EDIT NOTE ------------ +-- This file was generated with swagger-codegen. You can modify it to implement +-- the server. After you modify this file, you should add the following line +-- to the .swagger-codegen-ignore file: +-- +-- src/{{packageName}}-servers.ads +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ {{#imports}}with {{import}}; {{/imports}} +with Swagger.Servers; with {{package}}.Models; +with {{package}}.Skeletons; package {{package}}.Servers is + use {{package}}.Models; + type Server_Type is limited new {{package}}.Skeletons.Server_Type with null record; + {{#apiInfo}} {{#apis}} {{#operations}} {{#operation}} - -- {{summary}} - -- {{notes}} - procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; - {{/hasMore}}{{/allParams}}); - + -- {{summary}}{{#vendorExtensions.x-has-notes}} + -- {{#lambdaAdaComment}}{{unescapedNotes}}{{/lambdaAdaComment}}{{/vendorExtensions.x-has-notes}} + overriding + procedure {{operationId}} + (Server : in out Server_Type{{#hasParams}};{{/hasParams}} + {{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; + {{/hasMore}}{{/allParams}}{{#returnType}}; + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type); {{/operation}} {{/operations}} {{/apis}} {{/apiInfo}} + + package Server_Impl is + new {{package}}.Skeletons.Shared_Instance (Server_Type); + end {{package}}.Servers; diff --git a/modules/swagger-codegen/src/main/resources/Ada/server.mustache b/modules/swagger-codegen/src/main/resources/Ada/server.mustache new file mode 100644 index 00000000000..08aba9f071a --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/server.mustache @@ -0,0 +1,43 @@ +with Ada.IO_Exceptions; +with AWS.Config.Set; +with Swagger.Servers.AWS; +with Swagger.Servers.Applications; +with Util.Log.Loggers; +with Util.Properties; +with {{package}}.Servers; +procedure {{package}}.Server is + procedure Configure (Config : in out AWS.Config.Object); + + CONFIG_PATH : constant String := "{{packageConfig}}.properties"; + + procedure Configure (Config : in out AWS.Config.Object) is + begin + AWS.Config.Set.Server_Port (Config, 8080); + AWS.Config.Set.Max_Connection (Config, 8); + AWS.Config.Set.Accept_Queue_Size (Config, 512); + end Configure; + + App : aliased Swagger.Servers.Applications.Application_Type; + WS : Swagger.Servers.AWS.AWS_Container; + Log : constant Util.Log.Loggers.Logger := Util.Log.Loggers.Create ("{{package}}.Server"); + Props : Util.Properties.Manager; +begin + Props.Load_Properties (CONFIG_PATH); + Util.Log.Loggers.Initialize (Props); + + App.Configure (Props); + {{package}}.Servers.Server_Impl.Register (App); + + WS.Configure (Configure'Access); + WS.Register_Application ("{{basePathWithoutHost}}", App'Unchecked_Access); + App.Dump_Routes (Util.Log.INFO_LEVEL); + Log.Info ("Connect you browser to: http://localhost:8080{{basePathWithoutHost}}/ui/index.html"); + + WS.Start; + + delay 6000.0; + +exception + when Ada.IO_Exceptions.Name_Error => + Log.Error ("Cannot read application configuration file {0}", CONFIG_PATH); +end {{package}}.Server; diff --git a/modules/swagger-codegen/src/main/resources/Ada/swagger.mustache b/modules/swagger-codegen/src/main/resources/Ada/swagger.mustache new file mode 100644 index 00000000000..0a7a2006155 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/swagger.mustache @@ -0,0 +1 @@ +{{{swagger-json}}} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 97724a5d0e4..dbf38a7be08 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -1,4 +1,5 @@ io.swagger.codegen.languages.AdaCodegen +io.swagger.codegen.languages.AdaServerCodegen io.swagger.codegen.languages.AkkaScalaClientCodegen io.swagger.codegen.languages.AndroidClientCodegen io.swagger.codegen.languages.Apache2ConfigCodegen diff --git a/samples/client/petstore/ada/.swagger-codegen-ignore b/samples/client/petstore/ada/.swagger-codegen-ignore index c5fa491b4c5..9b9a09a8588 100644 --- a/samples/client/petstore/ada/.swagger-codegen-ignore +++ b/samples/client/petstore/ada/.swagger-codegen-ignore @@ -21,3 +21,4 @@ #docs/*.md # Then explicitly reverse the ignore rule for a single file: #!docs/README.md +petstore.gpr diff --git a/samples/client/petstore/ada/petstore.gpr b/samples/client/petstore/ada/petstore.gpr index ffcd99fd76c..8d28dc71535 100644 --- a/samples/client/petstore/ada/petstore.gpr +++ b/samples/client/petstore/ada/petstore.gpr @@ -1,15 +1,23 @@ +-- Swagger Petstore +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. +-- OpenAPI spec version: 1.0.0 +-- +-- https://github.com/swagger-api/swagger-codegen.git +-- +-- NOTE: Auto generated by the swagger code generator program. with "config"; with "util"; with "util_http"; +with "asf"; +with "security"; with "swagger"; project Petstore is Mains := ("petstore.adb"); for Main use Mains; - for Source_Dirs use ("src", "src/client"); - for Object_Dir use "./obj"; - for Exec_Dir use "./bin"; - + for Source_Dirs use ("src", "src/model", "src/client"); + for Object_Dir use "./" & Config'Exec_Dir & "/bin"; + package Binder renames Config.Binder; package Builder renames Config.Builder; package Compiler renames Config.Compiler; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-clients.adb b/samples/client/petstore/ada/src/client/samples-petstore-clients.adb index 37e99fb6575..c9fba09ea69 100644 --- a/samples/client/petstore/ada/src/client/samples-petstore-clients.adb +++ b/samples/client/petstore/ada/src/client/samples-petstore-clients.adb @@ -1,5 +1,5 @@ -- Swagger Petstore --- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. -- -- OpenAPI spec version: 1.0.0 -- Contact: apiteam@swagger.io @@ -31,7 +31,7 @@ package body Samples.Petstore.Clients is procedure Delete_Pet (Client : in out Client_Type; Pet_Id : in Swagger.Long; - Api_Key : in Swagger.UString) is + Api_Key : in Swagger.Nullable_UString) is URI : Swagger.Clients.URI_Type; begin Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, @@ -46,7 +46,7 @@ package body Samples.Petstore.Clients is -- Multiple status values can be provided with comma separated strings procedure Find_Pets_By_Status (Client : in out Client_Type; - Status : in Swagger.UString_Vectors.Vector; + Status : in Swagger.Nullable_UString_Vectors.Vector; Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector) is URI : Swagger.Clients.URI_Type; Reply : Swagger.Value_Type; @@ -64,7 +64,7 @@ package body Samples.Petstore.Clients is -- Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. procedure Find_Pets_By_Tags (Client : in out Client_Type; - Tags : in Swagger.UString_Vectors.Vector; + Tags : in Swagger.Nullable_UString_Vectors.Vector; Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector) is URI : Swagger.Clients.URI_Type; Reply : Swagger.Value_Type; @@ -117,8 +117,8 @@ package body Samples.Petstore.Clients is procedure Update_Pet_With_Form (Client : in out Client_Type; Pet_Id : in Swagger.Long; - Name : in Swagger.UString; - Status : in Swagger.UString) is + Name : in Swagger.Nullable_UString; + Status : in Swagger.Nullable_UString) is URI : Swagger.Clients.URI_Type; Req : Swagger.Clients.Request_Type; begin @@ -137,8 +137,8 @@ package body Samples.Petstore.Clients is procedure Upload_File (Client : in out Client_Type; Pet_Id : in Swagger.Long; - Additional_Metadata : in Swagger.UString; - File : in Swagger.Http_Content_Type; + Additional_Metadata : in Swagger.Nullable_UString; + File : in Swagger.File_Part_Type; Result : out Samples.Petstore.Models.ApiResponse_Type) is URI : Swagger.Clients.URI_Type; Req : Swagger.Clients.Request_Type; @@ -156,7 +156,7 @@ package body Samples.Petstore.Clients is end Upload_File; -- Delete purchase order by ID - -- For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + -- For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors procedure Delete_Order (Client : in out Client_Type; Order_Id : in Swagger.UString) is @@ -174,7 +174,7 @@ package body Samples.Petstore.Clients is -- Returns a map of status codes to quantities procedure Get_Inventory (Client : in out Client_Type; - Result : out Swagger.Integer_Map) is + Result : out Swagger.Nullable_Integer_Map) is URI : Swagger.Clients.URI_Type; Reply : Swagger.Value_Type; begin @@ -186,7 +186,7 @@ package body Samples.Petstore.Clients is end Get_Inventory; -- Find purchase order by ID - -- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + -- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions procedure Get_Order_By_Id (Client : in out Client_Type; Order_Id : in Swagger.Long; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-clients.ads b/samples/client/petstore/ada/src/client/samples-petstore-clients.ads index e10d1ab4cd1..5821707ea0c 100644 --- a/samples/client/petstore/ada/src/client/samples-petstore-clients.ads +++ b/samples/client/petstore/ada/src/client/samples-petstore-clients.ads @@ -1,5 +1,5 @@ -- Swagger Petstore --- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. -- -- OpenAPI spec version: 1.0.0 -- Contact: apiteam@swagger.io @@ -22,20 +22,20 @@ package Samples.Petstore.Clients is procedure Delete_Pet (Client : in out Client_Type; Pet_Id : in Swagger.Long; - Api_Key : in Swagger.UString); + Api_Key : in Swagger.Nullable_UString); -- Finds Pets by status -- Multiple status values can be provided with comma separated strings procedure Find_Pets_By_Status (Client : in out Client_Type; - Status : in Swagger.UString_Vectors.Vector; + Status : in Swagger.Nullable_UString_Vectors.Vector; Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector); -- Finds Pets by tags -- Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. procedure Find_Pets_By_Tags (Client : in out Client_Type; - Tags : in Swagger.UString_Vectors.Vector; + Tags : in Swagger.Nullable_UString_Vectors.Vector; Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector); -- Find pet by ID @@ -54,19 +54,19 @@ package Samples.Petstore.Clients is procedure Update_Pet_With_Form (Client : in out Client_Type; Pet_Id : in Swagger.Long; - Name : in Swagger.UString; - Status : in Swagger.UString); + Name : in Swagger.Nullable_UString; + Status : in Swagger.Nullable_UString); -- uploads an image procedure Upload_File (Client : in out Client_Type; Pet_Id : in Swagger.Long; - Additional_Metadata : in Swagger.UString; - File : in Swagger.Http_Content_Type; + Additional_Metadata : in Swagger.Nullable_UString; + File : in Swagger.File_Part_Type; Result : out Samples.Petstore.Models.ApiResponse_Type); -- Delete purchase order by ID - -- For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + -- For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors procedure Delete_Order (Client : in out Client_Type; Order_Id : in Swagger.UString); @@ -75,10 +75,10 @@ package Samples.Petstore.Clients is -- Returns a map of status codes to quantities procedure Get_Inventory (Client : in out Client_Type; - Result : out Swagger.Integer_Map); + Result : out Swagger.Nullable_Integer_Map); -- Find purchase order by ID - -- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + -- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions procedure Get_Order_By_Id (Client : in out Client_Type; Order_Id : in Swagger.Long; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-models.adb b/samples/client/petstore/ada/src/model/samples-petstore-models.adb similarity index 99% rename from samples/client/petstore/ada/src/client/samples-petstore-models.adb rename to samples/client/petstore/ada/src/model/samples-petstore-models.adb index 2c2cf97126d..542b67a2fd9 100644 --- a/samples/client/petstore/ada/src/client/samples-petstore-models.adb +++ b/samples/client/petstore/ada/src/model/samples-petstore-models.adb @@ -1,5 +1,5 @@ -- Swagger Petstore --- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. -- -- OpenAPI spec version: 1.0.0 -- Contact: apiteam@swagger.io @@ -13,6 +13,7 @@ package body Samples.Petstore.Models is use Swagger.Streams; + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; Value : in ApiResponse_Type) is @@ -61,6 +62,8 @@ package body Samples.Petstore.Models is end Deserialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; Value : in Category_Type) is @@ -107,6 +110,8 @@ package body Samples.Petstore.Models is end Deserialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; Value : in Tag_Type) is @@ -153,6 +158,8 @@ package body Samples.Petstore.Models is end Deserialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; Value : in User_Type) is @@ -211,6 +218,8 @@ package body Samples.Petstore.Models is end Deserialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; Value : in Order_Type) is @@ -265,6 +274,8 @@ package body Samples.Petstore.Models is end Deserialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; Name : in String; Value : in Pet_Type) is @@ -319,4 +330,5 @@ package body Samples.Petstore.Models is end Deserialize; + end Samples.Petstore.Models; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-models.ads b/samples/client/petstore/ada/src/model/samples-petstore-models.ads similarity index 86% rename from samples/client/petstore/ada/src/client/samples-petstore-models.ads rename to samples/client/petstore/ada/src/model/samples-petstore-models.ads index 81152ad52cc..9a5759d85e4 100644 --- a/samples/client/petstore/ada/src/client/samples-petstore-models.ads +++ b/samples/client/petstore/ada/src/model/samples-petstore-models.ads @@ -1,5 +1,5 @@ -- Swagger Petstore --- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters. +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. -- -- OpenAPI spec version: 1.0.0 -- Contact: apiteam@swagger.io @@ -18,9 +18,9 @@ package Samples.Petstore.Models is -- ------------------------------ type ApiResponse_Type is record - Code : Integer; - P_Type : Swagger.UString; - Message : Swagger.UString; + Code : Swagger.Nullable_Integer; + P_Type : Swagger.Nullable_UString; + Message : Swagger.Nullable_UString; end record; package ApiResponse_Type_Vectors is @@ -44,14 +44,15 @@ package Samples.Petstore.Models is Value : out ApiResponse_Type_Vectors.Vector); + -- ------------------------------ -- Pet category -- A category for a pet -- ------------------------------ type Category_Type is record - Id : Swagger.Long; - Name : Swagger.UString; + Id : Swagger.Nullable_Long; + Name : Swagger.Nullable_UString; end record; package Category_Type_Vectors is @@ -75,14 +76,15 @@ package Samples.Petstore.Models is Value : out Category_Type_Vectors.Vector); + -- ------------------------------ -- Pet Tag -- A tag for a pet -- ------------------------------ type Tag_Type is record - Id : Swagger.Long; - Name : Swagger.UString; + Id : Swagger.Nullable_Long; + Name : Swagger.Nullable_UString; end record; package Tag_Type_Vectors is @@ -106,20 +108,21 @@ package Samples.Petstore.Models is Value : out Tag_Type_Vectors.Vector); + -- ------------------------------ -- a User -- A User who is purchasing from the pet store -- ------------------------------ type User_Type is record - Id : Swagger.Long; - Username : Swagger.UString; - First_Name : Swagger.UString; - Last_Name : Swagger.UString; - Email : Swagger.UString; - Password : Swagger.UString; - Phone : Swagger.UString; - User_Status : Integer; + Id : Swagger.Nullable_Long; + Username : Swagger.Nullable_UString; + First_Name : Swagger.Nullable_UString; + Last_Name : Swagger.Nullable_UString; + Email : Swagger.Nullable_UString; + Password : Swagger.Nullable_UString; + Phone : Swagger.Nullable_UString; + User_Status : Swagger.Nullable_Integer; end record; package User_Type_Vectors is @@ -143,18 +146,19 @@ package Samples.Petstore.Models is Value : out User_Type_Vectors.Vector); + -- ------------------------------ -- Pet Order -- An order for a pets from the pet store -- ------------------------------ type Order_Type is record - Id : Swagger.Long; - Pet_Id : Swagger.Long; - Quantity : Integer; - Ship_Date : Swagger.Datetime; - Status : Swagger.UString; - Complete : Boolean; + Id : Swagger.Nullable_Long; + Pet_Id : Swagger.Nullable_Long; + Quantity : Swagger.Nullable_Integer; + Ship_Date : Swagger.Nullable_Date; + Status : Swagger.Nullable_UString; + Complete : Swagger.Nullable_Boolean; end record; package Order_Type_Vectors is @@ -178,18 +182,19 @@ package Samples.Petstore.Models is Value : out Order_Type_Vectors.Vector); + -- ------------------------------ -- a Pet -- A pet for sale in the pet store -- ------------------------------ type Pet_Type is record - Id : Swagger.Long; + Id : Swagger.Nullable_Long; Category : Samples.Petstore.Models.Category_Type; Name : Swagger.UString; - Photo_Urls : Swagger.UString_Vectors.Vector; + Photo_Urls : Swagger.Nullable_UString_Vectors.Vector; Tags : Samples.Petstore.Models.Tag_Type_Vectors.Vector; - Status : Swagger.UString; + Status : Swagger.Nullable_UString; end record; package Pet_Type_Vectors is @@ -213,4 +218,5 @@ package Samples.Petstore.Models is Value : out Pet_Type_Vectors.Vector); + end Samples.Petstore.Models; diff --git a/samples/client/petstore/ada/src/petstore.adb b/samples/client/petstore/ada/src/petstore.adb index b14200f0001..9c1db2490ad 100644 --- a/samples/client/petstore/ada/src/petstore.adb +++ b/samples/client/petstore/ada/src/petstore.adb @@ -5,10 +5,12 @@ with Util.Http.Clients.Curl; with Ada.Text_IO; with Ada.Command_Line; with Ada.Calendar.Formatting; +with Ada.Strings.Unbounded; with Ada.Exceptions; procedure Test is use Ada.Text_IO; + use type Ada.Strings.Unbounded.Unbounded_String; procedure Usage; procedure Print_Pet (Pet : in Samples.Petstore.Models.Pet_Type); @@ -48,14 +50,14 @@ procedure Test is procedure Print_Pet (Pet : in Samples.Petstore.Models.Pet_Type) is Need_Indent : Boolean := False; begin - Put_Line ("Id : " & Swagger.Long'Image (Pet.Id)); + Put_Line ("Id : " & Swagger.Long'Image (Pet.Id.Value)); Put_Line ("Name : " & Swagger.To_String (Pet.Name)); - Put_Line ("Status : " & Swagger.To_String (Pet.Status)); + Put_Line ("Status : " & Swagger.To_String (Pet.Status.Value)); if not Pet.Tags.Is_Empty then Put ("Tags : "); for Tag of Pet.Tags loop Put_Line ((if Need_Indent then " " else "") - & Swagger.To_String (Tag.Name)); + & Swagger.To_String (Tag.Name.Value)); Need_Indent := True; end loop; end if; @@ -63,7 +65,7 @@ procedure Test is Need_Indent := False; Put ("URLs : "); for Url of Pet.Photo_Urls loop - Put_Line ((if Need_Indent then " " else "") & Url); + Put_Line ((if Need_Indent then " " else "") & Swagger.To_String (Url.Value)); Need_Indent := True; end loop; end if; @@ -71,12 +73,12 @@ procedure Test is procedure Print_Order (Order : in Samples.Petstore.Models.Order_Type) is begin - Put_Line ("Id : " & Swagger.Long'Image (Order.Id)); - Put_Line ("Pet id : " & Swagger.Long'Image (Order.Pet_Id)); - Put_Line ("Quantity : " & Integer'Image (Order.Quantity)); - Put_Line ("Status : " & Swagger.To_String (Order.Status)); - Put_Line ("Ship date : " & Ada.Calendar.Formatting.Image (Order.Ship_Date)); - Put_Line ("Complete : " & Boolean'Image (Order.Complete)); + Put_Line ("Id : " & Swagger.Long'Image (Order.Id.Value)); + Put_Line ("Pet id : " & Swagger.Long'Image (Order.Pet_Id.Value)); + Put_Line ("Quantity : " & Integer'Image (Order.Quantity.Value)); + Put_Line ("Status : " & Swagger.To_String (Order.Status.Value)); + Put_Line ("Ship date : " & Ada.Calendar.Formatting.Image (Order.Ship_Date.Value)); + Put_Line ("Complete : " & Boolean'Image (Order.Complete.Value)); end Print_Order; procedure Get_User (C : in out Samples.Petstore.Clients.Client_Type) is @@ -85,13 +87,13 @@ procedure Test is begin for I in Arg .. Arg_Count loop C.Get_User_By_Name (Swagger.To_UString (Ada.Command_Line.Argument (I)), User); - Put_Line ("Id : " & Swagger.Long'Image (User.Id)); - Put_Line ("Username : " & Swagger.To_String (User.Username)); - Put_Line ("Firstname: " & Swagger.To_String (User.First_Name)); - Put_Line ("Lastname : " & Swagger.To_String (User.Last_Name)); - Put_Line ("Email : " & Swagger.To_String (User.Email)); - Put_Line ("Password : " & Swagger.To_String (User.Password)); - Put_Line ("Phone : " & Swagger.To_String (User.Phone)); + Put_Line ("Id : " & Swagger.Long'Image (User.Id.Value)); + Put_Line ("Username : " & Swagger.To_String (User.Username.Value)); + Put_Line ("Firstname: " & Swagger.To_String (User.First_Name.Value)); + Put_Line ("Lastname : " & Swagger.To_String (User.Last_Name.Value)); + Put_Line ("Email : " & Swagger.To_String (User.Email.Value)); + Put_Line ("Password : " & Swagger.To_String (User.Password.Value)); + Put_Line ("Phone : " & Swagger.To_String (User.Phone.Value)); end loop; end Get_User; @@ -128,10 +130,10 @@ procedure Test is begin for I in Arg .. Arg_Count loop declare - Status : Swagger.UString_Vectors.Vector; + Status : Swagger.Nullable_UString_Vectors.Vector; P : constant String := Ada.Command_Line.Argument (I); begin - Status.Append (P); + Status.Append ((Is_Null => False, Value => Swagger.To_UString (P))); C.Find_Pets_By_Status (Status, Pets); for Pet of Pets loop Print_Pet (Pet); @@ -141,17 +143,17 @@ procedure Test is end List_Pet; procedure List_Inventory (C : in out Samples.Petstore.Clients.Client_Type) is - List : Swagger.Integer_Map; - Iter : Swagger.Integer_Maps.Cursor; + List : Swagger.Nullable_Integer_Map; + Iter : Swagger.Nullable_Integer_Maps.Cursor; begin C.Get_Inventory (List); Ada.Text_IO.Put_Line ("Inventory size " & Natural'Image (Natural (List.Length))); Iter := List.First; - while Swagger.Integer_Maps.Has_Element (Iter) loop - Put (Swagger.Integer_Maps.Key (Iter)); + while Swagger.Nullable_Integer_Maps.Has_Element (Iter) loop + Put (Swagger.Nullable_Integer_Maps.Key (Iter)); Set_Col (70); - Put_Line (Natural'Image (Swagger.Integer_Maps.Element (Iter))); - Swagger.Integer_Maps.Next (Iter); + Put_Line (Natural'Image (Swagger.Nullable_Integer_Maps.Element (Iter).Value)); + Swagger.Nullable_Integer_Maps.Next (Iter); end loop; end List_Inventory; @@ -174,11 +176,14 @@ procedure Test is Usage; return; end if; - Pet.Id := Swagger.Long'Value (Ada.Command_Line.Argument (Arg)); + Pet.Id := (Is_Null => False, Value => Swagger.Long'Value (Ada.Command_Line.Argument (Arg))); Pet.Name := Swagger.To_UString (Ada.Command_Line.Argument (Arg + 1)); - Pet.Status := Swagger.To_UString (Ada.Command_Line.Argument (Arg + 2)); - Pet.Category.Id := Swagger.Long'Value (Ada.Command_Line.Argument (Arg + 3)); - Pet.Category.Name := Swagger.To_UString (Ada.Command_Line.Argument (Arg + 4)); + Pet.Status := (Is_Null => False, + Value => Swagger.To_UString (Ada.Command_Line.Argument (Arg + 2))); + Pet.Category.Id := (Is_Null => False, + Value => Swagger.Long'Value (Ada.Command_Line.Argument (Arg + 3))); + Pet.Category.Name := (Is_Null => False, + Value => Swagger.To_UString (Ada.Command_Line.Argument (Arg + 4))); C.Add_Pet (Pet); end Add_Pet; @@ -201,7 +206,8 @@ procedure Test is begin Arg := Arg + 1; for I in Arg .. Arg_Count loop - C.Delete_Pet (Swagger.Long'Value (Ada.Command_Line.Argument (I)), Key); + C.Delete_Pet (Swagger.Long'Value (Ada.Command_Line.Argument (I)), + (Is_Null => False, Value => Key)); end loop; end Delete_Pet; diff --git a/samples/client/petstore/ada/src/samples-petstore.ads b/samples/client/petstore/ada/src/samples-petstore.ads index c5292a19abf..18194660470 100644 --- a/samples/client/petstore/ada/src/samples-petstore.ads +++ b/samples/client/petstore/ada/src/samples-petstore.ads @@ -1,2 +1,14 @@ +-- Swagger Petstore +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. +-- ------------ EDIT NOTE ------------ +-- This file was generated with swagger-codegen. You can modify it to implement +-- the server. After you modify this file, you should add the following line +-- to the .swagger-codegen-ignore file: +-- +-- src/samples-petstore.ads +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ package Samples.Petstore is -end Samples.Petstore; \ No newline at end of file + +end Samples.Petstore; diff --git a/samples/client/petstore/ada/src/samples.ads b/samples/client/petstore/ada/src/samples.ads index af66cc10aa8..ff6bb421800 100644 --- a/samples/client/petstore/ada/src/samples.ads +++ b/samples/client/petstore/ada/src/samples.ads @@ -1,2 +1,14 @@ +-- Swagger Petstore +-- This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special_key` to test the authorization filters. +-- ------------ EDIT NOTE ------------ +-- This file was generated with swagger-codegen. You can modify it to implement +-- the server. After you modify this file, you should add the following line +-- to the .swagger-codegen-ignore file: +-- +-- src/samples-petstore.ads +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ package Samples is -end Samples; \ No newline at end of file + +end Samples;