From 53fd17e18aceea078d7f4aef47b3ec9d01f93371 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 7 Oct 2017 17:49:44 +0200 Subject: [PATCH 01/34] 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 --- bin/ada-petstore.sh | 35 ++ .../petstore/ada/.swagger-codegen-ignore | 23 ++ .../petstore/ada/.swagger-codegen/VERSION | 1 + samples/client/petstore/ada/config.gpr | 88 +++++ samples/client/petstore/ada/petstore.gpr | 18 + .../src/client/samples-petstore-clients.adb | 355 ++++++++++++++++++ .../src/client/samples-petstore-clients.ads | 139 +++++++ .../src/client/samples-petstore-models.adb | 322 ++++++++++++++++ .../src/client/samples-petstore-models.ads | 216 +++++++++++ samples/client/petstore/ada/src/petstore.adb | 268 +++++++++++++ .../petstore/ada/src/samples-petstore.ads | 2 + samples/client/petstore/ada/src/samples.ads | 2 + 12 files changed, 1469 insertions(+) create mode 100755 bin/ada-petstore.sh create mode 100644 samples/client/petstore/ada/.swagger-codegen-ignore create mode 100644 samples/client/petstore/ada/.swagger-codegen/VERSION create mode 100644 samples/client/petstore/ada/config.gpr create mode 100644 samples/client/petstore/ada/petstore.gpr create mode 100644 samples/client/petstore/ada/src/client/samples-petstore-clients.adb create mode 100644 samples/client/petstore/ada/src/client/samples-petstore-clients.ads create mode 100644 samples/client/petstore/ada/src/client/samples-petstore-models.adb create mode 100644 samples/client/petstore/ada/src/client/samples-petstore-models.ads create mode 100644 samples/client/petstore/ada/src/petstore.adb create mode 100644 samples/client/petstore/ada/src/samples-petstore.ads create mode 100644 samples/client/petstore/ada/src/samples.ads diff --git a/bin/ada-petstore.sh b/bin/ada-petstore.sh new file mode 100755 index 00000000000..d46e5013378 --- /dev/null +++ b/bin/ada-petstore.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash + +SCRIPT="$0" + +while [ -h "$SCRIPT" ] ; do + ls=`ls -ld "$SCRIPT"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + SCRIPT="$link" + else + SCRIPT=`dirname "$SCRIPT"`/"$link" + fi +done + +if [ ! -d "${APP_DIR}" ]; then + APP_DIR=`dirname "$SCRIPT"`/.. + APP_DIR=`cd "${APP_DIR}"; pwd` +fi + +executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar" + +if [ ! -f "$executable" ] +then + mvn clean package +fi + +# if you've executed sbt assembly previously it will use that instead. +export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" +model="modules/swagger-codegen/src/test/resources/2_0/petstore.yaml" +ags="$@ generate --template-dir modules/swagger-codegen/src/main/resources/Ada -l ada" +ags="$ags -i $model -t modules/swagger-codegen/src/main/resources/Ada -o samples/client/petstore/ada" +ags="$ags -DprojectName=Petstore --model-package Samples.Petstore" + +java $JAVA_OPTS -jar $executable $ags +rm -rf samples/client/petstore/ada/src/server diff --git a/samples/client/petstore/ada/.swagger-codegen-ignore b/samples/client/petstore/ada/.swagger-codegen-ignore new file mode 100644 index 00000000000..c5fa491b4c5 --- /dev/null +++ b/samples/client/petstore/ada/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/samples/client/petstore/ada/.swagger-codegen/VERSION b/samples/client/petstore/ada/.swagger-codegen/VERSION new file mode 100644 index 00000000000..f9f7450d135 --- /dev/null +++ b/samples/client/petstore/ada/.swagger-codegen/VERSION @@ -0,0 +1 @@ +2.3.0-SNAPSHOT \ No newline at end of file diff --git a/samples/client/petstore/ada/config.gpr b/samples/client/petstore/ada/config.gpr new file mode 100644 index 00000000000..d3533ef3398 --- /dev/null +++ b/samples/client/petstore/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/samples/client/petstore/ada/petstore.gpr b/samples/client/petstore/ada/petstore.gpr new file mode 100644 index 00000000000..ffcd99fd76c --- /dev/null +++ b/samples/client/petstore/ada/petstore.gpr @@ -0,0 +1,18 @@ +with "config"; +with "util"; +with "util_http"; +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"; + + package Binder renames Config.Binder; + package Builder renames Config.Builder; + package Compiler renames Config.Compiler; + package Linker renames Config.Linker; + +end Petstore; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-clients.adb b/samples/client/petstore/ada/src/client/samples-petstore-clients.adb new file mode 100644 index 00000000000..37e99fb6575 --- /dev/null +++ b/samples/client/petstore/ada/src/client/samples-petstore-clients.adb @@ -0,0 +1,355 @@ +-- 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 +-- Contact: apiteam@swagger.io +-- +-- NOTE: This package is auto generated by the swagger code generator 2.3.0-SNAPSHOT. +-- https://github.com/swagger-api/swagger-codegen.git +-- Do not edit the class manually. +with Swagger.Streams; +package body Samples.Petstore.Clients is + + -- Add a new pet to the store + procedure Add_Pet + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.Pet_Type) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (Swagger.Clients.APPLICATION_JSON, + Swagger.Clients.APPLICATION_XML)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/pet"); + Client.Call (Swagger.Clients.POST, URI, Req); + end Add_Pet; + + -- Deletes a pet + procedure Delete_Pet + (Client : in out Client_Type; + Pet_Id : in Swagger.Long; + Api_Key : in Swagger.UString) is + URI : Swagger.Clients.URI_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/pet/{petId}"); + URI.Set_Path_Param ("petId", Swagger.To_String (Pet_Id)); + Client.Call (Swagger.Clients.DELETE, URI); + end Delete_Pet; + + -- 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; + Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Add_Param ("status", Status); + URI.Set_Path ("/pet/findByStatus"); + Client.Call (Swagger.Clients.GET, URI, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + end Find_Pets_By_Status; + + -- 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; + Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Add_Param ("tags", Tags); + URI.Set_Path ("/pet/findByTags"); + Client.Call (Swagger.Clients.GET, URI, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + end Find_Pets_By_Tags; + + -- Find pet by ID + -- Returns a single pet + procedure Get_Pet_By_Id + (Client : in out Client_Type; + Pet_Id : in Swagger.Long; + Result : out Samples.Petstore.Models.Pet_Type) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/pet/{petId}"); + URI.Set_Path_Param ("petId", Swagger.To_String (Pet_Id)); + Client.Call (Swagger.Clients.GET, URI, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + end Get_Pet_By_Id; + + -- Update an existing pet + procedure Update_Pet + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.Pet_Type) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (Swagger.Clients.APPLICATION_JSON, + Swagger.Clients.APPLICATION_XML)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/pet"); + Client.Call (Swagger.Clients.PUT, URI, Req); + end Update_Pet; + + -- Updates a pet in the store with form data + procedure Update_Pet_With_Form + (Client : in out Client_Type; + Pet_Id : in Swagger.Long; + Name : in Swagger.UString; + Status : in Swagger.UString) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_FORM)); + Req.Stream.Write_Entity ("name", Name); + Req.Stream.Write_Entity ("status", Status); + + URI.Set_Path ("/pet/{petId}"); + URI.Set_Path_Param ("petId", Swagger.To_String (Pet_Id)); + Client.Call (Swagger.Clients.POST, URI); + end Update_Pet_With_Form; + + -- 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; + Result : out Samples.Petstore.Models.ApiResponse_Type) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((1 => Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_FORM)); + Req.Stream.Write_Entity ("additionalMetadata", Additional_Metadata); + Req.Stream.Write_Entity ("file", File); + + URI.Set_Path ("/pet/{petId}/uploadImage"); + URI.Set_Path_Param ("petId", Swagger.To_String (Pet_Id)); + Client.Call (Swagger.Clients.POST, URI, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + 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 + procedure Delete_Order + (Client : in out Client_Type; + Order_Id : in Swagger.UString) is + URI : Swagger.Clients.URI_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/store/order/{orderId}"); + URI.Set_Path_Param ("orderId", Order_Id); + Client.Call (Swagger.Clients.DELETE, URI); + end Delete_Order; + + -- Returns pet inventories by status + -- Returns a map of status codes to quantities + procedure Get_Inventory + (Client : in out Client_Type; + Result : out Swagger.Integer_Map) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((1 => Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/store/inventory"); + Client.Call (Swagger.Clients.GET, URI, Reply); + Swagger.Streams.Deserialize (Reply, "", Result); + end Get_Inventory; + + -- Find purchase order by ID + -- 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; + Result : out Samples.Petstore.Models.Order_Type) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/store/order/{orderId}"); + URI.Set_Path_Param ("orderId", Swagger.To_String (Order_Id)); + Client.Call (Swagger.Clients.GET, URI, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + end Get_Order_By_Id; + + -- Place an order for a pet + procedure Place_Order + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.Order_Type; + Result : out Samples.Petstore.Models.Order_Type) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_JSON)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/store/order"); + Client.Call (Swagger.Clients.POST, URI, Req, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + end Place_Order; + + -- Create user + -- This can only be done by the logged in user. + procedure Create_User + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.User_Type) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_JSON)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/user"); + Client.Call (Swagger.Clients.POST, URI, Req); + end Create_User; + + -- Creates list of users with given input array + procedure Create_Users_With_Array_Input + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.User_Type_Vectors.Vector) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_JSON)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/user/createWithArray"); + Client.Call (Swagger.Clients.POST, URI, Req); + end Create_Users_With_Array_Input; + + -- Creates list of users with given input array + procedure Create_Users_With_List_Input + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.User_Type_Vectors.Vector) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_JSON)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/user/createWithList"); + Client.Call (Swagger.Clients.POST, URI, Req); + end Create_Users_With_List_Input; + + -- Delete user + -- This can only be done by the logged in user. + procedure Delete_User + (Client : in out Client_Type; + Username : in Swagger.UString) is + URI : Swagger.Clients.URI_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/user/{username}"); + URI.Set_Path_Param ("username", Username); + Client.Call (Swagger.Clients.DELETE, URI); + end Delete_User; + + -- Get user by user name + procedure Get_User_By_Name + (Client : in out Client_Type; + Username : in Swagger.UString; + Result : out Samples.Petstore.Models.User_Type) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/user/{username}"); + URI.Set_Path_Param ("username", Username); + Client.Call (Swagger.Clients.GET, URI, Reply); + Samples.Petstore.Models.Deserialize (Reply, "", Result); + end Get_User_By_Name; + + -- Logs user into the system + procedure Login_User + (Client : in out Client_Type; + Username : in Swagger.UString; + Password : in Swagger.UString; + Result : out Swagger.UString) is + URI : Swagger.Clients.URI_Type; + Reply : Swagger.Value_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Add_Param ("username", Username); + URI.Add_Param ("password", Password); + URI.Set_Path ("/user/login"); + Client.Call (Swagger.Clients.GET, URI, Reply); + Swagger.Streams.Deserialize (Reply, "", Result); + end Login_User; + + -- Logs out current logged in user session + procedure Logout_User + (Client : in out Client_Type) is + URI : Swagger.Clients.URI_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + + URI.Set_Path ("/user/logout"); + Client.Call (Swagger.Clients.GET, URI); + end Logout_User; + + -- Updated user + -- This can only be done by the logged in user. + procedure Update_User + (Client : in out Client_Type; + Username : in Swagger.UString; + P_Body : in Samples.Petstore.Models.User_Type) is + URI : Swagger.Clients.URI_Type; + Req : Swagger.Clients.Request_Type; + begin + Client.Set_Accept ((Swagger.Clients.APPLICATION_XML, + Swagger.Clients.APPLICATION_JSON)); + Client.Initialize (Req, (1 => Swagger.Clients.APPLICATION_JSON)); + Samples.Petstore.Models.Serialize (Req.Stream, "body", P_Body); + + URI.Set_Path ("/user/{username}"); + URI.Set_Path_Param ("username", Username); + Client.Call (Swagger.Clients.PUT, URI, Req); + end Update_User; +end Samples.Petstore.Clients; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-clients.ads b/samples/client/petstore/ada/src/client/samples-petstore-clients.ads new file mode 100644 index 00000000000..e10d1ab4cd1 --- /dev/null +++ b/samples/client/petstore/ada/src/client/samples-petstore-clients.ads @@ -0,0 +1,139 @@ +-- 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 +-- Contact: apiteam@swagger.io +-- +-- NOTE: This package is auto generated by the swagger code generator 2.3.0-SNAPSHOT. +-- https://github.com/swagger-api/swagger-codegen.git +-- Do not edit the class manually. +with Samples.Petstore.Models; +with Swagger.Clients; +package Samples.Petstore.Clients is + + type Client_Type is new Swagger.Clients.Client_Type with null record; + + -- Add a new pet to the store + procedure Add_Pet + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.Pet_Type); + + -- Deletes a pet + procedure Delete_Pet + (Client : in out Client_Type; + Pet_Id : in Swagger.Long; + Api_Key : in Swagger.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; + 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; + Result : out Samples.Petstore.Models.Pet_Type_Vectors.Vector); + + -- Find pet by ID + -- Returns a single pet + procedure Get_Pet_By_Id + (Client : in out Client_Type; + Pet_Id : in Swagger.Long; + Result : out Samples.Petstore.Models.Pet_Type); + + -- Update an existing pet + procedure Update_Pet + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.Pet_Type); + + -- Updates a pet in the store with form data + procedure Update_Pet_With_Form + (Client : in out Client_Type; + Pet_Id : in Swagger.Long; + Name : in Swagger.UString; + Status : in Swagger.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; + 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 + procedure Delete_Order + (Client : in out Client_Type; + Order_Id : in Swagger.UString); + + -- Returns pet inventories by status + -- Returns a map of status codes to quantities + procedure Get_Inventory + (Client : in out Client_Type; + Result : out Swagger.Integer_Map); + + -- Find purchase order by ID + -- 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; + Result : out Samples.Petstore.Models.Order_Type); + + -- Place an order for a pet + procedure Place_Order + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.Order_Type; + Result : out Samples.Petstore.Models.Order_Type); + + -- Create user + -- This can only be done by the logged in user. + procedure Create_User + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.User_Type); + + -- Creates list of users with given input array + procedure Create_Users_With_Array_Input + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.User_Type_Vectors.Vector); + + -- Creates list of users with given input array + procedure Create_Users_With_List_Input + (Client : in out Client_Type; + P_Body : in Samples.Petstore.Models.User_Type_Vectors.Vector); + + -- Delete user + -- This can only be done by the logged in user. + procedure Delete_User + (Client : in out Client_Type; + Username : in Swagger.UString); + + -- Get user by user name + procedure Get_User_By_Name + (Client : in out Client_Type; + Username : in Swagger.UString; + Result : out Samples.Petstore.Models.User_Type); + + -- Logs user into the system + procedure Login_User + (Client : in out Client_Type; + Username : in Swagger.UString; + Password : in Swagger.UString; + Result : out Swagger.UString); + + -- Logs out current logged in user session + procedure Logout_User + (Client : in out Client_Type); + + -- Updated user + -- This can only be done by the logged in user. + procedure Update_User + (Client : in out Client_Type; + Username : in Swagger.UString; + P_Body : in Samples.Petstore.Models.User_Type); + +end Samples.Petstore.Clients; diff --git a/samples/client/petstore/ada/src/client/samples-petstore-models.adb b/samples/client/petstore/ada/src/client/samples-petstore-models.adb new file mode 100644 index 00000000000..2c2cf97126d --- /dev/null +++ b/samples/client/petstore/ada/src/client/samples-petstore-models.adb @@ -0,0 +1,322 @@ +-- 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 +-- Contact: apiteam@swagger.io +-- +-- NOTE: This package is auto generated by the swagger code generator 2.3.0-SNAPSHOT. +-- https://github.com/swagger-api/swagger-codegen.git +-- Do not edit the class manually. + +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 + begin + Into.Start_Entity (Name); + Into.Write_Entity ("code", Value.Code); + Into.Write_Entity ("type", Value.P_Type); + Into.Write_Entity ("message", Value.Message); + Into.End_Entity (Name); + end Serialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in ApiResponse_Type_Vectors.Vector) is + begin + Into.Start_Array (Name); + for Item of Value loop + Serialize (Into, "", Item); + end loop; + Into.End_Array (Name); + end Serialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out ApiResponse_Type) is + Object : Swagger.Value_Type; + begin + Swagger.Streams.Deserialize (From, Name, Object); + Swagger.Streams.Deserialize (Object, "code", Value.Code); + Swagger.Streams.Deserialize (Object, "type", Value.P_Type); + Swagger.Streams.Deserialize (Object, "message", Value.Message); + end Deserialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out ApiResponse_Type_Vectors.Vector) is + List : Swagger.Value_Array_Type; + Item : ApiResponse_Type; + begin + Value.Clear; + Swagger.Streams.Deserialize (From, Name, List); + for Data of List loop + Deserialize (Data, "", Item); + Value.Append (Item); + end loop; + end Deserialize; + + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Category_Type) is + begin + Into.Start_Entity (Name); + Serialize (Into, "id", Value.Id); + Into.Write_Entity ("name", Value.Name); + Into.End_Entity (Name); + end Serialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Category_Type_Vectors.Vector) is + begin + Into.Start_Array (Name); + for Item of Value loop + Serialize (Into, "", Item); + end loop; + Into.End_Array (Name); + end Serialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Category_Type) is + Object : Swagger.Value_Type; + begin + Swagger.Streams.Deserialize (From, Name, Object); + Swagger.Streams.Deserialize (Object, "id", Value.Id); + Swagger.Streams.Deserialize (Object, "name", Value.Name); + end Deserialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Category_Type_Vectors.Vector) is + List : Swagger.Value_Array_Type; + Item : Category_Type; + begin + Value.Clear; + Swagger.Streams.Deserialize (From, Name, List); + for Data of List loop + Deserialize (Data, "", Item); + Value.Append (Item); + end loop; + end Deserialize; + + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Tag_Type) is + begin + Into.Start_Entity (Name); + Serialize (Into, "id", Value.Id); + Into.Write_Entity ("name", Value.Name); + Into.End_Entity (Name); + end Serialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Tag_Type_Vectors.Vector) is + begin + Into.Start_Array (Name); + for Item of Value loop + Serialize (Into, "", Item); + end loop; + Into.End_Array (Name); + end Serialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Tag_Type) is + Object : Swagger.Value_Type; + begin + Swagger.Streams.Deserialize (From, Name, Object); + Swagger.Streams.Deserialize (Object, "id", Value.Id); + Swagger.Streams.Deserialize (Object, "name", Value.Name); + end Deserialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Tag_Type_Vectors.Vector) is + List : Swagger.Value_Array_Type; + Item : Tag_Type; + begin + Value.Clear; + Swagger.Streams.Deserialize (From, Name, List); + for Data of List loop + Deserialize (Data, "", Item); + Value.Append (Item); + end loop; + end Deserialize; + + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in User_Type) is + begin + Into.Start_Entity (Name); + Serialize (Into, "id", Value.Id); + Into.Write_Entity ("username", Value.Username); + Into.Write_Entity ("firstName", Value.First_Name); + Into.Write_Entity ("lastName", Value.Last_Name); + Into.Write_Entity ("email", Value.Email); + Into.Write_Entity ("password", Value.Password); + Into.Write_Entity ("phone", Value.Phone); + Into.Write_Entity ("userStatus", Value.User_Status); + Into.End_Entity (Name); + end Serialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in User_Type_Vectors.Vector) is + begin + Into.Start_Array (Name); + for Item of Value loop + Serialize (Into, "", Item); + end loop; + Into.End_Array (Name); + end Serialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out User_Type) is + Object : Swagger.Value_Type; + begin + Swagger.Streams.Deserialize (From, Name, Object); + Swagger.Streams.Deserialize (Object, "id", Value.Id); + Swagger.Streams.Deserialize (Object, "username", Value.Username); + Swagger.Streams.Deserialize (Object, "firstName", Value.First_Name); + Swagger.Streams.Deserialize (Object, "lastName", Value.Last_Name); + Swagger.Streams.Deserialize (Object, "email", Value.Email); + Swagger.Streams.Deserialize (Object, "password", Value.Password); + Swagger.Streams.Deserialize (Object, "phone", Value.Phone); + Swagger.Streams.Deserialize (Object, "userStatus", Value.User_Status); + end Deserialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out User_Type_Vectors.Vector) is + List : Swagger.Value_Array_Type; + Item : User_Type; + begin + Value.Clear; + Swagger.Streams.Deserialize (From, Name, List); + for Data of List loop + Deserialize (Data, "", Item); + Value.Append (Item); + end loop; + end Deserialize; + + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Order_Type) is + begin + Into.Start_Entity (Name); + Serialize (Into, "id", Value.Id); + Serialize (Into, "petId", Value.Pet_Id); + Into.Write_Entity ("quantity", Value.Quantity); + Into.Write_Entity ("shipDate", Value.Ship_Date); + Into.Write_Entity ("status", Value.Status); + Into.Write_Entity ("complete", Value.Complete); + Into.End_Entity (Name); + end Serialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Order_Type_Vectors.Vector) is + begin + Into.Start_Array (Name); + for Item of Value loop + Serialize (Into, "", Item); + end loop; + Into.End_Array (Name); + end Serialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Order_Type) is + Object : Swagger.Value_Type; + begin + Swagger.Streams.Deserialize (From, Name, Object); + Swagger.Streams.Deserialize (Object, "id", Value.Id); + Swagger.Streams.Deserialize (Object, "petId", Value.Pet_Id); + Swagger.Streams.Deserialize (Object, "quantity", Value.Quantity); + Deserialize (Object, "shipDate", Value.Ship_Date); + Swagger.Streams.Deserialize (Object, "status", Value.Status); + Swagger.Streams.Deserialize (Object, "complete", Value.Complete); + end Deserialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Order_Type_Vectors.Vector) is + List : Swagger.Value_Array_Type; + Item : Order_Type; + begin + Value.Clear; + Swagger.Streams.Deserialize (From, Name, List); + for Data of List loop + Deserialize (Data, "", Item); + Value.Append (Item); + end loop; + end Deserialize; + + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Pet_Type) is + begin + Into.Start_Entity (Name); + Serialize (Into, "id", Value.Id); + Serialize (Into, "category", Value.Category); + Into.Write_Entity ("name", Value.Name); + Serialize (Into, "photoUrls", Value.Photo_Urls); + Serialize (Into, "tags", Value.Tags); + Into.Write_Entity ("status", Value.Status); + Into.End_Entity (Name); + end Serialize; + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Pet_Type_Vectors.Vector) is + begin + Into.Start_Array (Name); + for Item of Value loop + Serialize (Into, "", Item); + end loop; + Into.End_Array (Name); + end Serialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Pet_Type) is + Object : Swagger.Value_Type; + begin + Swagger.Streams.Deserialize (From, Name, Object); + Swagger.Streams.Deserialize (Object, "id", Value.Id); + Deserialize (Object, "category", Value.Category); + Swagger.Streams.Deserialize (Object, "name", Value.Name); + Swagger.Streams.Deserialize (Object, "photoUrls", Value.Photo_Urls); + Deserialize (Object, "tags", Value.Tags); + Swagger.Streams.Deserialize (Object, "status", Value.Status); + end Deserialize; + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Pet_Type_Vectors.Vector) is + List : Swagger.Value_Array_Type; + Item : Pet_Type; + begin + Value.Clear; + Swagger.Streams.Deserialize (From, Name, List); + for Data of List loop + Deserialize (Data, "", Item); + Value.Append (Item); + end loop; + 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/client/samples-petstore-models.ads new file mode 100644 index 00000000000..7bf3095598f --- /dev/null +++ b/samples/client/petstore/ada/src/client/samples-petstore-models.ads @@ -0,0 +1,216 @@ +-- 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 +-- Contact: apiteam@swagger.io +-- +-- NOTE: This package is auto generated by the swagger code generator 2.3.0-SNAPSHOT. +-- https://github.com/swagger-api/swagger-codegen.git +-- Do not edit the class manually. +with Swagger.Streams; +with Ada.Containers.Vectors; +package Samples.Petstore.Models is + + + -- ------------------------------ + -- An uploaded response + -- Describes the result of uploading an image resource + -- ------------------------------ + type ApiResponse_Type is + record + Code : Integer; + P_Type : Swagger.UString; + Message : Swagger.UString; + end record; + + package ApiResponse_Type_Vectors is + new Ada.Containers.Vectors (Index_Type => Positive, + Element_Type => ApiResponse_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in ApiResponse_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in ApiResponse_Type_Vectors.Vector); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out ApiResponse_Type); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out ApiResponse_Type_Vectors.Vector); + + + -- ------------------------------ + -- Pet catehgry + -- A category for a pet + -- ------------------------------ + type Category_Type is + record + Id : Swagger.Long; + Name : Swagger.UString; + end record; + + package Category_Type_Vectors is + new Ada.Containers.Vectors (Index_Type => Positive, + Element_Type => Category_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Category_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Category_Type_Vectors.Vector); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Category_Type); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Category_Type_Vectors.Vector); + + + -- ------------------------------ + -- Pet Tag + -- A tag for a pet + -- ------------------------------ + type Tag_Type is + record + Id : Swagger.Long; + Name : Swagger.UString; + end record; + + package Tag_Type_Vectors is + new Ada.Containers.Vectors (Index_Type => Positive, + Element_Type => Tag_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Tag_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Tag_Type_Vectors.Vector); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Tag_Type); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + 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; + end record; + + package User_Type_Vectors is + new Ada.Containers.Vectors (Index_Type => Positive, + Element_Type => User_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in User_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in User_Type_Vectors.Vector); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out User_Type); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + 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; + end record; + + package Order_Type_Vectors is + new Ada.Containers.Vectors (Index_Type => Positive, + Element_Type => Order_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Order_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Order_Type_Vectors.Vector); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Order_Type); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Order_Type_Vectors.Vector); + + + -- ------------------------------ + -- a Pet + -- A pet for sale in the pet store + -- ------------------------------ + type Pet_Type is + record + Id : Swagger.Long; + Category : Samples.Petstore.Models.Category_Type; + Name : Swagger.UString; + Photo_Urls : Swagger.UString_Vectors.Vector; + Tags : Samples.Petstore.Models.Tag_Type_Vectors.Vector; + Status : Swagger.UString; + end record; + + package Pet_Type_Vectors is + new Ada.Containers.Vectors (Index_Type => Positive, + Element_Type => Pet_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Pet_Type); + + procedure Serialize (Into : in out Swagger.Streams.Output_Stream'Class; + Name : in String; + Value : in Pet_Type_Vectors.Vector); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + Value : out Pet_Type); + + procedure Deserialize (From : in Swagger.Value_Type; + Name : in String; + 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 new file mode 100644 index 00000000000..b14200f0001 --- /dev/null +++ b/samples/client/petstore/ada/src/petstore.adb @@ -0,0 +1,268 @@ +with Samples.Petstore.Clients; +with Samples.Petstore.Models; +with Swagger; +with Util.Http.Clients.Curl; +with Ada.Text_IO; +with Ada.Command_Line; +with Ada.Calendar.Formatting; +with Ada.Exceptions; +procedure Test is + + use Ada.Text_IO; + + procedure Usage; + procedure Print_Pet (Pet : in Samples.Petstore.Models.Pet_Type); + procedure Print_Order (Order : in Samples.Petstore.Models.Order_Type); + procedure Get_User (C : in out Samples.Petstore.Clients.Client_Type); + procedure Get_Pet (C : in out Samples.Petstore.Clients.Client_Type); + procedure Get_Order (C : in out Samples.Petstore.Clients.Client_Type); + procedure List_Inventory (C : in out Samples.Petstore.Clients.Client_Type); + procedure List_Pet (C : in out Samples.Petstore.Clients.Client_Type); + procedure Delete_Pet (C : in out Samples.Petstore.Clients.Client_Type); + procedure Delete_User (C : in out Samples.Petstore.Clients.Client_Type); + procedure Delete_Order (C : in out Samples.Petstore.Clients.Client_Type); + procedure Add_Pet (C : in out Samples.Petstore.Clients.Client_Type); + procedure Login (C : in out Samples.Petstore.Clients.Client_Type; + Username : in String; + Password : in String); + + Server : constant Swagger.UString := Swagger.To_UString ("http://petstore.swagger.io/v2"); + Arg_Count : constant Natural := Ada.Command_Line.Argument_Count; + Arg : Positive := 1; + + procedure Usage is + begin + Put_Line ("Usage: petstore {list|add|rm|update} {user|order|pet} {params}..."); + Put_Line (" get pet ... Print pet given its id"); + Put_Line (" get user ... Print user given its name"); + Put_Line (" get order ... Print order given its id"); + Put_Line (" list pet ... List the pets with the given status"); + Put_Line (" list inventory List the inventory"); + Put_Line (" add pet ... Remove user with given name"); + Put_Line (" rm order ... Remove order with given id"); + Put_Line (" login Use login operation to get a session"); + end Usage; + + 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 ("Name : " & Swagger.To_String (Pet.Name)); + Put_Line ("Status : " & Swagger.To_String (Pet.Status)); + 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)); + Need_Indent := True; + end loop; + end if; + if not Pet.Photo_Urls.Is_Empty then + Need_Indent := False; + Put ("URLs : "); + for Url of Pet.Photo_Urls loop + Put_Line ((if Need_Indent then " " else "") & Url); + Need_Indent := True; + end loop; + end if; + end Print_Pet; + + 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)); + end Print_Order; + + procedure Get_User (C : in out Samples.Petstore.Clients.Client_Type) is + + User : Samples.Petstore.Models.User_Type; + 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)); + end loop; + end Get_User; + + procedure Get_Pet (C : in out Samples.Petstore.Clients.Client_Type) is + Pet : Samples.Petstore.Models.Pet_Type; + begin + C.Set_Server (Server); + for I in Arg .. Arg_Count loop + declare + P : constant String := Ada.Command_Line.Argument (I); + begin + C.Get_Pet_By_Id (Swagger.Long'Value (P), Pet); + Print_Pet (Pet); + end; + end loop; + end Get_Pet; + + procedure Get_Order (C : in out Samples.Petstore.Clients.Client_Type) is + Order : Samples.Petstore.Models.Order_Type; + begin + C.Set_Server (Server); + for I in Arg .. Arg_Count loop + declare + P : constant String := Ada.Command_Line.Argument (I); + begin + C.Get_Order_By_Id (Swagger.Long'Value (P), Order); + Print_Order (Order); + end; + end loop; + end Get_Order; + + procedure List_Pet (C : in out Samples.Petstore.Clients.Client_Type) is + Pets : Samples.Petstore.Models.Pet_Type_Vectors.Vector; + begin + for I in Arg .. Arg_Count loop + declare + Status : Swagger.UString_Vectors.Vector; + P : constant String := Ada.Command_Line.Argument (I); + begin + Status.Append (P); + C.Find_Pets_By_Status (Status, Pets); + for Pet of Pets loop + Print_Pet (Pet); + end loop; + end; + end loop; + end List_Pet; + + procedure List_Inventory (C : in out Samples.Petstore.Clients.Client_Type) is + List : Swagger.Integer_Map; + Iter : Swagger.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)); + Set_Col (70); + Put_Line (Natural'Image (Swagger.Integer_Maps.Element (Iter))); + Swagger.Integer_Maps.Next (Iter); + end loop; + end List_Inventory; + + procedure Login (C : in out Samples.Petstore.Clients.Client_Type; + Username : in String; + Password : in String) is + Session : Swagger.UString; + begin + C.Login_User (Swagger.To_UString (Username), + Swagger.To_UString (Password), + Session); + Put_Line ("New session : " & Swagger.To_String (Session)); + end Login; + + procedure Add_Pet (C : in out Samples.Petstore.Clients.Client_Type) is + Pet : Samples.Petstore.Models.Pet_Type; + begin + if Arg_Count /= 7 then + Put_Line ("Missing some arguments for add pet command"); + Usage; + return; + end if; + Pet.Id := 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)); + C.Add_Pet (Pet); + end Add_Pet; + + procedure Delete_User (C : in out Samples.Petstore.Clients.Client_Type) is + begin + for I in Arg .. Arg_Count loop + C.Delete_User (Username => Swagger.To_UString (Ada.Command_Line.Argument (I))); + end loop; + end Delete_User; + + procedure Delete_Order (C : in out Samples.Petstore.Clients.Client_Type) is + begin + for I in Arg .. Arg_Count loop + C.Delete_Order (Swagger.To_UString (Ada.Command_Line.Argument (I))); + end loop; + end Delete_Order; + + procedure Delete_Pet (C : in out Samples.Petstore.Clients.Client_Type) is + Key : constant Swagger.UString := Swagger.To_UString (Ada.Command_Line.Argument (Arg)); + begin + Arg := Arg + 1; + for I in Arg .. Arg_Count loop + C.Delete_Pet (Swagger.Long'Value (Ada.Command_Line.Argument (I)), Key); + end loop; + end Delete_Pet; + +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 : Samples.Petstore.Clients.Client_Type; + begin + C.Set_Server (Server); + Arg := Arg + 2; + if Command = "login" then + Login (C, Item, Ada.Command_Line.Argument (Arg)); + elsif Command = "get" then + if Item = "user" then + Get_User (C); + elsif Item = "pet" then + Get_Pet (C); + elsif Item = "order" then + Get_Order (C); + else + Usage; + end if; + elsif Command = "list" then + if Item = "pet" then + List_Pet (C); + elsif Item = "inventory" then + List_Inventory (C); + else + Usage; + end if; + elsif Command = "add" then + if Item = "pet" then + Add_Pet (C); + else + Usage; + end if; + elsif Command = "rm" then + if Item = "user" then + Delete_User (C); + elsif Item = "order" then + Delete_Order (C); + elsif Item = "pet" then + Delete_Pet (C); + else + Usage; + end if; + elsif Command = "update" then + Usage; + else + Usage; + end if; + + exception + when E : Constraint_Error => + Put_Line ("Constraint error raised: " & Ada.Exceptions.Exception_Message (E)); + + end; +end Test; diff --git a/samples/client/petstore/ada/src/samples-petstore.ads b/samples/client/petstore/ada/src/samples-petstore.ads new file mode 100644 index 00000000000..c5292a19abf --- /dev/null +++ b/samples/client/petstore/ada/src/samples-petstore.ads @@ -0,0 +1,2 @@ +package Samples.Petstore is +end Samples.Petstore; \ No newline at end of file diff --git a/samples/client/petstore/ada/src/samples.ads b/samples/client/petstore/ada/src/samples.ads new file mode 100644 index 00000000000..af66cc10aa8 --- /dev/null +++ b/samples/client/petstore/ada/src/samples.ads @@ -0,0 +1,2 @@ +package Samples is +end Samples; \ No newline at end of file From 35f04b4727a5555c3ff41343b95738c99787439b Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 7 Oct 2017 18:01:37 +0200 Subject: [PATCH 02/34] Add some description for the samples --- samples/client/petstore/ada/README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 samples/client/petstore/ada/README.md diff --git a/samples/client/petstore/ada/README.md b/samples/client/petstore/ada/README.md new file mode 100644 index 00000000000..7783fbe14cf --- /dev/null +++ b/samples/client/petstore/ada/README.md @@ -0,0 +1,27 @@ +# petstore-api + +This Ada client uses the Petstore API to demonstrate how to use the generator +and use the generated Ada code. The following files are generated by +[Swagger Codegen](https://github.com/swagger-api/swagger-codegen): + +* src/client/samples-petstore-models.ads +* src/client/samples-petstore-models.adb +* src/client/samples-petstore-clients.ads +* src/client/samples-petstore-clients.adb + +## Requirements. + +You must have installed the GNAT Ada compiler as well the following libraries: + +* Ada Util (https://github.com/stcarrez/ada-util) +* Swagger Ada (https://github.com/stcarrez/swagger-ada) +* AWS (http://libre.adacore.com/libre/tools/aws/) + +## Building the petstore client + +Build the petstore client by using the following command: +```sh +gprbuild -Ppetstore -p +``` + + From 07bb281d06cc755f17f951c643a7434ad893dce0 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 7 Oct 2017 18:27:19 +0200 Subject: [PATCH 03/34] Update the documentation to explain how to build, how to use the generated Ada client code --- samples/client/petstore/ada/README.md | 72 ++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/samples/client/petstore/ada/README.md b/samples/client/petstore/ada/README.md index 7783fbe14cf..1a055b7a58b 100644 --- a/samples/client/petstore/ada/README.md +++ b/samples/client/petstore/ada/README.md @@ -1,4 +1,6 @@ -# petstore-api +# Swagger Petstore Ada Client + +## Overview This Ada client uses the Petstore API to demonstrate how to use the generator and use the generated Ada code. The following files are generated by @@ -9,9 +11,15 @@ and use the generated Ada code. The following files are generated by * src/client/samples-petstore-clients.ads * src/client/samples-petstore-clients.adb +The 'Models' package contains the definition of types used by the request or response +in the API operations. It also provides operations to serialize and deserialize these +objects in JSON, XML or form-based data streams. + +The 'Clients' package contains the definition of operations provided by the Petstore API. + ## Requirements. -You must have installed the GNAT Ada compiler as well the following libraries: +To build this sample, you must have installed the GNAT Ada compiler as well the following libraries: * Ada Util (https://github.com/stcarrez/ada-util) * Swagger Ada (https://github.com/stcarrez/swagger-ada) @@ -24,4 +32,64 @@ Build the petstore client by using the following command: gprbuild -Ppetstore -p ``` +## Using the Swagger Ada code + +### Initialization + +The HTTP/REST support is provided by [Ada Util](https://github.com/stcarrez/ada-util) +and encapsulated by [Swagger Ada](https://github.com/stcarrez/swagger-ada). If you want +to use Curl, you should initialize with the following: + +``` + Util.Http.Clients.Curl.Register; +``` + +But if you want to use [AWS](http://libre.adacore.com/libre/tools/aws/), you will initialize with: + + +``` + Util.Http.Clients.Web.Register; +``` + +After the initialization is done, you will declare a client instance to access +the API operations: + +``` + C : Samples.Petstore.Clients.Client_Type; +``` + +The 'Client_Type' is the generated type that will implement the operations +described in the OpenAPI description file. +And you should initialize the server base URI you want to connect to: + +``` + C.Set_Server ("http://petstore.swagger.io/v2"); +``` + +At this stage, you can use the generated operation. + +### Calling an operation + +Let's retrieve some pet information by calling the 'Get_Pet_By_Id' operation. +This operation needs an integer as input parameter and returns a 'Pet_Type' +object that contains all the pet information. You will first declare +the pet instance as follows: + +``` + Pet : Samples.Petstore.Models.Pet_Type; +``` + +And then call the 'Get_Pet_By_Id' operation: + +``` + C.Get_Pet_By_Id (768, Pet); +``` + +At this stage, you can access information from the 'Pet' instance: + +``` + Ada.Text_IO.Put_Line ("Id : " & Swagger.Long'Image (Pet.Id)); + Ada.Text_IO.Put_Line ("Name : " & Swagger.To_String (Pet.Name)); + Ada.Text_IO.Put_Line ("Status : " & Swagger.To_String (Pet.Status)); +``` From 9f6104a8460e6ee6849f9071c42f68c8a8cb8f18 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 14 Oct 2017 22:29:49 +0200 Subject: [PATCH 04/34] 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 --- .../swagger/codegen/languages/AdaCodegen.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) 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..152bc07b080 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 @@ -263,6 +263,34 @@ public Map postProcessOperations(Map objs) { 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); + + /* + * 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; } From e68c43c81ef2a086c6ed37e396354a4a75d7e7a2 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 14 Oct 2017 22:38:10 +0200 Subject: [PATCH 05/34] 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) --- .../main/resources/Ada/server-spec.mustache | 38 +++++++++++++++++-- 1 file changed, 34 insertions(+), 4 deletions(-) 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..c5c407b3dfc 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,50 @@ {{>licenseInfo}} {{#imports}}with {{import}}; {{/imports}} +with Swagger.Servers; with {{package}}.Models; package {{package}}.Servers is + use {{package}}.Models; + type Server_Type is limited interface; + +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + + -- {{summary}}{{#vendorExtensions.x-has-notes}} + -- {{notes}}{{/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}}) 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}} - -- {{notes}} - procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; - {{/hasMore}}{{/allParams}}); + -- {{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); {{/operation}} {{/operations}} {{/apis}} {{/apiInfo}} + end Skeleton; + end {{package}}.Servers; From de895272c4e2330adee5088691aacd940b0847f6 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 14 Oct 2017 22:40:13 +0200 Subject: [PATCH 06/34] 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 --- .../main/resources/Ada/server-body.mustache | 83 +++++++++++++++++-- 1 file changed, 76 insertions(+), 7 deletions(-) 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..a5b1e0de433 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache @@ -1,19 +1,88 @@ {{>licenseInfo}} +with Swagger.Streams; +with ASF.Rest.Operation; package body {{package}}.Servers is + + package body Skeleton is + {{#apiInfo}} {{#apis}} {{#operations}} {{#operation}} - -- {{summary}} - -- {{notes}} - procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; - {{/hasMore}}{{/allParams}}) is - begin - null; - end {{operationId}}; + -- {{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) is + {{#hasBodyParam}} + Input : Swagger.Value_Type; + {{/hasBodyParam}} + Impl : Implementation_Type; + {{#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}} + {{#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}}); + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + Impl.{{operationId}} (Result); + {{/returnType}} + {{^returnType}} + Impl.{{operationId}}; + {{/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 ASF.Rest.Operation (Handler => {{operationId}}'Access, + Method => ASF.Rest.{{httpMethod}}, + URI => "{{path}}"); +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + procedure Register (Server : in out Swagger.Servers.Application_Type'Class) is + begin +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + ASF.Rest.Register (Server, API_{{operationId}}.Definition); {{/operation}} {{/operations}} {{/apis}} {{/apiInfo}} + end Register; + + end Skeleton; + end {{package}}.Servers; From 71e95a56bd0c82d1bd84f0d73388f1b697a61d57 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 28 Oct 2017 13:46:08 +0200 Subject: [PATCH 07/34] Update the code generation to generate server Ada implementation code --- .../main/resources/Ada/server-body.mustache | 120 ++++++++++++++++++ .../main/resources/Ada/server-spec.mustache | 54 ++++++++ 2 files changed, 174 insertions(+) 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 a5b1e0de433..460ff6d6f2d 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache @@ -85,4 +85,124 @@ package body {{package}}.Servers is 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) 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}} + {{#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}}); + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + Server.{{operationId}} (Result); + {{/returnType}} + {{^returnType}} + Server.{{operationId}}; + {{/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 ASF.Rest.Operation (Handler => {{operationId}}'Access, + Method => ASF.Rest.{{httpMethod}}, + URI => "{{path}}"); +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + + procedure Register (Server : in out Swagger.Servers.Application_Type'Class) is + begin +{{#apiInfo}} +{{#apis}} +{{#operations}} +{{#operation}} + ASF.Rest.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}}) is + begin + Impl.{{operationId}} + ({{#allParams}}{{paramName}}{{#hasMore}}, + {{/hasMore}}{{/allParams}}{{#returnType}}, + Result{{/returnType}}); + end {{operationId}}; + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + procedure {{operationId}} (Result : out {{returnType}}) is + begin + Impl.{{operationId}} (Result); + end {{operationId}}; + {{/returnType}} + {{^returnType}} + procedure {{operationId}} is + begin + Impl.{{operationId}}; + end {{operationId}}; + {{/returnType}} + {{/hasParams}} + +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + end Server; + + end Shared_Instance; + end {{package}}.Servers; 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 c5c407b3dfc..407bb97007e 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache @@ -47,4 +47,58 @@ package {{package}}.Servers is {{/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); + +{{/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}}); + {{/hasParams}} + {{^hasParams}} + {{#returnType}} + procedure {{operationId}} (Result : out {{returnType}}); + {{/returnType}} + {{^returnType}} + procedure {{operationId}}; + {{/returnType}} + {{/hasParams}} + +{{/operation}} +{{/operations}} +{{/apis}} +{{/apiInfo}} + private + Impl : Implementation_Type; + end Server; + end Shared_Instance; + end {{package}}.Servers; From 1f824f040026147a0b183697dc6505d021b99532 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Fri, 8 Dec 2017 21:38:01 +0100 Subject: [PATCH 08/34] Improvement of Ada server support: generate the swagger.json template file --- .../io/swagger/codegen/languages/AdaCodegen.java | 16 +++++++++++++++- .../src/main/resources/Ada/server-spec.mustache | 4 ++-- .../src/main/resources/Ada/swagger.mustache | 1 + 3 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/Ada/swagger.mustache 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 152bc07b080..15567193bd7 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 @@ -3,12 +3,14 @@ import java.io.File; import java.util.*; +import com.fasterxml.jackson.core.JsonProcessingException; 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; public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig { protected String packageName = "swagger"; @@ -100,6 +102,7 @@ public void processOpts() { // String title = swagger.getInfo().getTitle(); supportingFiles.add(new SupportingFile("gnat-project.mustache", "", "project.gpr")); + 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); @@ -262,7 +265,7 @@ public Map postProcessOperations(Map objs) { 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); + op1.vendorExtensions.put("x-has-notes", op1.notes != null && op1.notes.length() > 0); /* * Scan the path parameter to construct a x-path-index that tells the index of @@ -385,6 +388,17 @@ public int compare(Map lhs, Map rhs) { @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); + } return super.postProcessSupportingFileData(objs); } } 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 407bb97007e..6660aa53857 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache @@ -80,8 +80,8 @@ package {{package}}.Servers is {{#hasParams}} procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; - {{/hasMore}}{{/allParams}}{{#returnType}}; - Result : out {{returnType}}{{/returnType}}); + {{/hasMore}}{{/allParams}}{{#returnType}}; + Result : out {{returnType}}{{/returnType}}); {{/hasParams}} {{^hasParams}} {{#returnType}} 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 From 3436dd9a488fdfb2f2d9aeeb975627a9d7537018 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 10 Dec 2017 11:22:57 +0100 Subject: [PATCH 09/34] Define toModelName operation to the creation of a model identifier --- .../codegen/languages/AbstractAdaCodegen.java | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) 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..337ae23e59c 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 @@ -152,12 +152,29 @@ 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; } } From 18af3f812145f38ece114b482b7626107431495a Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 10 Dec 2017 11:25:05 +0100 Subject: [PATCH 10/34] 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. --- .../swagger/codegen/languages/AdaCodegen.java | 108 ++++++++++++++++-- 1 file changed, 96 insertions(+), 12 deletions(-) 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 15567193bd7..129a4cef5b8 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,9 +1,15 @@ package io.swagger.codegen.languages; import java.io.File; +import java.io.IOException; +import java.io.Writer; import java.util.*; +import java.util.regex.Matcher; import com.fasterxml.jackson.core.JsonProcessingException; +import com.samskivert.mustache.Escapers; +import com.samskivert.mustache.Mustache; +import com.samskivert.mustache.Template; import io.swagger.codegen.*; import io.swagger.models.Model; import io.swagger.models.Operation; @@ -17,6 +23,8 @@ public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig { protected String projectName = "Swagger"; protected List> orderedModels; protected Map> modelDepends; + protected int scopeIndex = 0; + protected HashMap operationsScopes; public AdaCodegen() { super(); @@ -55,6 +63,7 @@ public AdaCodegen() { typeMapping.put("binary", "Swagger.Binary"); super.importMapping = new HashMap(); + operationsScopes = new HashMap(); } @Override @@ -118,6 +127,16 @@ public void processOpts() { */ additionalProperties.put("package", this.modelPackage); additionalProperties.put(CodegenConstants.PROJECT_NAME, projectName); + + // 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 @@ -150,7 +169,23 @@ public String escapeQuotationMark(String input) { @Override public String escapeUnsafeCharacters(String input) { - return input.replace("*/", "*_/").replace("/*", "/_*"); +// String result = input.replaceAll("`", "'"); + 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); } /** @@ -165,6 +200,10 @@ public String escapeUnsafeCharacters(String input) { 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(); @@ -182,7 +221,7 @@ public String getTypeDeclaration(Property p) { if (languageSpecificPrimitives.contains(swaggerType)) { return swaggerType; } - String modelType = toModelName(swaggerType); + String modelType = toModelName(swaggerType).replace("-", "_"); if (p instanceof StringProperty || p instanceof DateProperty || p instanceof DateTimeProperty || p instanceof FileProperty || languageSpecificPrimitives.contains(modelType)) { @@ -267,6 +306,8 @@ public Map postProcessOperations(Map objs) { op1.vendorExtensions.put("x-has-uniq-consumes", postProcessMediaTypes(op1.consumes) == 1); op1.vendorExtensions.put("x-has-notes", op1.notes != null && op1.notes.length() > 0); + postProcessAuthMethod(op1.authMethods); + /* * Scan the path parameter to construct a x-path-index that tells the index of * the path parameter. @@ -385,20 +426,63 @@ public int compare(Map lhs, Map rhs) { return postProcessModelsEnum(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); + } + } + } + @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); - } + 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); } } From 742339343390648f8d8ef45606152d21eabc05d4 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 10 Dec 2017 11:26:44 +0100 Subject: [PATCH 11/34] Use the #lambdaAdaComment filter to indent correctly a multi-line description --- .../src/main/resources/Ada/client-body.mustache | 7 ++++--- .../src/main/resources/Ada/client-spec.mustache | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) 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}}; From d35eb5a1a17f9f5f8bdd0487db01f0e8bed43626 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 10 Dec 2017 11:27:34 +0100 Subject: [PATCH 12/34] Fix model generation to support arrays --- .../src/main/resources/Ada/model-body.mustache | 4 ++-- .../src/main/resources/Ada/model-spec.mustache | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) 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; From e651ca7866ddd6bec9596f3fc333579195f256af Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 10 Dec 2017 11:27:56 +0100 Subject: [PATCH 13/34] Update the generated GNAT project file --- .../src/main/resources/Ada/gnat-project.mustache | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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..582bf7c8ebb 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache @@ -1,13 +1,16 @@ --- {{{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"); From 462682ef6c6e928684ac45d280709b85e83e641d Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 10 Dec 2017 11:28:25 +0100 Subject: [PATCH 14/34] 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 --- .../main/resources/Ada/server-body.mustache | 73 +++++++++++-------- .../main/resources/Ada/server-spec.mustache | 27 ++++--- 2 files changed, 62 insertions(+), 38 deletions(-) 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 460ff6d6f2d..2dcb9edc0bd 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache @@ -1,6 +1,6 @@ {{>licenseInfo}} with Swagger.Streams; -with ASF.Rest.Operation; +with Swagger.Servers.Operation; package body {{package}}.Servers is package body Skeleton is @@ -12,9 +12,10 @@ package body {{package}}.Servers is -- {{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) is + (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}} @@ -32,6 +33,11 @@ package body {{package}}.Servers is {{#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); @@ -43,14 +49,14 @@ package body {{package}}.Servers is {{/hasBodyParam}} Impl.{{operationId}} ({{#allParams}}{{paramName}}{{#hasMore}}, - {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result{{/returnType}}); + {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result, Context{{/returnType}}); {{/hasParams}} {{^hasParams}} {{#returnType}} - Impl.{{operationId}} (Result); + Impl.{{operationId}} (Result, Context); {{/returnType}} {{^returnType}} - Impl.{{operationId}}; + Impl.{{operationId}} (Context); {{/returnType}} {{/hasParams}} {{#returnType}} @@ -62,9 +68,9 @@ package body {{package}}.Servers is end {{operationId}}; package API_{{operationId}} is - new ASF.Rest.Operation (Handler => {{operationId}}'Access, - Method => ASF.Rest.{{httpMethod}}, - URI => "{{path}}"); + new Swagger.Servers.Operation (Handler => {{operationId}}, + Method => Swagger.Servers.{{httpMethod}}, + URI => "{{path}}"); {{/operation}} {{/operations}} {{/apis}} @@ -76,7 +82,7 @@ package body {{package}}.Servers is {{#apis}} {{#operations}} {{#operation}} - ASF.Rest.Register (Server, API_{{operationId}}.Definition); + Swagger.Servers.Register (Server, API_{{operationId}}.Definition); {{/operation}} {{/operations}} {{/apis}} @@ -94,9 +100,10 @@ package body {{package}}.Servers is -- {{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) is + (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}} @@ -113,6 +120,11 @@ package body {{package}}.Servers is {{#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); @@ -124,14 +136,14 @@ package body {{package}}.Servers is {{/hasBodyParam}} Server.{{operationId}} ({{#allParams}}{{paramName}}{{#hasMore}}, - {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result{{/returnType}}); + {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result, Context{{/returnType}}); {{/hasParams}} {{^hasParams}} {{#returnType}} - Server.{{operationId}} (Result); + Server.{{operationId}} (Result, Context); {{/returnType}} {{^returnType}} - Server.{{operationId}}; + Server.{{operationId}} (Context); {{/returnType}} {{/hasParams}} {{#returnType}} @@ -143,9 +155,9 @@ package body {{package}}.Servers is end {{operationId}}; package API_{{operationId}} is - new ASF.Rest.Operation (Handler => {{operationId}}'Access, - Method => ASF.Rest.{{httpMethod}}, - URI => "{{path}}"); + new Swagger.Servers.Operation (Handler => {{operationId}}, + Method => Swagger.Servers.{{httpMethod}}, + URI => "{{path}}"); {{/operation}} {{/operations}} {{/apis}} @@ -157,7 +169,7 @@ package body {{package}}.Servers is {{#apis}} {{#operations}} {{#operation}} - ASF.Rest.Register (Server, API_{{operationId}}.Definition); + Swagger.Servers.Register (Server, API_{{operationId}}.Definition); {{/operation}} {{/operations}} {{/apis}} @@ -173,26 +185,29 @@ package body {{package}}.Servers is {{#hasParams}} procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; - {{/hasMore}}{{/allParams}}{{#returnType}}; - Result : out {{returnType}}{{/returnType}}) is + {{/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}}); + {{/hasMore}}{{/allParams}}{{#returnType}}, + Result{{/returnType}}, + Context); end {{operationId}}; {{/hasParams}} {{^hasParams}} {{#returnType}} - procedure {{operationId}} (Result : out {{returnType}}) is + procedure {{operationId}} (Result : out {{returnType}}; + Context : in out Swagger.Servers.Context_Type) is begin - Impl.{{operationId}} (Result); + Impl.{{operationId}} (Result, Context); end {{operationId}}; {{/returnType}} {{^returnType}} - procedure {{operationId}} is + procedure {{operationId}} (Context : in out Swagger.Servers.Context_Type) is begin - Impl.{{operationId}}; + Impl.{{operationId}} (Context); end {{operationId}}; {{/returnType}} {{/hasParams}} 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 6660aa53857..638f4782c81 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache @@ -3,9 +3,14 @@ {{/imports}} with Swagger.Servers; with {{package}}.Models; +with Security.Permissions; package {{package}}.Servers 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}} @@ -13,12 +18,13 @@ package {{package}}.Servers is {{#operation}} -- {{summary}}{{#vendorExtensions.x-has-notes}} - -- {{notes}}{{/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}}) is abstract; + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type) is abstract; {{/operation}} {{/operations}} {{/apis}} @@ -37,9 +43,10 @@ package {{package}}.Servers is -- {{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); + (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}} @@ -60,9 +67,10 @@ package {{package}}.Servers is -- {{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); + (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}} @@ -81,7 +89,8 @@ package {{package}}.Servers is procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; {{/hasMore}}{{/allParams}}{{#returnType}}; - Result : out {{returnType}}{{/returnType}}); + Result : out {{returnType}}{{/returnType}}; + Context : in out Swagger.Servers.Context_Type); {{/hasParams}} {{^hasParams}} {{#returnType}} From 0731f041945fa2da6f869947ad02e7d76cdc03c1 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 13:59:36 +0100 Subject: [PATCH 15/34] Server code generation improvement - Fix generation of GNAT project - Generate the intermediate Ada packages if necessary - Generate the server main --- .../swagger/codegen/languages/AdaCodegen.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) 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 129a4cef5b8..2284f7de0a3 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 @@ -110,7 +110,6 @@ public void processOpts() { 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")); supportingFiles.add(new SupportingFile("swagger.mustache", "web" + File.separator + "swagger", "swagger.json")); if (additionalProperties.containsKey(CodegenConstants.PROJECT_NAME)) { @@ -120,6 +119,7 @@ public void processOpts() { // e.g. petstore.api (package name) => petstore_api (project name) projectName = packageName.replaceAll("\\.", "_"); } + supportingFiles.add(new SupportingFile("gnat-project.mustache", "", projectName + ".gpr")); /* * Additional Properties. These values can be passed to the templates and @@ -128,6 +128,22 @@ public void processOpts() { additionalProperties.put("package", this.modelPackage); 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 + names[0].toLowerCase() + ".ads")); + if (names.length > 1) { + String fileName = names[0].toLowerCase() + "-" + names[1].toLowerCase() + ".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 + pkgName.toLowerCase() + "-server.adb")); + // add lambda for mustache templates additionalProperties.put("lambdaAdaComment", new Mustache.Lambda() { @Override @@ -302,6 +318,12 @@ public Map postProcessOperations(Map objs) { 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); From c15a266006d66905adfd905a7f731142b7747862 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 14:00:45 +0100 Subject: [PATCH 16/34] Ada server main template --- .../src/main/resources/Ada/server.mustache | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 modules/swagger-codegen/src/main/resources/Ada/server.mustache 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..4f4666a1ee0 --- /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 Samples.Server; +procedure {{package}}.Server is + procedure Configure (Config : in out AWS.Config.Object); + + CONFIG_PATH : constant String := "{{package}}.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; + 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.Setup (Props); + Samples.Server.My_Server.Register (App); + + WS.Configure (Configure'Access); + WS.Register_Application ("/v2", App'Unchecked_Access); + App.Dump_Routes (Util.Log.INFO_LEVEL); + Log.Info ("Connect you browser to: http://localhost:8080/v2"); + + 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; From ce44ca4a481223f714dbd5a3671a40d4a394bc8a Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 14:01:07 +0100 Subject: [PATCH 17/34] Ada server code improvement - Add support to generate server permission verification - Fix the GNAT project definition - Templates for Ada intermediate packages --- .../main/resources/Ada/gnat-project.mustache | 2 +- .../Ada/package-spec-level1.mustache | 3 +++ .../Ada/package-spec-level2.mustache | 5 +++++ .../main/resources/Ada/server-body.mustache | 22 +++++++++++++------ .../main/resources/Ada/server-spec.mustache | 14 +++++++----- 5 files changed, 32 insertions(+), 14 deletions(-) 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 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 582bf7c8ebb..bc98c924ab8 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache @@ -13,7 +13,7 @@ with "security"; with "swagger"; project {{{projectName}}} is - Mains := ("{{{appName}}}-server.adb"); + Mains := ("{{{packageName}}}-server.adb"); for Main use Mains; for Source_Dirs use ("src", "src/client", "src/server"); for Object_Dir use "./" & Config'Exec_Dir & "/bin"; 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..d882ed54634 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache @@ -0,0 +1,3 @@ +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..0eee63e0d06 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache @@ -0,0 +1,5 @@ +{{>licenseInfo}} + +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 2dcb9edc0bd..2f2424179c3 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache @@ -10,6 +10,11 @@ package body {{package}}.Servers is {{#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; @@ -27,6 +32,14 @@ package body {{package}}.Servers is 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}} @@ -49,7 +62,7 @@ package body {{package}}.Servers is {{/hasBodyParam}} Impl.{{operationId}} ({{#allParams}}{{paramName}}{{#hasMore}}, - {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result, Context{{/returnType}}); + {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result{{/returnType}}, Context); {{/hasParams}} {{^hasParams}} {{#returnType}} @@ -66,11 +79,6 @@ package body {{package}}.Servers is {{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}} @@ -136,7 +144,7 @@ package body {{package}}.Servers is {{/hasBodyParam}} Server.{{operationId}} ({{#allParams}}{{paramName}}{{#hasMore}}, - {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result, Context{{/returnType}}); + {{/hasMore}}{{/allParams}}{{#returnType}}{{#hasParams}}, {{/hasParams}}Result{{/returnType}}, Context); {{/hasParams}} {{^hasParams}} {{#returnType}} 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 638f4782c81..952460dae75 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache @@ -7,10 +7,10 @@ with Security.Permissions; package {{package}}.Servers is use {{package}}.Models; type Server_Type is limited interface; - {{#authMethods}}{{#scopes}} +{{#authMethods}}{{#scopes}} -- {{description}} package ACL_{{ident}} is new Security.Permissions.Definition ("{{scope}}"); - {{/scopes}}{{/authMethods}} +{{/scopes}}{{/authMethods}} {{#apiInfo}} {{#apis}} @@ -23,7 +23,7 @@ package {{package}}.Servers is (Server : in out Server_Type{{#hasParams}};{{/hasParams}} {{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; {{/hasMore}}{{/allParams}}{{#returnType}}; - Result : out {{returnType}}{{/returnType}}; + Result : out {{returnType}}{{/returnType}}; Context : in out Swagger.Servers.Context_Type) is abstract; {{/operation}} {{/operations}} @@ -89,15 +89,17 @@ package {{package}}.Servers is procedure {{operationId}} ({{#allParams}}{{paramName}} : in {{dataType}}{{#hasMore}}; {{/hasMore}}{{/allParams}}{{#returnType}}; - Result : out {{returnType}}{{/returnType}}; + Result : out {{returnType}}{{/returnType}}; Context : in out Swagger.Servers.Context_Type); {{/hasParams}} {{^hasParams}} {{#returnType}} - procedure {{operationId}} (Result : out {{returnType}}); + procedure {{operationId}} + (Result : out {{returnType}}; + Context : in out Swagger.Servers.Context_Type); {{/returnType}} {{^returnType}} - procedure {{operationId}}; + procedure {{operationId}} (Context : in out Swagger.Servers.Context_Type); {{/returnType}} {{/hasParams}} From 53d4f7ea065aa68526b2bc9d39fee5d9dc505de7 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 15:27:52 +0100 Subject: [PATCH 18/34] Skeleton for the server side implementation --- .../Ada/server-skeleton-body.mustache | 231 ++++++++++++++++++ .../Ada/server-skeleton-spec.mustache | 115 +++++++++ 2 files changed, 346 insertions(+) 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 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; From d4660e2d2fb2decfa578b3ffc231f76e4508ebff Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 15:28:21 +0100 Subject: [PATCH 19/34] Generate an empty Ada server implementation --- .../io/swagger/codegen/languages/AdaCodegen.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) 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 2284f7de0a3..5b3f586d2ee 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 @@ -98,16 +98,20 @@ public void 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); + String srcPrefix = "src" + File.separator; + String serverPrefix = srcPrefix + "server" + File.separator + toFilename(modelPackage); + String clientPrefix = srcPrefix + "client" + File.separator + toFilename(modelPackage); + String implPrefix = srcPrefix + 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")); 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")); + 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")); // String title = swagger.getInfo().getTitle(); supportingFiles.add(new SupportingFile("swagger.mustache", "web" + File.separator + "swagger", "swagger.json")); From 9264f62a1dbedae9550364ecf330ba75fba785d2 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 15:28:48 +0100 Subject: [PATCH 20/34] Templates for the Ada server implementation --- .../main/resources/Ada/server-body.mustache | 229 +----------------- .../main/resources/Ada/server-spec.mustache | 94 +------ .../src/main/resources/Ada/server.mustache | 8 +- 3 files changed, 22 insertions(+), 309 deletions(-) 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 2f2424179c3..a393a272692 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-body.mustache @@ -1,231 +1,26 @@ {{>licenseInfo}} -with Swagger.Streams; -with Swagger.Servers.Operation; package body {{package}}.Servers 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}} + -- {{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}}; {{/operation}} {{/operations}} {{/apis}} {{/apiInfo}} - end Server; - - end Shared_Instance; end {{package}}.Servers; 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 952460dae75..f37a38736a9 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-spec.mustache @@ -3,14 +3,10 @@ {{/imports}} with Swagger.Servers; with {{package}}.Models; -with Security.Permissions; +with {{package}}.Skeletons; package {{package}}.Servers is use {{package}}.Models; - type Server_Type is limited interface; -{{#authMethods}}{{#scopes}} - -- {{description}} - package ACL_{{ident}} is new Security.Permissions.Definition ("{{scope}}"); -{{/scopes}}{{/authMethods}} + type Server_Type is limited new {{package}}.Skeletons.Server_Type with null record; {{#apiInfo}} {{#apis}} @@ -19,97 +15,19 @@ package {{package}}.Servers 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 abstract; + Context : in out Swagger.Servers.Context_Type); {{/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; + 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 index 4f4666a1ee0..227519177d8 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server.mustache @@ -4,7 +4,7 @@ with Swagger.Servers.AWS; with Swagger.Servers.Applications; with Util.Log.Loggers; with Util.Properties; -with Samples.Server; +with {{package}}.Servers; procedure {{package}}.Server is procedure Configure (Config : in out AWS.Config.Object); @@ -17,7 +17,7 @@ procedure {{package}}.Server is AWS.Config.Set.Accept_Queue_Size (Config, 512); end Configure; - App : aliased Swagger.Servers.Applications.Application; + 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; @@ -25,8 +25,8 @@ begin Props.Load_Properties (CONFIG_PATH); Util.Log.Loggers.Initialize (Props); - App.Setup (Props); - Samples.Server.My_Server.Register (App); + App.Configure (Props); + {{package}}.Servers.Server_Impl.Register (App); WS.Configure (Configure'Access); WS.Register_Application ("/v2", App'Unchecked_Access); From 07584337b08ae88c32b98a990a746f03d8b05c9a Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 17:01:29 +0100 Subject: [PATCH 21/34] Add a README.md file and a GNAT config.gpr file --- .../src/main/java/io/swagger/codegen/languages/AdaCodegen.java | 2 ++ 1 file changed, 2 insertions(+) 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 5b3f586d2ee..b3b1ddf8d9c 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 @@ -124,6 +124,8 @@ public void processOpts() { projectName = packageName.replaceAll("\\.", "_"); } supportingFiles.add(new SupportingFile("gnat-project.mustache", "", 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 From 9ea51423e8bd2774f0ac226c1540ea33d8e47aed Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 17:01:56 +0100 Subject: [PATCH 22/34] New templates to document the generated Ada server --- .../src/main/resources/Ada/README.mustache | 102 ++++++++++++++++++ .../src/main/resources/Ada/config.gpr | 88 +++++++++++++++ 2 files changed, 190 insertions(+) create mode 100644 modules/swagger-codegen/src/main/resources/Ada/README.mustache create mode 100644 modules/swagger-codegen/src/main/resources/Ada/config.gpr 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/config.gpr b/modules/swagger-codegen/src/main/resources/Ada/config.gpr new file mode 100644 index 00000000000..73c24f58edc --- /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 "Subversion"; + end Ide; + +end Config; From 00850806122d06c7f0dd7cea6f7d2cb6406c158d Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 18:04:07 +0100 Subject: [PATCH 23/34] Add server configuration file for the Ada server --- .../resources/Ada/server-properties.mustache | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache 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..25182b43e24 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache @@ -0,0 +1,21 @@ +swagger.dir=web +swagger.ui.enable=1 + +# 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 + + From c3aac0800a9485b63ccb9f73e5ca82a2cc44b7be Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 18:04:39 +0100 Subject: [PATCH 24/34] Fix the log message in the Ada server to report the correct URI to connect to --- .../swagger-codegen/src/main/resources/Ada/server.mustache | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/Ada/server.mustache b/modules/swagger-codegen/src/main/resources/Ada/server.mustache index 227519177d8..08aba9f071a 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server.mustache @@ -8,7 +8,7 @@ with {{package}}.Servers; procedure {{package}}.Server is procedure Configure (Config : in out AWS.Config.Object); - CONFIG_PATH : constant String := "{{package}}.properties"; + CONFIG_PATH : constant String := "{{packageConfig}}.properties"; procedure Configure (Config : in out AWS.Config.Object) is begin @@ -29,9 +29,9 @@ begin {{package}}.Servers.Server_Impl.Register (App); WS.Configure (Configure'Access); - WS.Register_Application ("/v2", App'Unchecked_Access); + WS.Register_Application ("{{basePathWithoutHost}}", App'Unchecked_Access); App.Dump_Routes (Util.Log.INFO_LEVEL); - Log.Info ("Connect you browser to: http://localhost:8080/v2"); + Log.Info ("Connect you browser to: http://localhost:8080{{basePathWithoutHost}}/ui/index.html"); WS.Start; From 11f5b9697288129fe27f50548d1e2955fcedc5ee Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Thu, 21 Dec 2017 18:05:10 +0100 Subject: [PATCH 25/34] Generate the Ada server configuration file --- .../src/main/java/io/swagger/codegen/languages/AdaCodegen.java | 3 +++ 1 file changed, 3 insertions(+) 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 b3b1ddf8d9c..53e0d39ed98 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 @@ -123,15 +123,18 @@ 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", "", 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(CodegenConstants.PROJECT_NAME, projectName); String names[] = this.modelPackage.split("\\."); From 85ec66be5f4cf82338368eafa1fb623e1102371c Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 23 Dec 2017 23:15:11 +0100 Subject: [PATCH 26/34] Improvement of Ada code model to support nullable types --- .../io/swagger/codegen/languages/AdaCodegen.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) 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 53e0d39ed98..fbb63054815 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 @@ -23,6 +23,7 @@ public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig { protected String projectName = "Swagger"; protected List> orderedModels; protected Map> modelDepends; + protected Map nullableTypeMapping; protected int scopeIndex = 0; protected HashMap operationsScopes; @@ -62,6 +63,15 @@ public AdaCodegen() { 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"); + super.importMapping = new HashMap(); operationsScopes = new HashMap(); } @@ -240,7 +250,11 @@ public String getTypeDeclaration(Property p) { return "Swagger." + getTypeDeclaration(inner) + "_Map"; } if (typeMapping.containsKey(swaggerType)) { - return typeMapping.get(swaggerType); + if (p.getRequired()) { + return typeMapping.get(swaggerType); + } else { + return nullableTypeMapping.get(swaggerType); + } } // LOGGER.info("Swagger type " + swaggerType); if (languageSpecificPrimitives.contains(swaggerType)) { From 61a3adc7db4741dc0ff431171e564ce595b21336 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sat, 23 Dec 2017 23:15:51 +0100 Subject: [PATCH 27/34] Update the Ada server templates --- .../src/main/resources/Ada/server-body.mustache | 12 +++++++++++- .../main/resources/Ada/server-properties.mustache | 3 ++- .../src/main/resources/Ada/server-spec.mustache | 12 +++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) 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 a393a272692..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,4 +1,14 @@ -{{>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}} diff --git a/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache b/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache index 25182b43e24..654383c72f3 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/server-properties.mustache @@ -1,5 +1,6 @@ swagger.dir=web -swagger.ui.enable=1 +swagger.web.enable=false +swagger.ui.enable=true # Configuration for log4j log4j.rootCategory=DEBUG,console,result 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 f37a38736a9..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,4 +1,14 @@ -{{>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; From cd1215b60ffb30097b55bb3031a15d776d75f180 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 24 Dec 2017 09:20:41 +0100 Subject: [PATCH 28/34] 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 --- .../codegen/languages/AbstractAdaCodegen.java | 428 ++++++++++++++++- .../swagger/codegen/languages/AdaCodegen.java | 440 +----------------- .../codegen/languages/AdaServerCodegen.java | 108 +++++ .../services/io.swagger.codegen.CodegenConfig | 1 + 4 files changed, 535 insertions(+), 442 deletions(-) create mode 100644 modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaServerCodegen.java 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 337ae23e59c..c8ea600a899 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,62 @@ 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); + 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); + + 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(); } /** @@ -177,4 +246,353 @@ public CodegenProperty fromProperty(String name, Property p) { } 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(); + return "Swagger." + getTypeDeclaration(inner) + "_Map"; + } + 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); + + 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 fbb63054815..03f81d66dbf 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 @@ -3,77 +3,15 @@ import java.io.File; import java.io.IOException; import java.io.Writer; -import java.util.*; -import java.util.regex.Matcher; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.samskivert.mustache.Escapers; 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.*; -import io.swagger.util.Json; public class AdaCodegen extends AbstractAdaCodegen implements CodegenConfig { - protected String packageName = "swagger"; - protected String projectName = "Swagger"; - protected List> orderedModels; - protected Map> modelDepends; - protected Map nullableTypeMapping; - protected int scopeIndex = 0; - protected HashMap operationsScopes; 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"); - - 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"); - - super.importMapping = new HashMap(); - operationsScopes = new HashMap(); } @Override @@ -91,17 +29,6 @@ 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(); @@ -109,22 +36,12 @@ public void processOpts() { 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 clientPrefix = srcPrefix + "client" + File.separator + toFilename(modelPackage); - String implPrefix = srcPrefix + 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")); + 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-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")); - - // String title = swagger.getInfo().getTitle(); - 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); @@ -137,7 +54,6 @@ public void processOpts() { supportingFiles.add(new SupportingFile("gnat-project.mustache", "", 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 @@ -159,9 +75,6 @@ public void processOpts() { 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 + pkgName.toLowerCase() + "-server.adb")); // add lambda for mustache templates additionalProperties.put("lambdaAdaComment", new Mustache.Lambda() { @@ -183,351 +96,4 @@ public String apiFileFolder() { 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) { -// String result = input.replaceAll("`", "'"); - 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(); - return "Swagger." + getTypeDeclaration(inner) + "_Map"; - } - 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); - - 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); - - 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); - } - - /** - * 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); - } - } - } - - @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); - } } 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..808a02b77ef --- /dev/null +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/AdaServerCodegen.java @@ -0,0 +1,108 @@ +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", "", 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(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 + names[0].toLowerCase() + ".ads")); + if (names.length > 1) { + String fileName = names[0].toLowerCase() + "-" + names[1].toLowerCase() + ".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 + pkgName.toLowerCase() + "-server.adb")); + + // 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/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 5c5d4220bad..5189f50eec2 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 From 10498d537dafa66f1b01db84f6ab21c0faf3287e Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 24 Dec 2017 14:57:03 +0100 Subject: [PATCH 29/34] 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 --- .../codegen/languages/AbstractAdaCodegen.java | 24 ++++++++--- .../swagger/codegen/languages/AdaCodegen.java | 13 +++++- .../codegen/languages/AdaServerCodegen.java | 9 ++-- .../src/main/resources/Ada/client.mustache | 43 +++++++++++++++++++ .../main/resources/Ada/gnat-project.mustache | 4 +- 5 files changed, 79 insertions(+), 14 deletions(-) create mode 100644 modules/swagger-codegen/src/main/resources/Ada/client.mustache 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 c8ea600a899..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 @@ -136,12 +136,6 @@ public AbstractAdaCodegen() { // 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); modelNameSuffix = "_Type"; embeddedTemplateDir = templateDir = "Ada"; @@ -309,7 +303,12 @@ public String getTypeDeclaration(Property p) { if (p instanceof MapProperty) { MapProperty mp = (MapProperty) p; Property inner = mp.getAdditionalProperties(); - return "Swagger." + getTypeDeclaration(inner) + "_Map"; + String name = getTypeDeclaration(inner) + "_Map"; + if (name.startsWith("Swagger.")) { + return name; + } else { + return "Swagger." + name; + } } if (typeMapping.containsKey(swaggerType)) { if (p.getRequired()) { @@ -416,6 +415,17 @@ public Map postProcessOperations(Map objs) { 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); /* 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 03f81d66dbf..279e98da33b 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 @@ -35,6 +35,9 @@ public void processOpts() { if (additionalProperties.containsKey(CodegenConstants.PACKAGE_NAME)) { packageName = (String) additionalProperties.get(CodegenConstants.PACKAGE_NAME); } + 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); @@ -61,20 +64,26 @@ public void processOpts() { */ 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 + names[0].toLowerCase() + ".ads")); + "src" + File.separator + toFilename(names[0]) + ".ads")); if (names.length > 1) { - String fileName = names[0].toLowerCase() + "-" + names[1].toLowerCase() + ".ads"; + 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() { 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 index 808a02b77ef..e6c8441c72b 100644 --- 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 @@ -67,15 +67,17 @@ public void processOpts() { */ 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 + names[0].toLowerCase() + ".ads")); + "src" + File.separator + toFilename(names[0]) + ".ads")); if (names.length > 1) { - String fileName = names[0].toLowerCase() + "-" + names[1].toLowerCase() + ".ads"; + 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, @@ -83,7 +85,8 @@ public void processOpts() { } pkgName = this.modelPackage; supportingFiles.add(new SupportingFile("server.mustache", null, - "src" + File.separator + pkgName.toLowerCase() + "-server.adb")); + "src" + File.separator + toFilename(pkgName) + "-server.adb")); + additionalProperties.put("packageName", toFilename(pkgName)); // add lambda for mustache templates additionalProperties.put("lambdaAdaComment", new Mustache.Lambda() { 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/gnat-project.mustache b/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache index bc98c924ab8..5bc6621e968 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/gnat-project.mustache @@ -13,9 +13,9 @@ with "security"; with "swagger"; project {{{projectName}}} is - Mains := ("{{{packageName}}}-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; From 99424c215a31d14c4bf6da20f7105c5e312609e4 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Sun, 24 Dec 2017 15:18:57 +0100 Subject: [PATCH 30/34] 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 --- .../io/swagger/codegen/languages/AdaCodegen.java | 4 ++-- .../swagger/codegen/languages/AdaServerCodegen.java | 2 +- .../src/main/resources/Ada/config.gpr | 2 +- .../main/resources/Ada/package-spec-level1.mustache | 11 +++++++++++ .../main/resources/Ada/package-spec-level2.mustache | 13 +++++++++++-- 5 files changed, 26 insertions(+), 6 deletions(-) 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 279e98da33b..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 @@ -54,8 +54,8 @@ public void processOpts() { projectName = packageName.replaceAll("\\.", "_"); } String configBaseName = modelPackage.toLowerCase(); - supportingFiles.add(new SupportingFile("gnat-project.mustache", "", projectName + ".gpr")); - supportingFiles.add(new SupportingFile("README.mustache", "", "README.md")); + 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")); /* 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 index e6c8441c72b..951ebec0f6c 100644 --- 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 @@ -56,7 +56,7 @@ public void processOpts() { projectName = packageName.replaceAll("\\.", "_"); } String configBaseName = modelPackage.toLowerCase(); - supportingFiles.add(new SupportingFile("gnat-project.mustache", "", projectName + ".gpr")); + 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")); diff --git a/modules/swagger-codegen/src/main/resources/Ada/config.gpr b/modules/swagger-codegen/src/main/resources/Ada/config.gpr index 73c24f58edc..d3533ef3398 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/config.gpr +++ b/modules/swagger-codegen/src/main/resources/Ada/config.gpr @@ -82,7 +82,7 @@ abstract project Config is end linker; package Ide is - for VCS_Kind use "Subversion"; + for VCS_Kind use "git"; end Ide; end Config; 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 index d882ed54634..3d9f3029d14 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level1.mustache @@ -1,3 +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 index 0eee63e0d06..70c0f494f08 100644 --- a/modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache +++ b/modules/swagger-codegen/src/main/resources/Ada/package-spec-level2.mustache @@ -1,5 +1,14 @@ -{{>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}}.ads +-- +-- Then, you can drop this edit note comment. +-- ------------ EDIT NOTE ------------ package {{packageLevel2}} is end {{packageLevel2}}; From 605b821ffa5f417cf804d5f26ee503ed5580ec67 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Tue, 26 Dec 2017 09:20:15 +0100 Subject: [PATCH 31/34] Regenerate the model and client Ada files --- .../src/client/samples-petstore-clients.adb | 22 ++++---- .../src/client/samples-petstore-clients.ads | 22 ++++---- .../samples-petstore-models.adb | 14 ++++- .../samples-petstore-models.ads | 56 ++++++++++--------- 4 files changed, 66 insertions(+), 48 deletions(-) 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/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 7bf3095598f..fc0e07382f6 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 catehgry -- 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; From b45db842393e8df9f00b8641010ec2c4b1ca16d7 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Tue, 26 Dec 2017 09:21:51 +0100 Subject: [PATCH 32/34] Update the Ada client sample to take into account the Nullable types --- samples/client/petstore/ada/src/petstore.adb | 66 +++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) 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; From a52170f1bc476a6195dd010c8fdee32577b88a52 Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Tue, 26 Dec 2017 09:22:25 +0100 Subject: [PATCH 33/34] Regenerate some files with Ada Swagger Codegen --- samples/client/petstore/ada/petstore.gpr | 16 ++++++++++++---- .../client/petstore/ada/src/samples-petstore.ads | 14 +++++++++++++- samples/client/petstore/ada/src/samples.ads | 14 +++++++++++++- 3 files changed, 38 insertions(+), 6 deletions(-) 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/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; From 471bcefc986186ab24fbf7ecf6b5d36a4cb778ea Mon Sep 17 00:00:00 2001 From: Stephane Carrez Date: Tue, 26 Dec 2017 10:21:21 +0100 Subject: [PATCH 34/34] Ignore generation of petstore.gpr --- samples/client/petstore/ada/.swagger-codegen-ignore | 1 + 1 file changed, 1 insertion(+) 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