From 8bb95d5ff3e3605a97da3055177a8f77b2e3a905 Mon Sep 17 00:00:00 2001 From: Fabian Schmidt Date: Thu, 26 Oct 2023 07:31:46 +0000 Subject: [PATCH] Update Client Generation --- src/model/zcl_oapi_parser.clas.abap | 16 +- src/model/zif_oapi_specification_v3.intf.abap | 18 +- src/utils/zif_oapi_exit.intf.abap | 42 ++ src/utils/zif_oapi_exit.intf.xml | 15 + src/v2/zcl_oapi_generator_v2.clas.abap | 578 ++++++++++++++---- 5 files changed, 547 insertions(+), 122 deletions(-) create mode 100644 src/utils/zif_oapi_exit.intf.abap create mode 100644 src/utils/zif_oapi_exit.intf.xml diff --git a/src/model/zcl_oapi_parser.clas.abap b/src/model/zcl_oapi_parser.clas.abap index fff5ef46..43b9edad 100644 --- a/src/model/zcl_oapi_parser.clas.abap +++ b/src/model/zcl_oapi_parser.clas.abap @@ -1,7 +1,7 @@ CLASS zcl_oapi_parser DEFINITION PUBLIC. PUBLIC SECTION. METHODS parse - IMPORTING iv_json TYPE string + IMPORTING iv_json TYPE string RETURNING VALUE(rs_schema) TYPE zif_oapi_specification_v3=>ty_specification. PRIVATE SECTION. @@ -14,30 +14,30 @@ CLASS zcl_oapi_parser DEFINITION PUBLIC. RETURNING VALUE(rt_servers) TYPE zif_oapi_specification_v3=>ty_servers. METHODS parse_parameters - IMPORTING iv_prefix TYPE string + IMPORTING iv_prefix TYPE string RETURNING VALUE(rt_parameters) TYPE zif_oapi_specification_v3=>ty_parameters. METHODS parse_parameters_ref - IMPORTING iv_prefix TYPE string + IMPORTING iv_prefix TYPE string RETURNING VALUE(rt_parameters) TYPE string_table. METHODS parse_responses - IMPORTING iv_prefix TYPE string + IMPORTING iv_prefix TYPE string RETURNING VALUE(rt_responses) TYPE zif_oapi_specification_v3=>ty_responses. METHODS parse_media_types - IMPORTING iv_prefix TYPE string + IMPORTING iv_prefix TYPE string RETURNING VALUE(rt_media_types) TYPE zif_oapi_specification_v3=>ty_media_types. METHODS parse_components RETURNING VALUE(rs_components) TYPE zif_oapi_specification_v3=>ty_components. METHODS parse_schema - IMPORTING iv_prefix TYPE string + IMPORTING iv_prefix TYPE string RETURNING VALUE(ri_schema) TYPE REF TO zif_oapi_schema. METHODS parse_schemas - IMPORTING iv_prefix TYPE string + IMPORTING iv_prefix TYPE string RETURNING VALUE(rt_schemas) TYPE zif_oapi_specification_v3=>ty_schemas. ENDCLASS. @@ -145,6 +145,8 @@ CLASS zcl_oapi_parser IMPLEMENTATION. LOOP AT lt_paths INTO lv_path. CLEAR ls_operation. ls_operation-path = lv_path. + ls_operation-path = replace( val = ls_operation-path regex = '\{[^}]*\}' with = space ). + lt_methods = mo_json->members( '/paths/' && lv_path && '/' ). LOOP AT lt_methods INTO lv_method. ls_operation-method = lv_method. diff --git a/src/model/zif_oapi_specification_v3.intf.abap b/src/model/zif_oapi_specification_v3.intf.abap index c5999e78..a984df90 100644 --- a/src/model/zif_oapi_specification_v3.intf.abap +++ b/src/model/zif_oapi_specification_v3.intf.abap @@ -32,13 +32,13 @@ INTERFACE zif_oapi_specification_v3 PUBLIC. TYPES ty_responses TYPE STANDARD TABLE OF ty_response WITH DEFAULT KEY. TYPES: BEGIN OF ty_operation, - path TYPE string, - method TYPE string, - summary TYPE string, - description TYPE string, - operation_id TYPE string, - deprecated TYPE abap_bool, - abap_name TYPE string, + path TYPE string, + method TYPE string, + summary TYPE string, + description TYPE string, + operation_id TYPE string, + deprecated TYPE abap_bool, + abap_name TYPE string, body_schema TYPE REF TO zif_oapi_schema, body_schema_ref TYPE string, parameters TYPE ty_parameters, @@ -72,8 +72,8 @@ INTERFACE zif_oapi_specification_v3 PUBLIC. END OF ty_components. TYPES: BEGIN OF ty_info, - title TYPE string, - version TYPE string, + title TYPE string, + version TYPE string, description TYPE string, END OF ty_info. diff --git a/src/utils/zif_oapi_exit.intf.abap b/src/utils/zif_oapi_exit.intf.abap new file mode 100644 index 00000000..f4415a87 --- /dev/null +++ b/src/utils/zif_oapi_exit.intf.abap @@ -0,0 +1,42 @@ +INTERFACE zif_oapi_exit + PUBLIC . + + METHODS constructor_exit + IMPORTING + ii_client TYPE REF TO if_http_client. + + METHODS before_send + IMPORTING + iv_path TYPE string + iv_operation_id TYPE string + iv_method TYPE string + ii_client TYPE REF TO if_http_client. + + METHODS after_receive + IMPORTING + iv_path TYPE string + iv_operation_id TYPE string + iv_method TYPE string + ii_client TYPE REF TO if_http_client. + + METHODS parse_response_to_abap + IMPORTING + iv_path TYPE string + iv_operation_id TYPE string + iv_method TYPE string + ii_client TYPE REF TO if_http_client + CHANGING + c_data TYPE data. + + METHODS parse_body_to_data + IMPORTING + iv_path TYPE string + iv_operation_id TYPE string + iv_method TYPE string + ii_client TYPE REF TO if_http_client + i_body TYPE data + RETURNING + VALUE(rv_body_data) TYPE xstring. + + +ENDINTERFACE. diff --git a/src/utils/zif_oapi_exit.intf.xml b/src/utils/zif_oapi_exit.intf.xml new file mode 100644 index 00000000..652a0902 --- /dev/null +++ b/src/utils/zif_oapi_exit.intf.xml @@ -0,0 +1,15 @@ + + + + + + ZIF_OAPI_EXIT + D + OpenAPI Userexit + 2 + 1 + X + + + + diff --git a/src/v2/zcl_oapi_generator_v2.clas.abap b/src/v2/zcl_oapi_generator_v2.clas.abap index 78e2c873..07b3334d 100644 --- a/src/v2/zcl_oapi_generator_v2.clas.abap +++ b/src/v2/zcl_oapi_generator_v2.clas.abap @@ -1,26 +1,32 @@ -CLASS zcl_oapi_generator_v2 DEFINITION PUBLIC. +CLASS zcl_oapi_generator_v2 DEFINITION + PUBLIC + CREATE PUBLIC . + PUBLIC SECTION. - TYPES: BEGIN OF ty_input, - clas_icf_serv TYPE c LENGTH 30, - clas_icf_impl TYPE c LENGTH 30, - clas_client TYPE c LENGTH 30, - intf TYPE c LENGTH 30, - openapi_json TYPE string, - END OF ty_input. - - TYPES: BEGIN OF ty_result, - clas_icf_serv TYPE string, - clas_icf_impl TYPE string, - clas_client TYPE string, - intf TYPE string, - END OF ty_result. + + TYPES: + BEGIN OF ty_input, + clas_icf_serv TYPE c LENGTH 30, + clas_icf_impl TYPE c LENGTH 30, + clas_client TYPE c LENGTH 30, + intf TYPE c LENGTH 30, + destination TYPE c LENGTH 30, + add_noparsing TYPE abap_bool, + openapi_json TYPE string, + END OF ty_input . + TYPES: + BEGIN OF ty_result, + clas_icf_serv TYPE string, + clas_icf_impl TYPE string, + clas_client TYPE string, + intf TYPE string, + END OF ty_result . METHODS run IMPORTING - is_input TYPE ty_input + !is_input TYPE ty_input RETURNING - VALUE(rs_result) TYPE ty_result. - + VALUE(rs_result) TYPE ty_result . PROTECTED SECTION. PRIVATE SECTION. DATA ms_specification TYPE zif_oapi_specification_v3=>ty_specification. @@ -40,9 +46,10 @@ CLASS zcl_oapi_generator_v2 DEFINITION PUBLIC. METHODS find_input_parameters IMPORTING - is_operation TYPE zif_oapi_specification_v3=>ty_operation + is_operation TYPE zif_oapi_specification_v3=>ty_operation + iv_no_body_type TYPE abap_bool DEFAULT abap_false RETURNING - VALUE(rv_abap) TYPE string. + VALUE(rv_abap) TYPE string. TYPES: BEGIN OF ty_returning, abap TYPE string, @@ -60,6 +67,18 @@ CLASS zcl_oapi_generator_v2 DEFINITION PUBLIC. RETURNING VALUE(rs_schema) TYPE zif_oapi_specification_v3=>ty_component_schema. + METHODS build_clas_client_response + IMPORTING + is_response TYPE zif_oapi_specification_v3=>ty_response + RETURNING + VALUE(rv_result) TYPE string. + + METHODS build_clas_client_body + IMPORTING + is_operation TYPE zif_oapi_specification_v3=>ty_operation + RETURNING + VALUE(rv_result) TYPE string. + ENDCLASS. @@ -67,33 +86,398 @@ ENDCLASS. CLASS zcl_oapi_generator_v2 IMPLEMENTATION. - METHOD find_schema. - DATA lv_name TYPE string. + METHOD build_clas_client. + DATA ls_operation LIKE LINE OF ms_specification-operations. + DATA lv_parameters TYPE string. + DATA lv_exit_class TYPE c LENGTH 30. - lv_name = iv_name. + lv_exit_class = ms_input-clas_client(25) && '_EXIT'. - REPLACE FIRST OCCURRENCE OF '#/components/schemas/' IN lv_name WITH ''. - READ TABLE ms_specification-components-schemas - INTO rs_schema WITH KEY name = lv_name. "#EC CI_SUBRC + "Declaration + rv_abap = |CLASS { ms_input-clas_client } DEFINITION PUBLIC.\n| && + |* Auto generated by https://github.com/abap-openapi/abap-openapi\n| && + | PUBLIC SECTION.\n| && + | INTERFACES { ms_input-intf }.\n| && + | METHODS constructor\n| && + | RAISING\n| && + | /iwbep/cx_gateway.\n| && + | METHODS get_http_client\n| && + | RETURNING VALUE(ri_client) TYPE REF TO if_http_client.\n| && + | METHODS get_exit_object\n| && + | RETURNING VALUE(ri_exit) TYPE REF TO zif_oapi_exit.\n| && + | PROTECTED SECTION.\n| && + | DATA mi_client TYPE REF TO if_http_client.\n| && + | DATA mi_exit TYPE REF TO zif_oapi_exit.\n| && + |ENDCLASS.\n\n|. + + "Impementation + "General + rv_abap = rv_abap && + |CLASS { ms_input-clas_client } IMPLEMENTATION.\n| && + | METHOD get_http_client.\n| && + | ri_client = mi_client.\n| && + | ENDMETHOD.\n\n| && + | METHOD get_exit_object.\n| && + | ri_exit = mi_exit.\n| && + | ENDMETHOD.\n\n| && + | METHOD constructor.\n| && + | cl_http_client=>create_by_destination(\n| && + | EXPORTING\n| && + | destination = '{ ms_input-destination }'\n| && + | IMPORTING\n| && + | client = mi_client\n| && + | EXCEPTIONS\n| && + | argument_not_found = 1\n| && + | destination_not_found = 2\n| && + | destination_no_authority = 3\n| && + | plugin_not_active = 4\n| && + | internal_error = 5\n| && + | OTHERS = 6 ).\n| && + | IF sy-subrc <> 0.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno.\n| && + | ENDIF.\n| && + |\n| && + | DATA(lv_class_name) = '{ lv_exit_class }'.\n| && + | TRY.\n| && + | CREATE OBJECT mi_exit TYPE (lv_class_name).\n| && + | mi_exit->constructor_exit(\n| && + | ii_client = mi_client ).\n| && + | CATCH cx_sy_create_object_error ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ENDMETHOD.\n\n|. + + + LOOP AT ms_specification-operations INTO ls_operation. + + "Parameters + CLEAR lv_parameters. + + IF ls_operation-parameters IS NOT INITIAL. + LOOP AT ls_operation-parameters ASSIGNING FIELD-SYMBOL(). + CASE -in. + + WHEN 'path'. + lv_parameters = -abap_name. + + WHEN 'query'. + IF sy-tabix = 1. + lv_parameters = |'?' && |. + ELSE. + lv_parameters = lv_parameters && | && '&' &&|. + ENDIF. + + lv_parameters = lv_parameters && |'{ -name }=' && { -abap_name }|. + WHEN 'header'. + "todo + WHEN 'cookie'. + "todo + + ENDCASE. + + ENDLOOP. + ELSE. + lv_parameters = |''|. + ENDIF. + + rv_abap = rv_abap && + | METHOD { ms_input-intf }~{ ls_operation-abap_name }.\n| && + |\n| && + | DATA:lv_path TYPE string,\n| && + | lv_parameters TYPE string,\n| && + | lv_uri TYPE string,\n| && + | lv_method TYPE string,\n| && + | lv_operation_id TYPE string,\n| && + | lv_body_data TYPE xstring,\n| && + | lv_response_string TYPE string,\n| && + | lv_code TYPE i,\n| && + | lv_reason TYPE string.\n| && + |\n| && + | lv_path = '{ ls_operation-path }'.\n| && + | lv_parameters = { lv_parameters }.\n| && + | lv_uri = lv_path && lv_parameters.\n| && + | lv_method = '{ to_upper( ls_operation-method ) }'.\n| && + | lv_operation_id = '{ ls_operation-operation_id }'.\n| && + |\n| && + | mi_client->request->set_method( lv_method ).\n| && + | cl_http_utility=>set_request_uri(\n| && + | request = mi_client->request\n| && + | uri = lv_uri ).\n|. + + "Body + rv_abap = rv_abap && build_clas_client_body( ls_operation ). + + "send + rv_abap = rv_abap && + | IF mi_exit IS BOUND.\n| && + | TRY.\n| && + | mi_exit->before_send(\n| && + | iv_path = lv_path\n| && + | iv_operation_id = lv_operation_id\n| && + | iv_method = lv_method\n| && + | ii_client = mi_client ).\n| && + | CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ENDIF.\n\n| && + | mi_client->send(\n| && + | EXCEPTIONS\n| && + | http_communication_failure = 1\n| && + | http_invalid_state = 2\n| && + | http_processing_failed = 3\n| && + | http_invalid_timeout = 4\n| && + | OTHERS = 5 ).\n| && + | IF sy-subrc <> 0.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno.\n| && + | ENDIF.\n\n|. + + "receive + rv_abap = rv_abap && + | mi_client->receive(\n| && + | EXCEPTIONS\n| && + | http_communication_failure = 1\n| && + | http_invalid_state = 2\n| && + | http_processing_failed = 3\n| && + | OTHERS = 4 ).\n| && + | IF sy-subrc <> 0.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno.\n| && + | ENDIF.\n| && + |\n| && + | IF mi_exit IS BOUND.\n| && + | TRY.\n| && + | mi_exit->after_receive(\n| && + | iv_path = lv_path\n| && + | iv_operation_id = lv_operation_id\n| && + | iv_method = lv_method\n| && + | ii_client = mi_client ).\n| && + | CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ENDIF.\n\n|. + + "Response + rv_abap = rv_abap && + | mi_client->response->get_status(\n| && + | IMPORTING\n| && + | code = lv_code\n| && + | reason = lv_reason ).\n\n|. + + IF ls_operation-responses IS NOT INITIAL. + rv_abap = rv_abap && + | CASE lv_code.\n|. + + LOOP AT ls_operation-responses ASSIGNING FIELD-SYMBOL(). + rv_abap = rv_abap && + | WHEN { -code }.\n| && + build_clas_client_response( ). + ENDLOOP. + + rv_abap = rv_abap && + | WHEN OTHERS.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | EXPORTING http_status_code = CONV #( lv_code ).\n| && + | ENDCASE.\n|. + ENDIF. + + rv_abap = rv_abap && + | ENDMETHOD.\n\n|. + + + IF ms_input-add_noparsing = abap_true. + + rv_abap = rv_abap && + | METHOD { ms_input-intf }~{ ls_operation-abap_name }_d.\n| && + |\n| && + | DATA:lv_path TYPE string,\n| && + | lv_parameters TYPE string,\n| && + | lv_uri TYPE string,\n| && + | lv_method TYPE string,\n| && + | lv_operation_id TYPE string,\n| && + | lv_body_data TYPE xstring,\n| && + | lv_code TYPE i,\n| && + | lv_reason TYPE string.\n| && + |\n| && + | lv_path = '{ ls_operation-path }'.\n| && + | lv_parameters = { lv_parameters }.\n| && + | lv_uri = lv_path && lv_parameters.\n| && + | lv_method = '{ to_upper( ls_operation-method ) }'.\n| && + | lv_operation_id = '{ ls_operation-operation_id }'.\n| && + |\n| && + | mi_client->request->set_method( lv_method ).\n| && + | cl_http_utility=>set_request_uri(\n| && + | request = mi_client->request\n| && + | uri = lv_uri ).\n\n|. + + "body + IF ls_operation-body_schema_ref IS NOT INITIAL. + rv_abap = rv_abap && + | mi_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).\n\n| && + | lv_body_data = cl_abap_codepage=>convert_to( source = body ).\n| && + | mi_client->request->set_data( lv_body_data ).\n\n|. + ENDIF. + + + "send + rv_abap = rv_abap && + | IF mi_exit IS BOUND.\n| && + | TRY.\n| && + | mi_exit->before_send(\n| && + | iv_path = lv_path\n| && + | iv_operation_id = lv_operation_id\n| && + | iv_method = lv_method\n| && + | ii_client = mi_client ).\n| && + | CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ENDIF.\n\n| && + | mi_client->send(\n| && + | EXCEPTIONS\n| && + | http_communication_failure = 1\n| && + | http_invalid_state = 2\n| && + | http_processing_failed = 3\n| && + | http_invalid_timeout = 4\n| && + | OTHERS = 5 ).\n| && + | IF sy-subrc <> 0.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno.\n| && + | ENDIF.\n| && + |\n| && + "receive + | mi_client->receive(\n| && + | EXCEPTIONS\n| && + | http_communication_failure = 1\n| && + | http_invalid_state = 2\n| && + | http_processing_failed = 3\n| && + | OTHERS = 4 ).\n| && + | IF sy-subrc <> 0.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno.\n| && + | ENDIF.\n| && + |\n| && + | IF mi_exit IS BOUND.\n| && + | TRY.\n| && + | mi_exit->after_receive(\n| && + | iv_path = lv_path\n| && + | iv_operation_id = lv_operation_id\n| && + | iv_method = lv_method\n| && + | ii_client = mi_client ).\n| && + | CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ENDIF.\n| && + |\n| && + "Response + | mi_client->response->get_status(\n| && + | IMPORTING\n| && + | code = lv_code\n| && + | reason = lv_reason ).\n\n|. + + IF ls_operation-responses IS NOT INITIAL. + rv_abap = rv_abap && + | CASE lv_code.\n|. + + LOOP AT ls_operation-responses ASSIGNING . + rv_abap = rv_abap && + | WHEN { -code }.\n| && + | return = mi_client->response->get_cdata( ).\n|. + ENDLOOP. + + rv_abap = rv_abap && + | WHEN OTHERS.\n| && + | RAISE EXCEPTION TYPE /iwbep/cx_gateway\n| && + | EXPORTING http_status_code = CONV #( lv_code ).\n| && + | ENDCASE.\n|. + ENDIF. + + rv_abap = rv_abap && + | ENDMETHOD.\n\n|. + ENDIF. + + ENDLOOP. + + rv_abap = rv_abap && |ENDCLASS.|. ENDMETHOD. + METHOD build_clas_client_body. + IF is_operation-body_schema_ref IS INITIAL. + RETURN. + ENDIF. - METHOD run. - DATA lo_parser TYPE REF TO zcl_oapi_parser. - DATA lo_references TYPE REF TO zcl_oapi_references. + rv_result = + | mi_client->request->set_header_field( name = 'Content-Type' value = 'application/json' ).\n\n| && + | IF mi_exit IS BOUND.\n| && + | TRY.\n| && + | lv_body_data = mi_exit->parse_body_to_data(\n| && + | EXPORTING\n| && + | iv_path = lv_path\n| && + | iv_operation_id = lv_operation_id\n| && + | iv_method = lv_method\n| && + | ii_client = mi_client\n| && + | i_body = body ).\n| && + | CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ELSE.\n| && + | lv_body_data = cl_abap_codepage=>convert_to( source = /ui2/cl_json=>serialize( data = body ) ).\n| && + | ENDIF.\n| && + |\n| && + | mi_client->request->set_data( lv_body_data ).\n|. - ms_input = is_input. + ENDMETHOD. - CREATE OBJECT lo_parser. - ms_specification = lo_parser->parse( is_input-openapi_json ). + METHOD build_clas_client_response. + IF is_response-content IS INITIAL. + rv_result = |" todo: no content only code\n|. + RETURN. + ENDIF. + IF lines( is_response-content ) > 1. + rv_result = |" todo: multiple response\n|. + RETURN. + ENDIF. - CREATE OBJECT lo_references. - ms_specification = lo_references->normalize( ms_specification ). + DATA(lo_response_name) = NEW zcl_oapi_response_name( ). + DATA(lv_response_name) = lo_response_name->generate_response_name( + iv_content_type = is_response-content[ 1 ]-type + iv_code = is_response-code ). + rv_result = + | IF mi_exit IS BOUND.\n| && + | TRY.\n| && + | mi_exit->parse_response_to_abap(\n| && + | EXPORTING\n| && + | iv_path = lv_path\n| && + | iv_operation_id = lv_operation_id\n| && + | iv_method = lv_method\n| && + | ii_client = mi_client\n| && + | CHANGING\n| && + | c_data = return-{ lv_response_name } ).\n| && + | CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method ##NO_HANDLER.\n| && + | ENDTRY.\n| && + | ELSE.\n| && + | lv_response_string = mi_client->response->get_cdata( ).\n| && + | /ui2/cl_json=>deserialize(\n| && + | EXPORTING\n| && + | json = lv_response_string\n| && + | CHANGING\n| && + | data = return-{ lv_response_name } ).\n| && + | ENDIF.\n|. - rs_result-clas_icf_serv = build_clas_icf_serv( ). - rs_result-clas_icf_impl = build_clas_icf_impl( ). - rs_result-clas_client = build_clas_client( ). - rs_result-intf = build_intf( ). + ENDMETHOD. + + + METHOD build_clas_icf_impl. + DATA ls_operation LIKE LINE OF ms_specification-operations. + + rv_abap = |CLASS { ms_input-clas_icf_impl } DEFINITION PUBLIC.\n| && + | PUBLIC SECTION.\n| && + | INTERFACES { ms_input-intf }.\n| && + |ENDCLASS.\n\n| && + |CLASS { ms_input-clas_icf_impl } IMPLEMENTATION.\n\n|. + + LOOP AT ms_specification-operations INTO ls_operation. + rv_abap = rv_abap && + | METHOD { ms_input-intf }~{ ls_operation-abap_name }.\n| && + |* Add implementation logic here\n| && + | ENDMETHOD.\n\n|. + ENDLOOP. + + rv_abap = rv_abap && |ENDCLASS.|. ENDMETHOD. @@ -218,70 +602,6 @@ CLASS zcl_oapi_generator_v2 IMPLEMENTATION. ENDMETHOD. - METHOD build_clas_icf_impl. - DATA ls_operation LIKE LINE OF ms_specification-operations. - - rv_abap = |CLASS { ms_input-clas_icf_impl } DEFINITION PUBLIC.\n| && - | PUBLIC SECTION.\n| && - | INTERFACES { ms_input-intf }.\n| && - |ENDCLASS.\n\n| && - |CLASS { ms_input-clas_icf_impl } IMPLEMENTATION.\n\n|. - - LOOP AT ms_specification-operations INTO ls_operation. - rv_abap = rv_abap && - | METHOD { ms_input-intf }~{ ls_operation-abap_name }.\n| && - |* Add implementation logic here\n| && - | ENDMETHOD.\n\n|. - ENDLOOP. - - rv_abap = rv_abap && |ENDCLASS.|. - ENDMETHOD. - - - METHOD build_clas_client. - DATA ls_operation LIKE LINE OF ms_specification-operations. - - rv_abap = |CLASS { ms_input-clas_client } DEFINITION PUBLIC.\n| && - |* Auto generated by https://github.com/abap-openapi/abap-openapi\n| && - | PUBLIC SECTION.\n| && - | INTERFACES { ms_input-intf }.\n| && - | METHODS constructor\n| && - | IMPORTING\n| && - | iv_url TYPE string\n| && - | iv_ssl_id TYPE ssfapplssl OPTIONAL.\n| && - | PROTECTED SECTION.\n| && - | DATA mi_client TYPE REF TO if_http_client.\n| && - |ENDCLASS.\n\n| && - |CLASS { ms_input-clas_client } IMPLEMENTATION.\n| && - | METHOD constructor.\n| && - | cl_http_client=>create_by_url(\n| && - | EXPORTING\n| && - | url = iv_url\n| && - | ssl_id = iv_ssl_id\n| && - | IMPORTING\n| && - | client = mi_client ).\n| && - | ENDMETHOD.\n\n|. - - LOOP AT ms_specification-operations INTO ls_operation. - rv_abap = rv_abap && - | METHOD { ms_input-intf }~{ ls_operation-abap_name }.\n| && - | DATA lv_code TYPE i.\n| && - |\n| && - | mi_client->request->set_method( '{ to_upper( ls_operation-method ) }' ).\n| && - | mi_client->request->set_data( '112233AABBCCDDEEFF' ).\n| && - | mi_client->send( ).\n| && - | mi_client->receive( ).\n| && - |\n| && - | mi_client->response->get_status( IMPORTING code = lv_code ).\n| && - | mi_client->response->get_data( ).\n| && - |* todo\n| && - | ENDMETHOD.\n\n|. - ENDLOOP. - - rv_abap = rv_abap && |ENDCLASS.|. - ENDMETHOD. - - METHOD build_intf. DATA ls_operation LIKE LINE OF ms_specification-operations. DATA ls_returning TYPE ty_returning. @@ -300,11 +620,22 @@ CLASS zcl_oapi_generator_v2 IMPLEMENTATION. rv_abap = rv_abap && |\n|. LOOP AT ms_specification-operations INTO ls_operation. + ls_returning = find_returning_parameter( ls_operation ). + rv_abap = rv_abap && ls_returning-type && | METHODS { ls_operation-abap_name }{ find_input_parameters( ls_operation ) }{ - ls_returning-abap }\n RAISING\n cx_static_check.\n|. + ls_returning-abap }\n RAISING\n /iwbep/cx_gateway.\n|. + + IF ms_input-add_noparsing = abap_true. + rv_abap = rv_abap && + | METHODS { ls_operation-abap_name }_d| && + find_input_parameters( is_operation = ls_operation iv_no_body_type = abap_true ) && + |\n| && + | RETURNING\n VALUE(return) TYPE string\n| && + | RAISING\n /iwbep/cx_gateway.\n|. + ENDIF. ENDLOOP. rv_abap = rv_abap && |ENDINTERFACE.|. ENDMETHOD. @@ -316,7 +647,9 @@ CLASS zcl_oapi_generator_v2 IMPLEMENTATION. DATA ls_parameter LIKE LINE OF is_operation-parameters. DATA lv_simple_type TYPE string. - LOOP AT is_operation-parameters INTO ls_parameter WHERE in = 'query'. + LOOP AT is_operation-parameters INTO ls_parameter + WHERE in = 'query' + OR in = 'path'. IF ls_parameter-schema->type = 'array'. lv_simple_type = 'string_table'. ELSE. @@ -330,7 +663,11 @@ CLASS zcl_oapi_generator_v2 IMPLEMENTATION. ENDLOOP. IF is_operation-body_schema_ref IS NOT INITIAL. - lv_str = | body TYPE { find_schema( is_operation-body_schema_ref )-abap_name }|. + IF iv_no_body_type = abap_true. + lv_str = | body TYPE string|. + ELSE. + lv_str = | body TYPE { find_schema( is_operation-body_schema_ref )-abap_name }|. + ENDIF. APPEND lv_str TO lt_list. ENDIF. @@ -341,7 +678,6 @@ CLASS zcl_oapi_generator_v2 IMPLEMENTATION. ENDIF. ENDMETHOD. - METHOD find_returning_parameter. DATA ls_response LIKE LINE OF is_operation-responses. DATA ls_content LIKE LINE OF ls_response-content. @@ -382,4 +718,34 @@ CLASS zcl_oapi_generator_v2 IMPLEMENTATION. ENDLOOP. ENDLOOP. ENDMETHOD. + + + METHOD find_schema. + DATA lv_name TYPE string. + + lv_name = iv_name. + + REPLACE FIRST OCCURRENCE OF '#/components/schemas/' IN lv_name WITH ''. + READ TABLE ms_specification-components-schemas + INTO rs_schema WITH KEY name = lv_name. "#EC CI_SUBRC + ENDMETHOD. + + + METHOD run. + DATA lo_parser TYPE REF TO zcl_oapi_parser. + DATA lo_references TYPE REF TO zcl_oapi_references. + + ms_input = is_input. + + CREATE OBJECT lo_parser. + ms_specification = lo_parser->parse( is_input-openapi_json ). + + CREATE OBJECT lo_references. + ms_specification = lo_references->normalize( ms_specification ). + + rs_result-clas_icf_serv = build_clas_icf_serv( ). + rs_result-clas_icf_impl = build_clas_icf_impl( ). + rs_result-clas_client = build_clas_client( ). + rs_result-intf = build_intf( ). + ENDMETHOD. ENDCLASS.