[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
This commit is contained in:
Stephane Carrez
2018-01-07 11:44:20 +01:00
committed by William Cheng
parent 743bc650ab
commit 362625bfa9
30 changed files with 1498 additions and 419 deletions

View File

@@ -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<Map<String, Object>> orderedModels;
protected Map<String, List<String>> modelDepends;
protected Map<String, String> nullableTypeMapping;
protected HashMap<String, String> operationsScopes;
protected int scopeIndex = 0;
public AbstractAdaCodegen() {
super();
@@ -90,6 +103,56 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
"with",
"xor")
);
typeMapping = new HashMap<String, String>();
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<String, String>();
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<String, List<String>>();
orderedModels = new ArrayList<Map<String, Object>>();
operationsScopes = new HashMap<String, String>();
super.importMapping = new HashMap<String, String>();
// CLI options
addOption(CodegenConstants.PROJECT_NAME, "GNAT project name",
this.projectName);
modelNameSuffix = "_Type";
embeddedTemplateDir = templateDir = "Ada";
languageSpecificPrimitives = new HashSet<String>(
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 @@ abstract public class AbstractAdaCodegen extends DefaultCodegen implements Codeg
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<Map<String, String>> types) {
int count = 0;
if (types != null) {
for (Map<String, String> 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<String, Model> 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<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) 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<String, Object> postProcessModels(Map<String, Object> objs) {
// Collect the model dependencies.
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
for (Map<String, Object> model : models) {
Object v = model.get("model");
if (v instanceof CodegenModel) {
CodegenModel m = (CodegenModel) v;
List<String> d = new ArrayList<String>();
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<String, List<String>> deps = modelDepends;
Collections.sort(orderedModels, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> lhs, Map<String, Object> rhs) {
Object v = lhs.get("model");
String lhsName = ((CodegenModel) v).name;
v = rhs.get("model");
String rhsName = ((CodegenModel) v).name;
List<String> lhsList = deps.get(lhsName);
List<String> 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<String, Object> 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<String, Object> postProcessSupportingFileData(Map<String, Object> 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<CodegenSecurity> authMethods = (List<CodegenSecurity>) 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<CodegenSecurity> authMethods) {
if (authMethods != null) {
for (CodegenSecurity authMethod : authMethods) {
if (authMethod.scopes != null) {
for (Map<String, Object> 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);
}
}
}
}

View File

@@ -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<Map<String, Object>> orderedModels;
protected Map<String, List<String>> modelDepends;
public AdaCodegen() {
super();
modelNameSuffix = "_Type";
orderedModels = new ArrayList<Map<String, Object>>();
modelDepends = new HashMap<String, List<String>>();
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<String>(
Arrays.asList("integer", "boolean", "Integer", "Character", "Boolean", "long", "float", "double", "int32_t", "int64_t"));
typeMapping = new HashMap<String, String>();
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<String, String>();
}
@Override
@@ -70,36 +29,22 @@ public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig {
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,13 +53,47 @@ public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig {
// 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);
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("client.mustache", null,
"src" + File.separator + toFilename(pkgName) + "-client.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
@@ -126,237 +105,4 @@ public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig {
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<Map<String, String>> types) {
int count = 0;
if (types != null) {
for (Map<String, String> 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<String, Model> 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<String, Object> postProcessOperations(Map<String, Object> objs) {
Map<String, Object> operations = (Map<String, Object>) objs.get("operations");
List<CodegenOperation> operationList = (List<CodegenOperation>) 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<String, Object> postProcessModels(Map<String, Object> objs) {
// Collect the model dependencies.
List<Map<String, Object>> models = (List<Map<String, Object>>) objs.get("models");
for (Map<String, Object> model : models) {
Object v = model.get("model");
if (v instanceof CodegenModel) {
CodegenModel m = (CodegenModel) v;
List<String> d = new ArrayList<String>();
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<String, List<String>> deps = modelDepends;
Collections.sort(orderedModels, new Comparator<Map<String, Object>>() {
@Override
public int compare(Map<String, Object> lhs, Map<String, Object> rhs) {
Object v = lhs.get("model");
String lhsName = ((CodegenModel) v).name;
v = rhs.get("model");
String rhsName = ((CodegenModel) v).name;
List<String> lhsList = deps.get(lhsName);
List<String> 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<String, Object> 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<String, Object> postProcessSupportingFileData(Map<String, Object> objs) {
objs.put("orderedModels", orderedModels);
return super.postProcessSupportingFileData(objs);
}
}

View File

@@ -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);
}
}

View File

@@ -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}}

View File

@@ -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}}

View File

@@ -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}};

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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}};

View File

@@ -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}};

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -0,0 +1 @@
{{{swagger-json}}}

View File

@@ -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

View File

@@ -21,3 +21,4 @@
#docs/*.md
# Then explicitly reverse the ignore rule for a single file:
#!docs/README.md
petstore.gpr

View File

@@ -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;

View File

@@ -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 &lt; 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 &lt;&#x3D; 5 or &gt; 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;

View File

@@ -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 &lt; 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 &lt;&#x3D; 5 or &gt; 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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;
end Samples.Petstore;

View File

@@ -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;
end Samples;