Skip to content

Commit

Permalink
Api shape unification (#19)
Browse files Browse the repository at this point in the history
* sub_section for json

Rethink of split_path: Split is the method to create a path+name that can be found in table.
So the previous logic, that treated ending / and a delimiter does not make sense. I had a feeling that it was wrong, now I know. So now: /a/b/ results in '/a/' + 'b', and / results in '' + '' which is existing root element !
This however allows acessing attrs with '/' at the end of the path - like '/value/'. Maybe this is not good. But if needed this can be guarded in `get_item` instead of `split_path`

* change ping to GET

* support new api shape for check_object

* linter fixes

* more linter fixes

* linter ... mmmm

* get the linter fix back to original

* Update zcl_abaplint_json_reader.clas.abap

* Update zcl_abaplint_json_reader.clas.abap

Co-authored-by: Lars Hvam <[email protected]>
  • Loading branch information
sbcgua and larshp authored Apr 27, 2020
1 parent cfb47fe commit 14ed1de
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 43 deletions.
67 changes: 57 additions & 10 deletions src/zcl_abaplint_backend.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,20 @@ CLASS zcl_abaplint_backend DEFINITION
!iv_object_name TYPE sobj_name
RETURNING
VALUE(rv_files) TYPE string .
METHODS send_get
IMPORTING
!ii_client TYPE REF TO if_http_client
RAISING
zcx_abaplint_error .
METHODS send_post
IMPORTING
!ii_client TYPE REF TO if_http_client
RAISING
zcx_abaplint_error .
METHODS send
IMPORTING
!ii_client TYPE REF TO if_http_client
!iv_method TYPE string
RAISING
zcx_abaplint_error .
METHODS create_client
Expand Down Expand Up @@ -194,14 +205,28 @@ CLASS ZCL_ABAPLINT_BACKEND IMPLEMENTATION.

li_client->request->set_cdata( lv_cdata ).

send( li_client ).
send_post( li_client ).

DATA lv_response TYPE string.
lv_response = li_client->response->get_cdata( ).

DATA li_reader TYPE REF TO zif_abaplint_json_reader.
li_reader = zcl_abaplint_json_reader=>parse( lv_response ).

IF li_reader->exists( '/success' ) = abap_false.
RAISE EXCEPTION TYPE zcx_abaplint_error
EXPORTING
message = |Unexpected API response shape|.
ENDIF.

IF li_reader->value_integer( '/success' ) <> 1.
RAISE EXCEPTION TYPE zcx_abaplint_error
EXPORTING
message = |API request failed: { li_reader->value_string( '/error/message' ) }|.
ENDIF.

li_reader = li_reader->sub_section( '/payload' ).

DATA lt_issues TYPE string_table.
DATA lv_issue LIKE LINE OF lt_issues.
DATA lv_prefix TYPE string.
Expand Down Expand Up @@ -280,7 +305,7 @@ CLASS ZCL_ABAPLINT_BACKEND IMPLEMENTATION.

DATA lx_error TYPE REF TO zcx_abaplint_error.
TRY.
send( li_client ).
send_get( li_client ).
rs_message-message = li_client->response->get_cdata( ).
rs_message-error = abap_false.
CATCH zcx_abaplint_error INTO lx_error.
Expand All @@ -295,21 +320,29 @@ CLASS ZCL_ABAPLINT_BACKEND IMPLEMENTATION.

METHOD send.

ii_client->request->set_method( iv_method ).
ii_client->request->set_header_field(
name = 'content-type'
value = 'application/json' ).
ii_client->request->set_header_field(
name = '~request_method'
value = 'POST' ).

ii_client->send( timeout = 6000 ).

ii_client->receive(
ii_client->send(
EXPORTING
timeout = 6000
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4 ).
http_invalid_timeout = 4
OTHERS = 5 ).
IF sy-subrc = 0.
ii_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4 ).
ENDIF.

IF sy-subrc <> 0.
DATA lv_ecode TYPE i.
DATA lv_emessage TYPE string.
Expand All @@ -329,7 +362,7 @@ CLASS ZCL_ABAPLINT_BACKEND IMPLEMENTATION.
IMPORTING
code = lv_scode
reason = lv_sreason ).
IF lv_scode <> 200.
IF lv_scode < 200 OR lv_scode >= 300.
DATA lv_error_response TYPE string.
lv_error_response = ii_client->response->get_cdata( ). " good for debugging

Expand All @@ -339,4 +372,18 @@ CLASS ZCL_ABAPLINT_BACKEND IMPLEMENTATION.
ENDIF.

ENDMETHOD.


METHOD send_get.
send(
ii_client = ii_client
iv_method = if_http_request=>co_request_method_get ).
ENDMETHOD.


METHOD send_post.
send(
ii_client = ii_client
iv_method = if_http_request=>co_request_method_post ).
ENDMETHOD.
ENDCLASS.
71 changes: 50 additions & 21 deletions src/zcl_abaplint_json_reader.clas.abap
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CLASS zcl_abaplint_json_reader DEFINITION
PUBLIC
CREATE PUBLIC .
CREATE PRIVATE .

PUBLIC SECTION.

Expand All @@ -14,12 +14,6 @@ CLASS zcl_abaplint_json_reader DEFINITION
RAISING
zcx_abaplint_error.

METHODS constructor
IMPORTING
iv_json TYPE string
RAISING
zcx_abaplint_error.

PROTECTED SECTION.

PRIVATE SECTION.
Expand Down Expand Up @@ -55,15 +49,6 @@ ENDCLASS.
CLASS ZCL_ABAPLINT_JSON_READER IMPLEMENTATION.


METHOD constructor.

DATA lo_parser TYPE REF TO lcl_json_parser.
CREATE OBJECT lo_parser.
mt_json_tree = lo_parser->parse( iv_json ).

ENDMETHOD.


METHOD get_item.

FIELD-SYMBOLS <item> LIKE LINE OF mt_json_tree.
Expand Down Expand Up @@ -100,23 +85,38 @@ CLASS ZCL_ABAPLINT_JSON_READER IMPLEMENTATION.

METHOD parse.

CREATE OBJECT ro_instance EXPORTING iv_json = iv_json.
DATA lo_parser TYPE REF TO lcl_json_parser.

CREATE OBJECT ro_instance.
CREATE OBJECT lo_parser.
ro_instance->mt_json_tree = lo_parser->parse( iv_json ).

ENDMETHOD.


METHOD split_path.

DATA lv_offs TYPE i.
DATA lv_len TYPE i.
DATA lv_trim_slash TYPE i.

lv_offs = find( val = reverse( iv_path ) sub = '/' ).
lv_len = strlen( iv_path ).
IF lv_len = 0 OR iv_path = '/'.
RETURN. " empty path is the alias for root item = '' + ''
ENDIF.

IF substring( val = iv_path off = lv_len - 1 ) = '/'.
lv_trim_slash = 1. " ignore last '/'
ENDIF.

lv_offs = find( val = reverse( iv_path ) sub = '/' off = lv_trim_slash ).
IF lv_offs = -1.
lv_offs = 0.
lv_offs = lv_len. " treat whole string as the 'name' part
ENDIF.
lv_offs = strlen( iv_path ) - lv_offs.
lv_offs = lv_len - lv_offs.

rv_path_name-path = normalize_path( substring( val = iv_path len = lv_offs ) ).
rv_path_name-name = substring( val = iv_path off = lv_offs ).
rv_path_name-name = substring( val = iv_path off = lv_offs len = lv_len - lv_offs - lv_trim_slash ).

ENDMETHOD.

Expand Down Expand Up @@ -146,6 +146,35 @@ CLASS ZCL_ABAPLINT_JSON_READER IMPLEMENTATION.
ENDMETHOD.


METHOD zif_abaplint_json_reader~sub_section.

DATA lo_section TYPE REF TO zcl_abaplint_json_reader.
DATA ls_item LIKE LINE OF mt_json_tree.
DATA lv_normalized_path TYPE string.
DATA ls_path_parts TYPE ty_path_name.
DATA lv_path_len TYPE i.

CREATE OBJECT lo_section.
lv_normalized_path = normalize_path( iv_path ).
lv_path_len = strlen( lv_normalized_path ).
ls_path_parts = split_path( lv_normalized_path ).

LOOP AT mt_json_tree INTO ls_item.
IF strlen( ls_item-path ) >= lv_path_len
AND substring( val = ls_item-path len = lv_path_len ) = lv_normalized_path.
ls_item-path = substring( val = ls_item-path off = lv_path_len - 1 ). " less closing '/'
INSERT ls_item INTO TABLE lo_section->mt_json_tree.
ELSEIF ls_item-path = ls_path_parts-path AND ls_item-name = ls_path_parts-name.
CLEAR: ls_item-path, ls_item-name. " this becomes a new root
INSERT ls_item INTO TABLE lo_section->mt_json_tree.
ENDIF.
ENDLOOP.

ri_json = lo_section.

ENDMETHOD.


METHOD zif_abaplint_json_reader~value.

DATA lv_item TYPE REF TO zif_abaplint_json_reader=>ty_node.
Expand Down
Loading

0 comments on commit 14ed1de

Please sign in to comment.