diff --git a/src/01/00/01/z2ui5_cl_ajson.clas.locals_imp.abap b/src/01/00/01/z2ui5_cl_ajson.clas.locals_imp.abap index 40a21a2b..b06d4458 100644 --- a/src/01/00/01/z2ui5_cl_ajson.clas.locals_imp.abap +++ b/src/01/00/01/z2ui5_cl_ajson.clas.locals_imp.abap @@ -2,596 +2,596 @@ * UTILS ********************************************************************** -interface lif_kind. +INTERFACE lif_kind. - types ty_kind type c length 1. + TYPES ty_kind TYPE c LENGTH 1. - constants: - any type ty_kind value cl_abap_typedescr=>typekind_any, - date type ty_kind value cl_abap_typedescr=>typekind_date, - time type ty_kind value cl_abap_typedescr=>typekind_time, - packed type ty_kind value cl_abap_typedescr=>typekind_packed, - table type ty_kind value cl_abap_typedescr=>typekind_table, - struct_flat type ty_kind value cl_abap_typedescr=>typekind_struct1, - struct_deep type ty_kind value cl_abap_typedescr=>typekind_struct2, - data_ref type ty_kind value cl_abap_typedescr=>typekind_dref, - object_ref type ty_kind value cl_abap_typedescr=>typekind_oref, - enum type ty_kind value 'k'. " cl_abap_typedescr=>typekind_enum not in lower releases + CONSTANTS: + any TYPE ty_kind VALUE cl_abap_typedescr=>typekind_any, + date TYPE ty_kind VALUE cl_abap_typedescr=>typekind_date, + time TYPE ty_kind VALUE cl_abap_typedescr=>typekind_time, + packed TYPE ty_kind VALUE cl_abap_typedescr=>typekind_packed, + table TYPE ty_kind VALUE cl_abap_typedescr=>typekind_table, + struct_flat TYPE ty_kind VALUE cl_abap_typedescr=>typekind_struct1, + struct_deep TYPE ty_kind VALUE cl_abap_typedescr=>typekind_struct2, + data_ref TYPE ty_kind VALUE cl_abap_typedescr=>typekind_dref, + object_ref TYPE ty_kind VALUE cl_abap_typedescr=>typekind_oref, + enum TYPE ty_kind VALUE 'k'. " cl_abap_typedescr=>typekind_enum not in lower releases - constants: - begin of numeric, - int1 type ty_kind value cl_abap_tabledescr=>typekind_int1, - int2 type ty_kind value cl_abap_tabledescr=>typekind_int2, - int4 type ty_kind value cl_abap_tabledescr=>typekind_int, - int8 type ty_kind value '8', " cl_abap_tabledescr=>typekind_int8 not in lower releases - float type ty_kind value cl_abap_tabledescr=>typekind_float, - packed type ty_kind value cl_abap_tabledescr=>typekind_packed, - decfloat16 type ty_kind value cl_abap_tabledescr=>typekind_decfloat16, - decfloat34 type ty_kind value cl_abap_tabledescr=>typekind_decfloat34, - end of numeric. + CONSTANTS: + BEGIN OF numeric, + int1 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_int1, + int2 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_int2, + int4 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_int, + int8 TYPE ty_kind VALUE '8', " cl_abap_tabledescr=>typekind_int8 not in lower releases + float TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_float, + packed TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_packed, + decfloat16 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_decfloat16, + decfloat34 TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_decfloat34, + END OF numeric. - constants: - begin of texts, - char type ty_kind value cl_abap_tabledescr=>typekind_char, - numc type ty_kind value cl_abap_tabledescr=>typekind_num, - string type ty_kind value cl_abap_tabledescr=>typekind_string, - end of texts. + CONSTANTS: + BEGIN OF texts, + char TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_char, + numc TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_num, + string TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_string, + END OF texts. - constants: - begin of binary, - hex type ty_kind value cl_abap_tabledescr=>typekind_hex, - xstring type ty_kind value cl_abap_tabledescr=>typekind_xstring, - end of binary. + CONSTANTS: + BEGIN OF binary, + hex TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_hex, + xstring TYPE ty_kind VALUE cl_abap_tabledescr=>typekind_xstring, + END OF binary. - constants: - begin of deep_targets, - table type ty_kind value cl_abap_typedescr=>typekind_table, - struct_flat type ty_kind value cl_abap_typedescr=>typekind_struct1, - struct_deep type ty_kind value cl_abap_typedescr=>typekind_struct2, - data_ref type ty_kind value cl_abap_typedescr=>typekind_dref, - object_ref type ty_kind value cl_abap_typedescr=>typekind_oref, - end of deep_targets. + CONSTANTS: + BEGIN OF deep_targets, + table TYPE ty_kind VALUE cl_abap_typedescr=>typekind_table, + struct_flat TYPE ty_kind VALUE cl_abap_typedescr=>typekind_struct1, + struct_deep TYPE ty_kind VALUE cl_abap_typedescr=>typekind_struct2, + data_ref TYPE ty_kind VALUE cl_abap_typedescr=>typekind_dref, + object_ref TYPE ty_kind VALUE cl_abap_typedescr=>typekind_oref, + END OF deep_targets. -endinterface. +ENDINTERFACE. -class lcl_utils definition final. - public section. +CLASS lcl_utils DEFINITION FINAL. + PUBLIC SECTION. - class-methods normalize_path - importing - iv_path type string - returning - value(rv_path) type string. - class-methods split_path - importing - iv_path type string - returning - value(rv_path_name) type z2ui5_if_ajson_types=>ty_path_name. - class-methods validate_array_index - importing - iv_path type string - iv_index type string - returning - value(rv_index) type i - raising - z2UI5_cx_ajson_error. - class-methods string_to_xstring_utf8 - importing - iv_str type string - returning - value(rv_xstr) type xstring. + CLASS-METHODS normalize_path + IMPORTING + iv_path TYPE string + RETURNING + VALUE(rv_path) TYPE string. + CLASS-METHODS split_path + IMPORTING + iv_path TYPE string + RETURNING + VALUE(rv_path_name) TYPE z2ui5_if_ajson_types=>ty_path_name. + CLASS-METHODS validate_array_index + IMPORTING + iv_path TYPE string + iv_index TYPE string + RETURNING + VALUE(rv_index) TYPE i + RAISING + z2ui5_cx_ajson_error. + CLASS-METHODS string_to_xstring_utf8 + IMPORTING + iv_str TYPE string + RETURNING + VALUE(rv_xstr) TYPE xstring. -endclass. +ENDCLASS. -class lcl_utils implementation. +CLASS lcl_utils IMPLEMENTATION. - method string_to_xstring_utf8. + METHOD string_to_xstring_utf8. - data lo_conv type ref to object. - data lv_out_ce type string. + DATA lo_conv TYPE REF TO object. + DATA lv_out_ce TYPE string. lv_out_ce = 'CL_ABAP_CONV_OUT_CE'. - try. - call method ('CL_ABAP_CONV_CODEPAGE')=>create_out - receiving - instance = lo_conv. - call method lo_conv->('IF_ABAP_CONV_OUT~CONVERT') - exporting - source = iv_str - receiving - result = rv_xstr. - catch cx_sy_dyn_call_illegal_class. - call method (lv_out_ce)=>create - exporting - encoding = 'UTF-8' - receiving - conv = lo_conv. - call method lo_conv->('CONVERT') - exporting - data = iv_str - importing - buffer = rv_xstr. - endtry. + TRY. + CALL METHOD ('CL_ABAP_CONV_CODEPAGE')=>create_out + RECEIVING + instance = lo_conv. + CALL METHOD lo_conv->('IF_ABAP_CONV_OUT~CONVERT') + EXPORTING + source = iv_str + RECEIVING + result = rv_xstr. + CATCH cx_sy_dyn_call_illegal_class. + CALL METHOD (lv_out_ce)=>create + EXPORTING + encoding = 'UTF-8' + RECEIVING + conv = lo_conv. + CALL METHOD lo_conv->('CONVERT') + EXPORTING + data = iv_str + IMPORTING + buffer = rv_xstr. + ENDTRY. - endmethod. + ENDMETHOD. - method validate_array_index. + METHOD validate_array_index. - if not iv_index co '0123456789'. - z2UI5_cx_ajson_error=>raise( |Cannot add non-numeric key [{ iv_index }] to array [{ iv_path }]| ). - endif. + IF NOT iv_index CO '0123456789'. + z2ui5_cx_ajson_error=>raise( |Cannot add non-numeric key [{ iv_index }] to array [{ iv_path }]| ). + ENDIF. rv_index = iv_index. - if rv_index = 0. - z2UI5_cx_ajson_error=>raise( |Cannot add zero key to array [{ iv_path }]| ). - endif. + IF rv_index = 0. + z2ui5_cx_ajson_error=>raise( |Cannot add zero key to array [{ iv_path }]| ). + ENDIF. - endmethod. + ENDMETHOD. - method normalize_path. + METHOD normalize_path. rv_path = iv_path. - if strlen( rv_path ) = 0. + IF strlen( rv_path ) = 0. rv_path = '/'. - endif. - if rv_path+0(1) <> '/'. + ENDIF. + IF rv_path+0(1) <> '/'. rv_path = '/' && rv_path. - endif. - if substring( val = rv_path off = strlen( rv_path ) - 1 ) <> '/'. + ENDIF. + IF substring( val = rv_path off = strlen( rv_path ) - 1 ) <> '/'. rv_path = rv_path && '/'. - endif. + ENDIF. - endmethod. + ENDMETHOD. - method split_path. + METHOD split_path. - data lv_offs type i. - data lv_len type i. - data lv_trim_slash type i. + DATA lv_offs TYPE i. + DATA lv_len TYPE i. + DATA lv_trim_slash TYPE i. lv_len = strlen( iv_path ). - if lv_len = 0 or iv_path = '/'. - return. " empty path is the alias for root item = '' + '' - endif. + 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 ) = '/'. + IF substring( val = iv_path off = lv_len - 1 ) = '/'. lv_trim_slash = 1. " ignore last '/' - endif. + ENDIF. lv_offs = find( val = reverse( iv_path ) sub = '/' off = lv_trim_slash ). - if lv_offs = -1. + IF lv_offs = -1. lv_offs = lv_len. " treat whole string as the 'name' part - endif. + ENDIF. 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 len = lv_len - lv_offs - lv_trim_slash ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * PARSER ********************************************************************** -class lcl_json_parser definition final. - public section. +CLASS lcl_json_parser DEFINITION FINAL. + PUBLIC SECTION. - methods parse - importing - iv_json type string - iv_keep_item_order type abap_bool default abap_false - returning - value(rt_json_tree) type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS parse + IMPORTING + iv_json TYPE string + iv_keep_item_order TYPE abap_bool DEFAULT abap_false + RETURNING + VALUE(rt_json_tree) TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - private section. + PRIVATE SECTION. - types: - ty_stack_tt type standard table of ref to z2ui5_if_ajson_types=>ty_node. + TYPES: + ty_stack_tt TYPE STANDARD TABLE OF REF TO z2ui5_if_ajson_types=>ty_node. - data mt_stack type ty_stack_tt. - data mv_stack_path type string. - data mv_keep_item_order type abap_bool. + DATA mt_stack TYPE ty_stack_tt. + DATA mv_stack_path TYPE string. + DATA mv_keep_item_order TYPE abap_bool. - methods raise - importing - iv_error type string - raising - z2UI5_cx_ajson_error. + METHODS raise + IMPORTING + iv_error TYPE string + RAISING + z2ui5_cx_ajson_error. - methods _parse - importing - iv_json type string - returning - value(rt_json_tree) type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error cx_dynamic_check. " cx_sxml_error is not released on Steampunk #153 + METHODS _parse + IMPORTING + iv_json TYPE string + RETURNING + VALUE(rt_json_tree) TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error cx_dynamic_check. " cx_sxml_error is not released on Steampunk #153 - methods _get_location - importing - iv_json type string - iv_offset type i - returning - value(rv_location) type string. + METHODS _get_location + IMPORTING + iv_json TYPE string + iv_offset TYPE i + RETURNING + VALUE(rv_location) TYPE string. -endclass. +ENDCLASS. -class lcl_json_parser implementation. +CLASS lcl_json_parser IMPLEMENTATION. - method parse. - data lx_sxml_parse type ref to cx_sxml_parse_error. - data lx_sxml type ref to cx_dynamic_check. - data lv_location type string. + METHOD parse. + DATA lx_sxml_parse TYPE REF TO cx_sxml_parse_error. + DATA lx_sxml TYPE REF TO cx_dynamic_check. + DATA lv_location TYPE string. mv_keep_item_order = iv_keep_item_order. - try. - " TODO sane JSON check: - " JSON can be true,false,null,(-)digits - " or start from " or from { - rt_json_tree = _parse( iv_json ). - catch cx_sxml_parse_error into lx_sxml_parse. - lv_location = _get_location( - iv_json = iv_json - iv_offset = lx_sxml_parse->xml_offset ). - z2UI5_cx_ajson_error=>raise( - iv_msg = |Json parsing error (SXML): { lx_sxml_parse->get_text( ) }| - iv_location = lv_location ). - catch cx_dynamic_check into lx_sxml. " cx_sxml_error - z2UI5_cx_ajson_error=>raise( - iv_msg = |Json parsing error (SXML): { lx_sxml->get_text( ) }| - iv_location = '@PARSER' ). - endtry. + TRY. + " TODO sane JSON check: + " JSON can be true,false,null,(-)digits + " or start from " or from { + rt_json_tree = _parse( iv_json ). + CATCH cx_sxml_parse_error INTO lx_sxml_parse. + lv_location = _get_location( + iv_json = iv_json + iv_offset = lx_sxml_parse->xml_offset ). + z2ui5_cx_ajson_error=>raise( + iv_msg = |Json parsing error (SXML): { lx_sxml_parse->get_text( ) }| + iv_location = lv_location ). + CATCH cx_dynamic_check INTO lx_sxml. " cx_sxml_error + z2ui5_cx_ajson_error=>raise( + iv_msg = |Json parsing error (SXML): { lx_sxml->get_text( ) }| + iv_location = '@PARSER' ). + ENDTRY. - endmethod. + ENDMETHOD. - method _get_location. + METHOD _get_location. - data lv_json type string. - data lv_offset type i. - data lt_text type table of string. - data lv_text type string. - data lv_line type i. - data lv_pos type i. + DATA lv_json TYPE string. + DATA lv_offset TYPE i. + DATA lt_text TYPE TABLE OF string. + DATA lv_text TYPE string. + DATA lv_line TYPE i. + DATA lv_pos TYPE i. lv_offset = iv_offset. - if lv_offset < 0. + IF lv_offset < 0. lv_offset = 0. - endif. - if lv_offset > strlen( iv_json ). + ENDIF. + IF lv_offset > strlen( iv_json ). lv_offset = strlen( iv_json ). - endif. + ENDIF. lv_json = iv_json(lv_offset). - replace all occurrences of cl_abap_char_utilities=>cr_lf - in lv_json with cl_abap_char_utilities=>newline. + REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf + IN lv_json WITH cl_abap_char_utilities=>newline. - split lv_json at cl_abap_char_utilities=>newline into table lt_text. + SPLIT lv_json AT cl_abap_char_utilities=>newline INTO TABLE lt_text. lv_line = lines( lt_text ). - if lv_line = 0. + IF lv_line = 0. lv_line = 1. lv_pos = 1. - else. - read table lt_text index lv_line into lv_text. + ELSE. + READ TABLE lt_text INDEX lv_line INTO lv_text. lv_pos = strlen( lv_text ) + 1. - endif. + ENDIF. rv_location = |Line { lv_line }, Offset { lv_pos }|. - endmethod. + ENDMETHOD. - method _parse. + METHOD _parse. - data lo_reader type ref to if_sxml_reader. - data lr_stack_top like line of mt_stack. - data lo_node type ref to if_sxml_node. - field-symbols like line of rt_json_tree. + DATA lo_reader TYPE REF TO if_sxml_reader. + DATA lr_stack_top LIKE LINE OF mt_stack. + DATA lo_node TYPE REF TO if_sxml_node. + FIELD-SYMBOLS LIKE LINE OF rt_json_tree. - clear mt_stack. - clear mv_stack_path. - if iv_json is initial. - return. - endif. + CLEAR mt_stack. + CLEAR mv_stack_path. + IF iv_json IS INITIAL. + RETURN. + ENDIF. lo_reader = cl_sxml_string_reader=>create( lcl_utils=>string_to_xstring_utf8( iv_json ) ). " TODO: self protection, check non-empty, check starting from object ... - do. + DO. lo_node = lo_reader->read_next_node( ). - if lo_node is not bound. - exit. - endif. + IF lo_node IS NOT BOUND. + EXIT. + ENDIF. - case lo_node->type. - when if_sxml_node=>co_nt_element_open. - data lt_attributes type if_sxml_attribute=>attributes. - data lo_attr like line of lt_attributes. - data lo_open type ref to if_sxml_open_element. + CASE lo_node->type. + WHEN if_sxml_node=>co_nt_element_open. + DATA lt_attributes TYPE if_sxml_attribute=>attributes. + DATA lo_attr LIKE LINE OF lt_attributes. + DATA lo_open TYPE REF TO if_sxml_open_element. lo_open ?= lo_node. - append initial line to rt_json_tree assigning . + APPEND INITIAL LINE TO rt_json_tree ASSIGNING . -type = lo_open->qname-name. - read table mt_stack index 1 into lr_stack_top. - if sy-subrc = 0. + READ TABLE mt_stack INDEX 1 INTO lr_stack_top. + IF sy-subrc = 0. " Using string is faster than rebuilding path from stack -path = mv_stack_path. lr_stack_top->children = lr_stack_top->children + 1. - if lr_stack_top->type = `array`. " This is parser type not ajson type + IF lr_stack_top->type = `array`. " This is parser type not ajson type -name = |{ lr_stack_top->children }|. -index = lr_stack_top->children. - else. + ELSE. lt_attributes = lo_open->get_attributes( ). - loop at lt_attributes into lo_attr. - if lo_attr->qname-name = 'name' and lo_attr->value_type = if_sxml_value=>co_vt_text. + LOOP AT lt_attributes INTO lo_attr. + IF lo_attr->qname-name = 'name' AND lo_attr->value_type = if_sxml_value=>co_vt_text. -name = lo_attr->get_value( ). - endif. - endloop. - if mv_keep_item_order = abap_true. + ENDIF. + ENDLOOP. + IF mv_keep_item_order = abap_true. -order = lr_stack_top->children. - endif. - endif. - if -name is initial. + ENDIF. + ENDIF. + IF -name IS INITIAL. raise( 'Node without name (maybe not JSON)' ). - endif. - endif. + ENDIF. + ENDIF. - get reference of into lr_stack_top. - insert lr_stack_top into mt_stack index 1. + GET REFERENCE OF INTO lr_stack_top. + INSERT lr_stack_top INTO mt_stack INDEX 1. " add path component mv_stack_path = mv_stack_path && -name && '/'. - when if_sxml_node=>co_nt_element_close. - data lo_close type ref to if_sxml_close_element. + WHEN if_sxml_node=>co_nt_element_close. + DATA lo_close TYPE REF TO if_sxml_close_element. lo_close ?= lo_node. - read table mt_stack index 1 into lr_stack_top. - delete mt_stack index 1. - if lo_close->qname-name <> lr_stack_top->type. + READ TABLE mt_stack INDEX 1 INTO lr_stack_top. + DELETE mt_stack INDEX 1. + IF lo_close->qname-name <> lr_stack_top->type. raise( 'Unexpected closing node type' ). - endif. + ENDIF. " remove last path component mv_stack_path = substring( val = mv_stack_path len = find( val = mv_stack_path sub = '/' occ = -2 ) + 1 ). - when if_sxml_node=>co_nt_value. - data lo_value type ref to if_sxml_value_node. + WHEN if_sxml_node=>co_nt_value. + DATA lo_value TYPE REF TO if_sxml_value_node. lo_value ?= lo_node. -value = lo_value->get_value( ). - when others. + WHEN OTHERS. raise( 'Unexpected node type' ). - endcase. - enddo. + ENDCASE. + ENDDO. - if lines( mt_stack ) > 0. + IF lines( mt_stack ) > 0. raise( 'Unexpected end of data' ). - endif. + ENDIF. - endmethod. + ENDMETHOD. - method raise. + METHOD raise. - z2UI5_cx_ajson_error=>raise( + z2ui5_cx_ajson_error=>raise( iv_location = mv_stack_path iv_msg = |JSON PARSER: { iv_error } @ { mv_stack_path }| ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * SERIALIZER ********************************************************************** -class lcl_json_serializer definition final create private. - public section. +CLASS lcl_json_serializer DEFINITION FINAL CREATE PRIVATE. + PUBLIC SECTION. - class-methods stringify - importing - it_json_tree type z2ui5_if_ajson_types=>ty_nodes_ts - iv_indent type i default 0 - iv_keep_item_order type abap_bool default abap_false - returning - value(rv_json_string) type string - raising - z2UI5_cx_ajson_error. + CLASS-METHODS stringify + IMPORTING + it_json_tree TYPE z2ui5_if_ajson_types=>ty_nodes_ts + iv_indent TYPE i DEFAULT 0 + iv_keep_item_order TYPE abap_bool DEFAULT abap_false + RETURNING + VALUE(rv_json_string) TYPE string + RAISING + z2ui5_cx_ajson_error. - class-methods class_constructor. + CLASS-METHODS class_constructor. - private section. + PRIVATE SECTION. - class-data gv_comma_with_lf type string. + CLASS-DATA gv_comma_with_lf TYPE string. - data mt_json_tree type z2ui5_if_ajson_types=>ty_nodes_ts. - data mv_keep_item_order type abap_bool. - data mt_buffer type string_table. - data mv_indent_step type i. - data mv_level type i. + DATA mt_json_tree TYPE z2ui5_if_ajson_types=>ty_nodes_ts. + DATA mv_keep_item_order TYPE abap_bool. + DATA mt_buffer TYPE string_table. + DATA mv_indent_step TYPE i. + DATA mv_level TYPE i. - class-methods escape_string - importing - iv_unescaped type string - returning - value(rv_escaped) type string. + CLASS-METHODS escape_string + IMPORTING + iv_unescaped TYPE string + RETURNING + VALUE(rv_escaped) TYPE string. - methods _stringify - returning - value(rv_json_string) type string - raising - z2UI5_cx_ajson_error. + METHODS _stringify + RETURNING + VALUE(rv_json_string) TYPE string + RAISING + z2ui5_cx_ajson_error. - methods stringify_node - importing - is_node type z2ui5_if_ajson_types=>ty_node - raising - z2UI5_cx_ajson_error. + METHODS stringify_node + IMPORTING + is_node TYPE z2ui5_if_ajson_types=>ty_node + RAISING + z2ui5_cx_ajson_error. - methods stringify_set - importing - iv_parent_path type string - iv_array type abap_bool - raising - z2UI5_cx_ajson_error. + METHODS stringify_set + IMPORTING + iv_parent_path TYPE string + iv_array TYPE abap_bool + RAISING + z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class lcl_json_serializer implementation. +CLASS lcl_json_serializer IMPLEMENTATION. - method class_constructor. + METHOD class_constructor. gv_comma_with_lf = ',' && cl_abap_char_utilities=>newline. - endmethod. + ENDMETHOD. - method stringify. + METHOD stringify. - data lo type ref to lcl_json_serializer. - create object lo. + DATA lo TYPE REF TO lcl_json_serializer. + CREATE OBJECT lo. lo->mt_json_tree = it_json_tree. lo->mv_indent_step = iv_indent. lo->mv_keep_item_order = iv_keep_item_order. rv_json_string = lo->_stringify( ). - endmethod. + ENDMETHOD. - method _stringify. + METHOD _stringify. - field-symbols like line of mt_json_tree. - read table mt_json_tree assigning - with key + FIELD-SYMBOLS LIKE LINE OF mt_json_tree. + READ TABLE mt_json_tree ASSIGNING + WITH KEY path = '' name = ''. " Root - if sy-subrc <> 0. - return. - endif. + IF sy-subrc <> 0. + RETURN. + ENDIF. stringify_node( ). rv_json_string = concat_lines_of( table = mt_buffer ). - endmethod. + ENDMETHOD. - method stringify_node. + METHOD stringify_node. - data lv_item type string. - data lv_indent_prefix type string. + DATA lv_item TYPE string. + DATA lv_indent_prefix TYPE string. - if mv_indent_step > 0. + IF mv_indent_step > 0. lv_indent_prefix = repeat( val = ` ` occ = mv_indent_step * mv_level ). lv_item = lv_indent_prefix. - endif. + ENDIF. - if is_node-name is not initial and is_node-index is initial. " Not root, not array item - if mv_indent_step > 0. + IF is_node-name IS NOT INITIAL AND is_node-index IS INITIAL. " Not root, not array item + IF mv_indent_step > 0. lv_item = lv_item && |"{ is_node-name }": |. - else. + ELSE. lv_item = |"{ is_node-name }":|. - endif. - endif. + ENDIF. + ENDIF. - case is_node-type. - when z2ui5_if_ajson_types=>node_type-array. + CASE is_node-type. + WHEN z2ui5_if_ajson_types=>node_type-array. lv_item = lv_item && '['. - when z2ui5_if_ajson_types=>node_type-object. + WHEN z2ui5_if_ajson_types=>node_type-object. lv_item = lv_item && '{'. - when z2ui5_if_ajson_types=>node_type-string. + WHEN z2ui5_if_ajson_types=>node_type-string. lv_item = lv_item && |"{ escape_string( is_node-value ) }"|. - when z2ui5_if_ajson_types=>node_type-boolean or z2ui5_if_ajson_types=>node_type-number. + WHEN z2ui5_if_ajson_types=>node_type-boolean OR z2ui5_if_ajson_types=>node_type-number. lv_item = lv_item && is_node-value. - when z2ui5_if_ajson_types=>node_type-null. + WHEN z2ui5_if_ajson_types=>node_type-null. lv_item = lv_item && 'null'. - when others. - z2UI5_cx_ajson_error=>raise( + WHEN OTHERS. + z2ui5_cx_ajson_error=>raise( iv_msg = |Unexpected type [{ is_node-type }]| iv_location = is_node-path && is_node-name ). - endcase. + ENDCASE. - if mv_indent_step > 0 - and ( is_node-type = z2ui5_if_ajson_types=>node_type-array or is_node-type = z2ui5_if_ajson_types=>node_type-object ) - and is_node-children > 0. + IF mv_indent_step > 0 + AND ( is_node-type = z2ui5_if_ajson_types=>node_type-array OR is_node-type = z2ui5_if_ajson_types=>node_type-object ) + AND is_node-children > 0. mv_level = mv_level + 1. lv_item = lv_item && cl_abap_char_utilities=>newline. - endif. + ENDIF. - append lv_item to mt_buffer. + APPEND lv_item TO mt_buffer. " finish complex item - if is_node-type = z2ui5_if_ajson_types=>node_type-array or is_node-type = z2ui5_if_ajson_types=>node_type-object. - data lv_children_path type string. - data lv_tail type string. + IF is_node-type = z2ui5_if_ajson_types=>node_type-array OR is_node-type = z2ui5_if_ajson_types=>node_type-object. + DATA lv_children_path TYPE string. + DATA lv_tail TYPE string. lv_children_path = is_node-path && is_node-name && '/'. " for root: path = '' and name = '', so result is '/' - case is_node-type. - when z2ui5_if_ajson_types=>node_type-array. - if is_node-children > 0. + CASE is_node-type. + WHEN z2ui5_if_ajson_types=>node_type-array. + IF is_node-children > 0. stringify_set( iv_parent_path = lv_children_path iv_array = abap_true ). - endif. + ENDIF. lv_tail = ']'. - when z2ui5_if_ajson_types=>node_type-object. - if is_node-children > 0. + WHEN z2ui5_if_ajson_types=>node_type-object. + IF is_node-children > 0. stringify_set( iv_parent_path = lv_children_path iv_array = abap_false ). - endif. + ENDIF. lv_tail = '}'. - endcase. + ENDCASE. - if mv_indent_step > 0 and is_node-children > 0. + IF mv_indent_step > 0 AND is_node-children > 0. lv_tail = lv_indent_prefix && lv_tail. mv_level = mv_level - 1. - endif. - append lv_tail to mt_buffer. - endif. + ENDIF. + APPEND lv_tail TO mt_buffer. + ENDIF. - endmethod. + ENDMETHOD. - method stringify_set. + METHOD stringify_set. - data lv_tab_key type string. - data lv_first_done type abap_bool. - field-symbols like line of mt_json_tree. + DATA lv_tab_key TYPE string. + DATA lv_first_done TYPE abap_bool. + FIELD-SYMBOLS LIKE LINE OF mt_json_tree. - if iv_array = abap_true. + IF iv_array = abap_true. lv_tab_key = 'array_index'. " path + index - elseif mv_keep_item_order = abap_true. + ELSEIF mv_keep_item_order = abap_true. lv_tab_key = 'item_order'. " path + order - else. + ELSE. lv_tab_key = 'primary_key'. " path + name - endif. + ENDIF. - loop at mt_json_tree assigning using key (lv_tab_key) where path = iv_parent_path. - if lv_first_done = abap_false. + LOOP AT mt_json_tree ASSIGNING USING KEY (lv_tab_key) WHERE path = iv_parent_path. + IF lv_first_done = abap_false. lv_first_done = abap_true. - elseif mv_indent_step > 0. - append gv_comma_with_lf to mt_buffer. - else. - append ',' to mt_buffer. - endif. + ELSEIF mv_indent_step > 0. + APPEND gv_comma_with_lf TO mt_buffer. + ELSE. + APPEND ',' TO mt_buffer. + ENDIF. stringify_node( ). - endloop. + ENDLOOP. - if mv_indent_step > 0 and lv_first_done = abap_true. " only of items were in the list - append cl_abap_char_utilities=>newline to mt_buffer. - endif. + IF mv_indent_step > 0 AND lv_first_done = abap_true. " only of items were in the list + APPEND cl_abap_char_utilities=>newline TO mt_buffer. + ENDIF. - endmethod. + ENDMETHOD. - method escape_string. + METHOD escape_string. rv_escaped = iv_unescaped. - if rv_escaped ca |"\\\t\n\r|. + IF rv_escaped CA |"\\\t\n\r|. " TODO consider performance ... " see also https://www.json.org/json-en.html rv_escaped = replace( @@ -620,110 +620,118 @@ class lcl_json_serializer implementation. with = '\"' occ = 0 ). - endif. + ENDIF. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * JSON_TO_ABAP ********************************************************************** -class lcl_json_to_abap definition final. - public section. +CLASS lcl_json_to_abap DEFINITION FINAL. + PUBLIC SECTION. - methods constructor - importing - !iv_corresponding type abap_bool default abap_false - !ii_custom_mapping type ref to z2ui5_if_ajson_mapping optional. + METHODS constructor + IMPORTING + !iv_corresponding TYPE abap_bool DEFAULT abap_false + !ii_custom_mapping TYPE REF TO z2ui5_if_ajson_mapping OPTIONAL. - methods to_abap - importing - it_nodes type z2ui5_if_ajson_types=>ty_nodes_ts - changing - c_container type any - raising - z2UI5_cx_ajson_error. + METHODS to_abap + IMPORTING + it_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_ts + CHANGING + c_container TYPE any + RAISING + z2ui5_cx_ajson_error. - methods to_timestamp - importing - iv_value type z2ui5_if_ajson_types=>ty_node-value - returning - value(rv_result) type timestamp - raising - z2UI5_cx_ajson_error. + METHODS to_timestamp + IMPORTING + iv_value TYPE z2ui5_if_ajson_types=>ty_node-value + RETURNING + VALUE(rv_result) TYPE timestamp + RAISING + z2ui5_cx_ajson_error. - methods to_date - importing - iv_value type z2ui5_if_ajson_types=>ty_node-value - returning - value(rv_result) type d - raising - z2UI5_cx_ajson_error. + METHODS to_date + IMPORTING + iv_value TYPE z2ui5_if_ajson_types=>ty_node-value + RETURNING + VALUE(rv_result) TYPE d + RAISING + z2ui5_cx_ajson_error. - private section. + METHODS to_time + IMPORTING + iv_value TYPE z2ui5_if_ajson_types=>ty_node-value + RETURNING + VALUE(rv_result) TYPE t + RAISING + z2ui5_cx_ajson_error. - types: - begin of ty_type_cache, - type_path type string, - target_field_name type string, - dd type ref to cl_abap_datadescr, - type_kind like lif_kind=>any, - tab_item_buf type ref to data, - end of ty_type_cache. - data mt_node_type_cache type hashed table of ty_type_cache with unique key type_path. + PRIVATE SECTION. - data mr_nodes type ref to z2ui5_if_ajson_types=>ty_nodes_ts. - data mi_custom_mapping type ref to z2ui5_if_ajson_mapping. - data mv_corresponding type abap_bool. + TYPES: + BEGIN OF ty_type_cache, + type_path TYPE string, + target_field_name TYPE string, + dd TYPE REF TO cl_abap_datadescr, + type_kind LIKE lif_kind=>any, + tab_item_buf TYPE REF TO data, + END OF ty_type_cache. + DATA mt_node_type_cache TYPE HASHED TABLE OF ty_type_cache WITH UNIQUE KEY type_path. - methods any_to_abap - importing - iv_path type string - is_parent_type type ty_type_cache optional - i_container_ref type ref to data - raising - z2UI5_cx_ajson_error. + DATA mr_nodes TYPE REF TO z2ui5_if_ajson_types=>ty_nodes_ts. + DATA mi_custom_mapping TYPE REF TO z2ui5_if_ajson_mapping. + DATA mv_corresponding TYPE abap_bool. - methods value_to_abap - importing - is_node type z2ui5_if_ajson_types=>ty_node - is_node_type type ty_type_cache - i_container_ref type ref to data - raising - z2UI5_cx_ajson_error + METHODS any_to_abap + IMPORTING + iv_path TYPE string + is_parent_type TYPE ty_type_cache OPTIONAL + i_container_ref TYPE REF TO data + RAISING + z2ui5_cx_ajson_error. + + METHODS value_to_abap + IMPORTING + is_node TYPE z2ui5_if_ajson_types=>ty_node + is_node_type TYPE ty_type_cache + i_container_ref TYPE REF TO data + RAISING + z2ui5_cx_ajson_error cx_sy_conversion_no_number. - methods get_node_type - importing - is_node type z2ui5_if_ajson_types=>ty_node optional " Empty for root - is_parent_type type ty_type_cache optional - i_container_ref type ref to data optional - returning - value(rs_node_type) type ty_type_cache - raising - z2UI5_cx_ajson_error. + METHODS get_node_type + IMPORTING + is_node TYPE z2ui5_if_ajson_types=>ty_node OPTIONAL " Empty for root + is_parent_type TYPE ty_type_cache OPTIONAL + i_container_ref TYPE REF TO data OPTIONAL + RETURNING + VALUE(rs_node_type) TYPE ty_type_cache + RAISING + z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class lcl_json_to_abap implementation. +CLASS lcl_json_to_abap IMPLEMENTATION. - method constructor. + METHOD constructor. mi_custom_mapping = ii_custom_mapping. mv_corresponding = iv_corresponding. - endmethod. + ENDMETHOD. - method to_abap. + METHOD to_abap. - data lr_ref type ref to data. + DATA lr_ref TYPE REF TO data. - clear c_container. " what about data/obj refs ? - clear mt_node_type_cache. + CLEAR c_container. " what about data/obj refs ? + CLEAR mt_node_type_cache. - get reference of c_container into lr_ref. - get reference of it_nodes into mr_nodes. + GET REFERENCE OF c_container INTO lr_ref. + GET REFERENCE OF it_nodes INTO mr_nodes. get_node_type( i_container_ref = lr_ref ). " Pre-cache root node type @@ -731,656 +739,675 @@ class lcl_json_to_abap implementation. iv_path = '' i_container_ref = lr_ref ). - endmethod. + ENDMETHOD. - method get_node_type. + METHOD get_node_type. - data lv_node_type_path type string. - data lo_sdescr type ref to cl_abap_structdescr. - data lo_tdescr type ref to cl_abap_tabledescr. - data lo_ddescr type ref to cl_abap_datadescr. + DATA lv_node_type_path TYPE string. + DATA lo_sdescr TYPE REF TO cl_abap_structdescr. + DATA lo_tdescr TYPE REF TO cl_abap_tabledescr. + DATA lo_ddescr TYPE REF TO cl_abap_datadescr. " Calculate type path - if is_parent_type-type_kind = lif_kind=>table. + IF is_parent_type-type_kind = lif_kind=>table. lv_node_type_path = is_parent_type-type_path && '/-'. " table item type - elseif is_parent_type-type_kind is not initial. + ELSEIF is_parent_type-type_kind IS NOT INITIAL. lv_node_type_path = is_parent_type-type_path && '/' && is_node-name. - endif. " For root node lv_node_type_path remains '' + ENDIF. " For root node lv_node_type_path remains '' " Get or create cached - read table mt_node_type_cache into rs_node_type with key type_path = lv_node_type_path. - if sy-subrc <> 0. + READ TABLE mt_node_type_cache INTO rs_node_type WITH KEY type_path = lv_node_type_path. + IF sy-subrc <> 0. rs_node_type-type_path = lv_node_type_path. - if mi_custom_mapping is bound. + IF mi_custom_mapping IS BOUND. rs_node_type-target_field_name = to_upper( mi_custom_mapping->to_abap( iv_path = is_node-path iv_name = is_node-name ) ). - if rs_node_type-target_field_name is initial. + IF rs_node_type-target_field_name IS INITIAL. rs_node_type-target_field_name = to_upper( is_node-name ). - endif. - else. + ENDIF. + ELSE. rs_node_type-target_field_name = to_upper( is_node-name ). - endif. + ENDIF. - case is_parent_type-type_kind. - when lif_kind=>table. + CASE is_parent_type-type_kind. + WHEN lif_kind=>table. lo_tdescr ?= is_parent_type-dd. rs_node_type-dd = lo_tdescr->get_table_line_type( ). - when lif_kind=>struct_flat or lif_kind=>struct_deep. + WHEN lif_kind=>struct_flat OR lif_kind=>struct_deep. lo_sdescr ?= is_parent_type-dd. lo_sdescr->get_component_type( - exporting + EXPORTING p_name = rs_node_type-target_field_name - receiving + RECEIVING p_descr_ref = rs_node_type-dd - exceptions + EXCEPTIONS component_not_found = 4 ). - if sy-subrc <> 0. - if mv_corresponding = abap_false. - z2UI5_cx_ajson_error=>raise( |Path not found| ). - else. - clear rs_node_type. - return. - endif. - endif. + IF sy-subrc <> 0. + IF mv_corresponding = abap_false. + z2ui5_cx_ajson_error=>raise( |Path not found| ). + ELSE. + CLEAR rs_node_type. + RETURN. + ENDIF. + ENDIF. - when ''. " Root node + WHEN ''. " Root node rs_node_type-dd ?= cl_abap_typedescr=>describe_by_data_ref( i_container_ref ). - when others. - z2UI5_cx_ajson_error=>raise( |Unexpected parent type| ). - endcase. + WHEN OTHERS. + z2ui5_cx_ajson_error=>raise( |Unexpected parent type| ). + ENDCASE. rs_node_type-type_kind = rs_node_type-dd->type_kind. " for caching and cleaner unintialized access - if rs_node_type-type_kind = lif_kind=>table. + IF rs_node_type-type_kind = lif_kind=>table. lo_tdescr ?= rs_node_type-dd. - if lo_tdescr->table_kind <> cl_abap_tabledescr=>tablekind_std. + IF lo_tdescr->table_kind <> cl_abap_tabledescr=>tablekind_std. lo_ddescr = lo_tdescr->get_table_line_type( ). - create data rs_node_type-tab_item_buf type handle lo_ddescr. - endif. - endif. + CREATE DATA rs_node_type-tab_item_buf TYPE HANDLE lo_ddescr. + ENDIF. + ENDIF. - insert rs_node_type into table mt_node_type_cache. - endif. + INSERT rs_node_type INTO TABLE mt_node_type_cache. + ENDIF. - endmethod. + ENDMETHOD. - method any_to_abap. + METHOD any_to_abap. - data ls_node_type like line of mt_node_type_cache. - data lx_ajson type ref to z2UI5_cx_ajson_error. - data lx_root type ref to cx_root. - data lr_target_field type ref to data. + DATA ls_node_type LIKE LINE OF mt_node_type_cache. + DATA lx_ajson TYPE REF TO z2ui5_cx_ajson_error. + DATA lx_root TYPE REF TO cx_root. + DATA lr_target_field TYPE REF TO data. - field-symbols type z2ui5_if_ajson_types=>ty_node. - field-symbols type standard table. - field-symbols type any table. - field-symbols type any. - field-symbols type any. + FIELD-SYMBOLS TYPE z2ui5_if_ajson_types=>ty_node. + FIELD-SYMBOLS TYPE STANDARD TABLE. + FIELD-SYMBOLS TYPE ANY TABLE. + FIELD-SYMBOLS TYPE any. + FIELD-SYMBOLS TYPE any. " Assign container - case is_parent_type-type_kind. - when lif_kind=>table. - if is_parent_type-tab_item_buf is bound. " Indirect hint that table was sorted/hashed, see get_node_type. - assign i_container_ref->* to . - assert sy-subrc = 0. + CASE is_parent_type-type_kind. + WHEN lif_kind=>table. + IF is_parent_type-tab_item_buf IS BOUND. " Indirect hint that table was sorted/hashed, see get_node_type. + ASSIGN i_container_ref->* TO . + ASSERT sy-subrc = 0. lr_target_field = is_parent_type-tab_item_buf. " For hashed/sorted table - same buffer for all children - assign is_parent_type-tab_item_buf->* to . - assert sy-subrc = 0. + ASSIGN is_parent_type-tab_item_buf->* TO . + ASSERT sy-subrc = 0. - else. - assign i_container_ref->* to . - assert sy-subrc = 0. - endif. + ELSE. + ASSIGN i_container_ref->* TO . + ASSERT sy-subrc = 0. + ENDIF. - when lif_kind=>struct_flat or lif_kind=>struct_deep. - assign i_container_ref->* to . - assert sy-subrc = 0. - endcase. + WHEN lif_kind=>struct_flat OR lif_kind=>struct_deep. + ASSIGN i_container_ref->* TO . + ASSERT sy-subrc = 0. + ENDCASE. - try. + TRY. - " array_index because stringified index goes in wrong order [1, 10, 2 ...] - loop at mr_nodes->* assigning using key array_index where path = iv_path. + " array_index because stringified index goes in wrong order [1, 10, 2 ...] + LOOP AT mr_nodes->* ASSIGNING USING KEY array_index WHERE path = iv_path. - " Get or create type cache record - if is_parent_type-type_kind <> lif_kind=>table or ls_node_type-type_kind is initial. - " table records are the same, no need to refetch twice + " Get or create type cache record + IF is_parent_type-type_kind <> lif_kind=>table OR ls_node_type-type_kind IS INITIAL. + " table records are the same, no need to refetch twice - ls_node_type = get_node_type( - is_node = - is_parent_type = is_parent_type ). + ls_node_type = get_node_type( + is_node = + is_parent_type = is_parent_type ). - if mv_corresponding = abap_true and ls_node_type is initial. - continue. - endif. + IF mv_corresponding = abap_true AND ls_node_type IS INITIAL. + CONTINUE. + ENDIF. - endif. + ENDIF. - " Validate node type - if ls_node_type-type_kind = lif_kind=>data_ref or - ls_node_type-type_kind = lif_kind=>object_ref. - " TODO maybe in future - z2UI5_cx_ajson_error=>raise( 'Cannot assign to ref' ). - endif. + " Validate node type + IF ls_node_type-type_kind = lif_kind=>data_ref OR + ls_node_type-type_kind = lif_kind=>object_ref. + " TODO maybe in future + z2ui5_cx_ajson_error=>raise( 'Cannot assign to ref' ). + ENDIF. - " Find target field reference - case is_parent_type-type_kind. - when lif_kind=>table. - if not ls_node_type-target_field_name co '0123456789'. - " Does not affect anything actually but for integrity - z2UI5_cx_ajson_error=>raise( 'Need index to access tables' ). - endif. + " Find target field reference + CASE is_parent_type-type_kind. + WHEN lif_kind=>table. + IF NOT ls_node_type-target_field_name CO '0123456789'. + " Does not affect anything actually but for integrity + z2ui5_cx_ajson_error=>raise( 'Need index to access tables' ). + ENDIF. - if is_parent_type-tab_item_buf is not bound. " Indirect hint that table was srt/hsh, see get_node_type - append initial line to reference into lr_target_field. - assert sy-subrc = 0. - endif. + IF is_parent_type-tab_item_buf IS NOT BOUND. " Indirect hint that table was srt/hsh, see get_node_type + APPEND INITIAL LINE TO REFERENCE INTO lr_target_field. + ASSERT sy-subrc = 0. + ENDIF. - when lif_kind=>struct_flat or lif_kind=>struct_deep. - field-symbols type any. - assign component ls_node_type-target_field_name of structure to . - assert sy-subrc = 0. - get reference of into lr_target_field. + WHEN lif_kind=>struct_flat OR lif_kind=>struct_deep. + FIELD-SYMBOLS TYPE any. + ASSIGN COMPONENT ls_node_type-target_field_name OF STRUCTURE TO . + ASSERT sy-subrc = 0. + GET REFERENCE OF INTO lr_target_field. - when ''. " Root node - lr_target_field = i_container_ref. + WHEN ''. " Root node + lr_target_field = i_container_ref. - when others. - z2UI5_cx_ajson_error=>raise( 'Unexpected parent type' ). - endcase. + WHEN OTHERS. + z2ui5_cx_ajson_error=>raise( 'Unexpected parent type' ). + ENDCASE. - " Process value assignment - case -type. - when z2ui5_if_ajson_types=>node_type-object. - if ls_node_type-type_kind <> lif_kind=>struct_flat and - ls_node_type-type_kind <> lif_kind=>struct_deep. - z2UI5_cx_ajson_error=>raise( 'Expected structure' ). - endif. - any_to_abap( - iv_path = -path && -name && '/' - is_parent_type = ls_node_type - i_container_ref = lr_target_field ). + " Process value assignment + CASE -type. + WHEN z2ui5_if_ajson_types=>node_type-object. + IF ls_node_type-type_kind <> lif_kind=>struct_flat AND + ls_node_type-type_kind <> lif_kind=>struct_deep. + z2ui5_cx_ajson_error=>raise( 'Expected structure' ). + ENDIF. + any_to_abap( + iv_path = -path && -name && '/' + is_parent_type = ls_node_type + i_container_ref = lr_target_field ). - when z2ui5_if_ajson_types=>node_type-array. - if not ls_node_type-type_kind = lif_kind=>table. - z2UI5_cx_ajson_error=>raise( 'Expected table' ). - endif. - any_to_abap( - iv_path = -path && -name && '/' - is_parent_type = ls_node_type - i_container_ref = lr_target_field ). + WHEN z2ui5_if_ajson_types=>node_type-array. + IF NOT ls_node_type-type_kind = lif_kind=>table. + z2ui5_cx_ajson_error=>raise( 'Expected table' ). + ENDIF. + any_to_abap( + iv_path = -path && -name && '/' + is_parent_type = ls_node_type + i_container_ref = lr_target_field ). - when others. - value_to_abap( - is_node = - is_node_type = ls_node_type - i_container_ref = lr_target_field ). - endcase. + WHEN OTHERS. + value_to_abap( + is_node = + is_node_type = ls_node_type + i_container_ref = lr_target_field ). + ENDCASE. - if is_parent_type-tab_item_buf is bound. " Indirect hint that table was sorted/hashed, see get_node_type. - try. - insert into table . - if sy-subrc <> 0. - z2UI5_cx_ajson_error=>raise( 'Duplicate insertion' ). - endif. - catch cx_sy_itab_duplicate_key. - z2UI5_cx_ajson_error=>raise( 'Duplicate insertion' ). - endtry. - endif. + IF is_parent_type-tab_item_buf IS BOUND. " Indirect hint that table was sorted/hashed, see get_node_type. + TRY. + INSERT INTO TABLE . + IF sy-subrc <> 0. + z2ui5_cx_ajson_error=>raise( 'Duplicate insertion' ). + ENDIF. + CATCH cx_sy_itab_duplicate_key. + z2ui5_cx_ajson_error=>raise( 'Duplicate insertion' ). + ENDTRY. + ENDIF. - endloop. + ENDLOOP. - catch z2UI5_cx_ajson_error into lx_ajson. - if lx_ajson->location is initial. - lx_ajson->set_location( -path && -name ). - endif. - raise exception lx_ajson. - catch cx_sy_conversion_no_number. - z2UI5_cx_ajson_error=>raise( - iv_msg = 'Source is not a number' - iv_location = -path && -name ). - catch cx_root into lx_root. - z2UI5_cx_ajson_error=>raise( - iv_msg = lx_root->get_text( ) - iv_location = -path && -name ). - endtry. + CATCH z2ui5_cx_ajson_error INTO lx_ajson. + IF lx_ajson->location IS INITIAL. + lx_ajson->set_location( -path && -name ). + ENDIF. + RAISE EXCEPTION lx_ajson. + CATCH cx_sy_conversion_no_number. + z2ui5_cx_ajson_error=>raise( + iv_msg = 'Source is not a number' + iv_location = -path && -name ). + CATCH cx_root INTO lx_root. + z2ui5_cx_ajson_error=>raise( + iv_msg = lx_root->get_text( ) + iv_location = -path && -name ). + ENDTRY. - endmethod. + ENDMETHOD. - method value_to_abap. + METHOD value_to_abap. - field-symbols type any. + FIELD-SYMBOLS TYPE any. - if is_node_type-type_kind ca lif_kind=>deep_targets. - z2UI5_cx_ajson_error=>raise( |Unsupported target for value [{ is_node_type-type_kind }]| ). - endif. + IF is_node_type-type_kind CA lif_kind=>deep_targets. + z2ui5_cx_ajson_error=>raise( |Unsupported target for value [{ is_node_type-type_kind }]| ). + ENDIF. - assign i_container_ref->* to . - assert sy-subrc = 0. + ASSIGN i_container_ref->* TO . + ASSERT sy-subrc = 0. - case is_node-type. - when z2ui5_if_ajson_types=>node_type-null. + CASE is_node-type. + WHEN z2ui5_if_ajson_types=>node_type-null. " Do nothing - when z2ui5_if_ajson_types=>node_type-boolean. + WHEN z2ui5_if_ajson_types=>node_type-boolean. " TODO: check type ? = boolc( is_node-value = 'true' ). - when z2ui5_if_ajson_types=>node_type-number. + WHEN z2ui5_if_ajson_types=>node_type-number. " TODO: check type ? = is_node-value. - when z2ui5_if_ajson_types=>node_type-string. + WHEN z2ui5_if_ajson_types=>node_type-string. " TODO: check type ? - if is_node_type-type_kind = lif_kind=>date and is_node-value is not initial. + IF is_node_type-type_kind = lif_kind=>date AND is_node-value IS NOT INITIAL. = to_date( is_node-value ). - elseif is_node_type-type_kind = lif_kind=>packed and is_node-value is not initial. + ELSEIF is_node_type-type_kind = lif_kind=>time AND is_node-value IS NOT INITIAL. + = to_time( is_node-value ). + ELSEIF is_node_type-type_kind = lif_kind=>packed AND is_node-value IS NOT INITIAL. = to_timestamp( is_node-value ). - else. + ELSE. = is_node-value. - endif. - when others. - z2UI5_cx_ajson_error=>raise( |Unexpected JSON type [{ is_node-type }]| ). - endcase. + ENDIF. + WHEN OTHERS. + z2ui5_cx_ajson_error=>raise( |Unexpected JSON type [{ is_node-type }]| ). + ENDCASE. - endmethod. + ENDMETHOD. - method to_date. + METHOD to_date. - data lv_y type c length 4. - data lv_m type c length 2. - data lv_d type c length 2. + DATA lv_y TYPE c LENGTH 4. + DATA lv_m TYPE c LENGTH 2. + DATA lv_d TYPE c LENGTH 2. - find first occurrence of regex '^(\d{4})-(\d{2})-(\d{2})(T|$)' "#EC NOTEXT - in iv_value - submatches lv_y lv_m lv_d. - if sy-subrc <> 0. - z2UI5_cx_ajson_error=>raise( 'Unexpected date format' ). - endif. - concatenate lv_y lv_m lv_d into rv_result. + FIND FIRST OCCURRENCE OF REGEX '^(\d{4})-(\d{2})-(\d{2})(T|$)' "#EC NOTEXT + IN iv_value + SUBMATCHES lv_y lv_m lv_d. + IF sy-subrc <> 0. + z2ui5_cx_ajson_error=>raise( 'Unexpected date format' ). + ENDIF. + CONCATENATE lv_y lv_m lv_d INTO rv_result. - endmethod. + ENDMETHOD. - method to_timestamp. + METHOD to_timestamp. - constants lc_utc type c length 6 value 'UTC'. - constants lc_regex_ts_with_hour type string - value `^(\d{4})-(\d{2})-(\d{2})(T)(\d{2}):(\d{2}):(\d{2})(\+)(\d{2}):(\d{2})`. "#EC NOTEXT - constants lc_regex_ts_utc type string - value `^(\d{4})-(\d{2})-(\d{2})(T)(\d{2}):(\d{2}):(\d{2})(Z|$)`. "#EC NOTEXT + CONSTANTS lc_utc TYPE c LENGTH 6 VALUE 'UTC'. + CONSTANTS lc_regex_ts_with_hour TYPE string + VALUE `^(\d{4})-(\d{2})-(\d{2})(T)(\d{2}):(\d{2}):(\d{2})(\+)(\d{2}):(\d{2})`. "#EC NOTEXT + CONSTANTS lc_regex_ts_utc TYPE string + VALUE `^(\d{4})-(\d{2})-(\d{2})(T)(\d{2}):(\d{2}):(\d{2})(Z|$)`. "#EC NOTEXT - data: - begin of ls_timestamp, - year type c length 4, - month type c length 2, - day type c length 2, - t type c length 1, - hour type c length 2, - minute type c length 2, - second type c length 2, - local_sign type c length 1, - local_hour type c length 2, - local_minute type c length 2, - end of ls_timestamp. + DATA: + BEGIN OF ls_timestamp, + year TYPE c LENGTH 4, + month TYPE c LENGTH 2, + day TYPE c LENGTH 2, + t TYPE c LENGTH 1, + hour TYPE c LENGTH 2, + minute TYPE c LENGTH 2, + second TYPE c LENGTH 2, + local_sign TYPE c LENGTH 1, + local_hour TYPE c LENGTH 2, + local_minute TYPE c LENGTH 2, + END OF ls_timestamp. - data lv_date type d. - data lv_time type t. - data lv_seconds_conv type i. - data lv_timestamp type timestampl. + DATA lv_date TYPE d. + DATA lv_time TYPE t. + DATA lv_seconds_conv TYPE i. + DATA lv_timestamp TYPE timestampl. - find first occurrence of regex lc_regex_ts_with_hour - in iv_value submatches + FIND FIRST OCCURRENCE OF REGEX lc_regex_ts_with_hour + IN iv_value SUBMATCHES ls_timestamp-year ls_timestamp-month ls_timestamp-day ls_timestamp-t ls_timestamp-hour ls_timestamp-minute ls_timestamp-second ls_timestamp-local_sign ls_timestamp-local_hour ls_timestamp-local_minute. - if sy-subrc = 0. + IF sy-subrc = 0. lv_seconds_conv = ( ls_timestamp-local_hour * 3600 ) + ( ls_timestamp-local_minute * 60 ). - else. + ELSE. - find first occurrence of regex lc_regex_ts_utc - in iv_value submatches + FIND FIRST OCCURRENCE OF REGEX lc_regex_ts_utc + IN iv_value SUBMATCHES ls_timestamp-year ls_timestamp-month ls_timestamp-day ls_timestamp-t ls_timestamp-hour ls_timestamp-minute ls_timestamp-second. - if sy-subrc <> 0. - z2UI5_cx_ajson_error=>raise( 'Unexpected timestamp format' ). - endif. + IF sy-subrc <> 0. + z2ui5_cx_ajson_error=>raise( 'Unexpected timestamp format' ). + ENDIF. - endif. + ENDIF. - concatenate ls_timestamp-year ls_timestamp-month ls_timestamp-day into lv_date. - concatenate ls_timestamp-hour ls_timestamp-minute ls_timestamp-second into lv_time. + CONCATENATE ls_timestamp-year ls_timestamp-month ls_timestamp-day INTO lv_date. + CONCATENATE ls_timestamp-hour ls_timestamp-minute ls_timestamp-second INTO lv_time. - convert date lv_date time lv_time into time stamp lv_timestamp time zone lc_utc. + CONVERT DATE lv_date TIME lv_time INTO TIME STAMP lv_timestamp TIME ZONE lc_utc. - try. + TRY. - case ls_timestamp-local_sign. - when '-'. - lv_timestamp = cl_abap_tstmp=>add( - tstmp = lv_timestamp - secs = lv_seconds_conv ). - when '+'. - lv_timestamp = cl_abap_tstmp=>subtractsecs( - tstmp = lv_timestamp - secs = lv_seconds_conv ). - endcase. + CASE ls_timestamp-local_sign. + WHEN '-'. + lv_timestamp = cl_abap_tstmp=>add( + tstmp = lv_timestamp + secs = lv_seconds_conv ). + WHEN '+'. + lv_timestamp = cl_abap_tstmp=>subtractsecs( + tstmp = lv_timestamp + secs = lv_seconds_conv ). + ENDCASE. - catch cx_parameter_invalid_range cx_parameter_invalid_type. - z2UI5_cx_ajson_error=>raise( 'Unexpected error calculating timestamp' ). - endtry. + CATCH cx_parameter_invalid_range cx_parameter_invalid_type. + z2ui5_cx_ajson_error=>raise( 'Unexpected error calculating timestamp' ). + ENDTRY. - if lv_timestamp is not initial. + IF lv_timestamp IS NOT INITIAL. cl_abap_tstmp=>move( - exporting + EXPORTING tstmp_src = lv_timestamp - importing + IMPORTING tstmp_tgt = rv_result ). - endif. + ENDIF. - endmethod. + ENDMETHOD. -endclass. + + METHOD to_time. + + DATA lv_h TYPE c LENGTH 2. + DATA lv_m TYPE c LENGTH 2. + DATA lv_s TYPE c LENGTH 2. + + FIND FIRST OCCURRENCE OF REGEX '^(\d{2}):(\d{2}):(\d{2})(T|$)' "#EC NOTEXT + IN iv_value + SUBMATCHES lv_h lv_m lv_s. + IF sy-subrc <> 0. + z2ui5_cx_ajson_error=>raise( 'Unexpected time format' ). + ENDIF. + CONCATENATE lv_h lv_m lv_s INTO rv_result. + + ENDMETHOD. + +ENDCLASS. ********************************************************************** * ABAP_TO_JSON ********************************************************************** -class lcl_abap_to_json definition final. - public section. +CLASS lcl_abap_to_json DEFINITION FINAL. + PUBLIC SECTION. - class-methods convert - importing - iv_data type any - is_prefix type z2ui5_if_ajson_types=>ty_path_name optional - iv_array_index type i default 0 - ii_custom_mapping type ref to z2ui5_if_ajson_mapping optional - is_opts type z2ui5_if_ajson=>ty_opts optional - iv_item_order type i default 0 - returning - value(rt_nodes) type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + CLASS-METHODS convert + IMPORTING + iv_data TYPE any + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name OPTIONAL + iv_array_index TYPE i DEFAULT 0 + ii_custom_mapping TYPE REF TO z2ui5_if_ajson_mapping OPTIONAL + is_opts TYPE z2ui5_if_ajson=>ty_opts OPTIONAL + iv_item_order TYPE i DEFAULT 0 + RETURNING + VALUE(rt_nodes) TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - class-methods insert_with_type - importing - iv_data type any - iv_type type z2ui5_if_ajson_types=>ty_node_type - is_prefix type z2ui5_if_ajson_types=>ty_path_name optional - iv_array_index type i default 0 - ii_custom_mapping type ref to z2ui5_if_ajson_mapping optional - is_opts type z2ui5_if_ajson=>ty_opts optional - iv_item_order type i default 0 - returning - value(rt_nodes) type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + CLASS-METHODS insert_with_type + IMPORTING + iv_data TYPE any + iv_type TYPE z2ui5_if_ajson_types=>ty_node_type + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name OPTIONAL + iv_array_index TYPE i DEFAULT 0 + ii_custom_mapping TYPE REF TO z2ui5_if_ajson_mapping OPTIONAL + is_opts TYPE z2ui5_if_ajson=>ty_opts OPTIONAL + iv_item_order TYPE i DEFAULT 0 + RETURNING + VALUE(rt_nodes) TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - class-methods format_date - importing - iv_date type d - returning - value(rv_str) type string. - class-methods format_time - importing - iv_time type t - returning - value(rv_str) type string. - class-methods format_timestamp - importing - iv_ts type timestamp - returning - value(rv_str) type string. + CLASS-METHODS format_date + IMPORTING + iv_date TYPE d + RETURNING + VALUE(rv_str) TYPE string. + CLASS-METHODS format_time + IMPORTING + iv_time TYPE t + RETURNING + VALUE(rv_str) TYPE string. + CLASS-METHODS format_timestamp + IMPORTING + iv_ts TYPE timestamp + RETURNING + VALUE(rv_str) TYPE string. - class-methods class_constructor. + CLASS-METHODS class_constructor. - private section. + PRIVATE SECTION. - class-data gv_ajson_absolute_type_name type string. - data mi_custom_mapping type ref to z2ui5_if_ajson_mapping. - data mv_keep_item_order type abap_bool. - data mv_format_datetime type abap_bool. + CLASS-DATA gv_ajson_absolute_type_name TYPE string. + DATA mi_custom_mapping TYPE REF TO z2ui5_if_ajson_mapping. + DATA mv_keep_item_order TYPE abap_bool. + DATA mv_format_datetime TYPE abap_bool. - methods convert_any - importing - iv_data type any - io_type type ref to cl_abap_typedescr - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS convert_any + IMPORTING + iv_data TYPE any + io_type TYPE REF TO cl_abap_typedescr + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - methods convert_ajson - importing - io_json type ref to z2ui5_if_ajson - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS convert_ajson + IMPORTING + io_json TYPE REF TO z2ui5_if_ajson + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - methods convert_value - importing - iv_data type any - io_type type ref to cl_abap_typedescr - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS convert_value + IMPORTING + iv_data TYPE any + io_type TYPE REF TO cl_abap_typedescr + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - methods convert_ref - importing - iv_data type any - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS convert_ref + IMPORTING + iv_data TYPE any + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - methods convert_struc - importing - iv_data type any - io_type type ref to cl_abap_typedescr - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS convert_struc + IMPORTING + iv_data TYPE any + io_type TYPE REF TO cl_abap_typedescr + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - methods convert_table - importing - iv_data type any - io_type type ref to cl_abap_typedescr - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS convert_table + IMPORTING + iv_data TYPE any + io_type TYPE REF TO cl_abap_typedescr + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. - methods insert_value_with_type - importing - iv_data type any - iv_type type z2ui5_if_ajson_types=>ty_node_type - io_type type ref to cl_abap_typedescr - is_prefix type z2ui5_if_ajson_types=>ty_path_name - iv_index type i default 0 - iv_item_order type i default 0 - changing - ct_nodes type z2ui5_if_ajson_types=>ty_nodes_tt - raising - z2UI5_cx_ajson_error. + METHODS insert_value_with_type + IMPORTING + iv_data TYPE any + iv_type TYPE z2ui5_if_ajson_types=>ty_node_type + io_type TYPE REF TO cl_abap_typedescr + is_prefix TYPE z2ui5_if_ajson_types=>ty_path_name + iv_index TYPE i DEFAULT 0 + iv_item_order TYPE i DEFAULT 0 + CHANGING + ct_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt + RAISING + z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class lcl_abap_to_json implementation. +CLASS lcl_abap_to_json IMPLEMENTATION. - method class_constructor. + METHOD class_constructor. - data lo_dummy type ref to z2ui5_cl_ajson. - data lo_type type ref to cl_abap_refdescr. + DATA lo_dummy TYPE REF TO z2ui5_cl_ajson. + DATA lo_type TYPE REF TO cl_abap_refdescr. lo_type ?= cl_abap_typedescr=>describe_by_data( lo_dummy ). gv_ajson_absolute_type_name = lo_type->get_referenced_type( )->absolute_name. - endmethod. + ENDMETHOD. - method convert. + METHOD convert. - data lo_type type ref to cl_abap_typedescr. - data lo_converter type ref to lcl_abap_to_json. + DATA lo_type TYPE REF TO cl_abap_typedescr. + DATA lo_converter TYPE REF TO lcl_abap_to_json. lo_type = cl_abap_typedescr=>describe_by_data( iv_data ). - create object lo_converter. + CREATE OBJECT lo_converter. lo_converter->mi_custom_mapping = ii_custom_mapping. lo_converter->mv_keep_item_order = is_opts-keep_item_order. lo_converter->mv_format_datetime = is_opts-format_datetime. lo_converter->convert_any( - exporting + EXPORTING iv_data = iv_data io_type = lo_type is_prefix = is_prefix iv_index = iv_array_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = rt_nodes ). - endmethod. + ENDMETHOD. - method convert_any. + METHOD convert_any. - case io_type->kind. - when cl_abap_typedescr=>kind_elem. + CASE io_type->kind. + WHEN cl_abap_typedescr=>kind_elem. convert_value( - exporting + EXPORTING iv_data = iv_data io_type = io_type is_prefix = is_prefix iv_index = iv_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = ct_nodes ). - when cl_abap_typedescr=>kind_struct. + WHEN cl_abap_typedescr=>kind_struct. convert_struc( - exporting + EXPORTING iv_data = iv_data io_type = io_type is_prefix = is_prefix iv_index = iv_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = ct_nodes ). - when cl_abap_typedescr=>kind_table. + WHEN cl_abap_typedescr=>kind_table. convert_table( - exporting + EXPORTING iv_data = iv_data io_type = io_type is_prefix = is_prefix iv_index = iv_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = ct_nodes ). - when others. + WHEN OTHERS. - if io_type->type_kind = lif_kind=>data_ref or iv_data is initial. + IF io_type->type_kind = lif_kind=>data_ref OR iv_data IS INITIAL. " Convert data references and initial references to other types (like ref to class or interface) " Initial references will result in "null" convert_ref( - exporting + EXPORTING iv_data = iv_data is_prefix = is_prefix iv_index = iv_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = ct_nodes ). - elseif io_type->type_kind = lif_kind=>object_ref - and cl_abap_typedescr=>describe_by_object_ref( iv_data )->absolute_name = gv_ajson_absolute_type_name. + ELSEIF io_type->type_kind = lif_kind=>object_ref + AND cl_abap_typedescr=>describe_by_object_ref( iv_data )->absolute_name = gv_ajson_absolute_type_name. convert_ajson( - exporting + EXPORTING io_json = iv_data is_prefix = is_prefix iv_index = iv_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = ct_nodes ). - else. - z2UI5_cx_ajson_error=>raise( |Unsupported type [{ io_type->type_kind + ELSE. + z2ui5_cx_ajson_error=>raise( |Unsupported type [{ io_type->type_kind }] @{ is_prefix-path && is_prefix-name }| ). - endif. + ENDIF. - endcase. + ENDCASE. - endmethod. + ENDMETHOD. - method convert_ajson. + METHOD convert_ajson. - field-symbols like line of ct_nodes. - field-symbols like line of ct_nodes. + FIELD-SYMBOLS LIKE LINE OF ct_nodes. + FIELD-SYMBOLS LIKE LINE OF ct_nodes. - if io_json is not bound. - return. - endif. + IF io_json IS NOT BOUND. + RETURN. + ENDIF. - loop at io_json->mt_json_tree assigning . - append to ct_nodes assigning . + LOOP AT io_json->mt_json_tree ASSIGNING . + APPEND TO ct_nodes ASSIGNING . - if -path is initial and -name is initial. " root node + IF -path IS INITIAL AND -name IS INITIAL. " root node -path = is_prefix-path. -name = is_prefix-name. -index = iv_index. -order = iv_item_order. - else. + ELSE. -path = is_prefix-path && is_prefix-name && -path. - endif. - endloop. + ENDIF. + ENDLOOP. - endmethod. + ENDMETHOD. - method format_date. - if iv_date is not initial. + METHOD format_date. + IF iv_date IS NOT INITIAL. rv_str = iv_date+0(4) && '-' && iv_date+4(2) && '-' && iv_date+6(2). - endif. - endmethod. + ENDIF. + ENDMETHOD. - method format_time. - if iv_time is not initial. + METHOD format_time. + IF iv_time IS NOT INITIAL. rv_str = iv_time+0(2) && ':' && iv_time+2(2) && ':' && iv_time+4(2). - endif. - endmethod. + ENDIF. + ENDMETHOD. - method format_timestamp. + METHOD format_timestamp. - constants lc_utc type c length 6 value 'UTC'. + CONSTANTS lc_utc TYPE c LENGTH 6 VALUE 'UTC'. - data lv_date type d. - data lv_time type t. + DATA lv_date TYPE d. + DATA lv_time TYPE t. - convert time stamp iv_ts time zone lc_utc - into date lv_date time lv_time. + CONVERT TIME STAMP iv_ts TIME ZONE lc_utc + INTO DATE lv_date TIME lv_time. rv_str = lv_date+0(4) && '-' && lv_date+4(2) && '-' && lv_date+6(2) && @@ -1388,114 +1415,114 @@ class lcl_abap_to_json implementation. lv_time+0(2) && ':' && lv_time+2(2) && ':' && lv_time+4(2) && 'Z'. - endmethod. + ENDMETHOD. - method convert_value. + METHOD convert_value. - data ls_node like line of ct_nodes. + DATA ls_node LIKE LINE OF ct_nodes. ls_node-path = is_prefix-path. ls_node-name = is_prefix-name. ls_node-index = iv_index. ls_node-order = iv_item_order. - if ls_node-name is initial. + IF ls_node-name IS INITIAL. ls_node-name = is_prefix-name. - endif. + ENDIF. - if io_type->absolute_name = '\TYPE-POOL=ABAP\TYPE=ABAP_BOOL' - or io_type->absolute_name = '\TYPE=ABAP_BOOLEAN' - or io_type->absolute_name = '\TYPE=XSDBOOLEAN' - or io_type->absolute_name = '\TYPE=FLAG' - or io_type->absolute_name = '\TYPE=XFELD'. + IF io_type->absolute_name = '\TYPE-POOL=ABAP\TYPE=ABAP_BOOL' + OR io_type->absolute_name = '\TYPE=ABAP_BOOLEAN' + OR io_type->absolute_name = '\TYPE=XSDBOOLEAN' + OR io_type->absolute_name = '\TYPE=FLAG' + OR io_type->absolute_name = '\TYPE=XFELD'. ls_node-type = z2ui5_if_ajson_types=>node_type-boolean. - if iv_data is not initial. + IF iv_data IS NOT INITIAL. ls_node-value = 'true'. - else. + ELSE. ls_node-value = 'false'. - endif. - elseif io_type->absolute_name = '\TYPE=TIMESTAMP'. - if mv_format_datetime = abap_true. + ENDIF. + ELSEIF io_type->absolute_name = '\TYPE=TIMESTAMP'. + IF mv_format_datetime = abap_true. ls_node-type = z2ui5_if_ajson_types=>node_type-string. ls_node-value = format_timestamp( iv_data ). - else. + ELSE. ls_node-type = z2ui5_if_ajson_types=>node_type-number. ls_node-value = |{ iv_data }|. - endif. - elseif io_type->type_kind co lif_kind=>texts or - io_type->type_kind co lif_kind=>binary or - io_type->type_kind co lif_kind=>enum. + ENDIF. + ELSEIF io_type->type_kind CO lif_kind=>texts OR + io_type->type_kind CO lif_kind=>binary OR + io_type->type_kind CO lif_kind=>enum. ls_node-type = z2ui5_if_ajson_types=>node_type-string. ls_node-value = |{ iv_data }|. - elseif io_type->type_kind = lif_kind=>date. + ELSEIF io_type->type_kind = lif_kind=>date. ls_node-type = z2ui5_if_ajson_types=>node_type-string. - if mv_format_datetime = abap_true. + IF mv_format_datetime = abap_true. ls_node-value = format_date( iv_data ). - else. + ELSE. ls_node-value = |{ iv_data }|. - endif. - elseif io_type->type_kind = lif_kind=>time. + ENDIF. + ELSEIF io_type->type_kind = lif_kind=>time. ls_node-type = z2ui5_if_ajson_types=>node_type-string. - if mv_format_datetime = abap_true. + IF mv_format_datetime = abap_true. ls_node-value = format_time( iv_data ). - else. + ELSE. ls_node-value = |{ iv_data }|. - endif. - elseif io_type->type_kind co lif_kind=>numeric. + ENDIF. + ELSEIF io_type->type_kind CO lif_kind=>numeric. ls_node-type = z2ui5_if_ajson_types=>node_type-number. ls_node-value = |{ iv_data }|. - else. - z2UI5_cx_ajson_error=>raise( |Unexpected elementary type [{ + ELSE. + z2ui5_cx_ajson_error=>raise( |Unexpected elementary type [{ io_type->type_kind }] @{ is_prefix-path && is_prefix-name }| ). - endif. + ENDIF. - append ls_node to ct_nodes. + APPEND ls_node TO ct_nodes. - endmethod. + ENDMETHOD. - method convert_ref. + METHOD convert_ref. - data ls_node like line of ct_nodes. + DATA ls_node LIKE LINE OF ct_nodes. ls_node-path = is_prefix-path. ls_node-name = is_prefix-name. ls_node-index = iv_index. ls_node-order = iv_item_order. - if mi_custom_mapping is bound. + IF mi_custom_mapping IS BOUND. ls_node-name = mi_custom_mapping->to_json( iv_path = is_prefix-path iv_name = is_prefix-name ). - endif. + ENDIF. - if ls_node-name is initial. + IF ls_node-name IS INITIAL. ls_node-name = is_prefix-name. - endif. + ENDIF. - if iv_data is initial. + IF iv_data IS INITIAL. ls_node-type = z2ui5_if_ajson_types=>node_type-null. ls_node-value = 'null'. - else. + ELSE. " TODO support data references - z2UI5_cx_ajson_error=>raise( |Unexpected reference @{ is_prefix-path && is_prefix-name }| ). - endif. + z2ui5_cx_ajson_error=>raise( |Unexpected reference @{ is_prefix-path && is_prefix-name }| ). + ENDIF. - append ls_node to ct_nodes. + APPEND ls_node TO ct_nodes. - endmethod. + ENDMETHOD. - method convert_struc. + METHOD convert_struc. - data lo_struc type ref to cl_abap_structdescr. - data lt_comps type cl_abap_structdescr=>included_view. - data ls_next_prefix like is_prefix. - data lv_mapping_prefix_name like is_prefix-name. - data lv_item_order type i. - data ls_root like line of ct_nodes. + DATA lo_struc TYPE REF TO cl_abap_structdescr. + DATA lt_comps TYPE cl_abap_structdescr=>included_view. + DATA ls_next_prefix LIKE is_prefix. + DATA lv_mapping_prefix_name LIKE is_prefix-name. + DATA lv_item_order TYPE i. + DATA ls_root LIKE LINE OF ct_nodes. - field-symbols like ls_root. - field-symbols like line of lt_comps. - field-symbols type any. + FIELD-SYMBOLS LIKE ls_root. + FIELD-SYMBOLS LIKE LINE OF lt_comps. + FIELD-SYMBOLS TYPE any. " Object root @@ -1504,19 +1531,19 @@ class lcl_abap_to_json implementation. ls_root-type = z2ui5_if_ajson_types=>node_type-object. ls_root-index = iv_index. - if mi_custom_mapping is bound. + IF mi_custom_mapping IS BOUND. ls_root-name = mi_custom_mapping->to_json( iv_path = is_prefix-path iv_name = is_prefix-name ). - endif. + ENDIF. - if ls_root-name is initial. + IF ls_root-name IS INITIAL. ls_root-name = is_prefix-name. - endif. + ENDIF. ls_root-order = iv_item_order. - append ls_root to ct_nodes assigning . + APPEND ls_root TO ct_nodes ASSIGNING . " Object attributes @@ -1530,51 +1557,51 @@ class lcl_abap_to_json implementation. ls_next_prefix-path = is_prefix-path && -name && '/'. - loop at lt_comps assigning . - clear lv_mapping_prefix_name. + LOOP AT lt_comps ASSIGNING . + CLEAR lv_mapping_prefix_name. -children = -children + 1. ls_next_prefix-name = to_lower( -name ). - assign component -name of structure iv_data to . - assert sy-subrc = 0. + ASSIGN COMPONENT -name OF STRUCTURE iv_data TO . + ASSERT sy-subrc = 0. - if mi_custom_mapping is bound and -type->kind = cl_abap_typedescr=>kind_elem. + IF mi_custom_mapping IS BOUND AND -type->kind = cl_abap_typedescr=>kind_elem. lv_mapping_prefix_name = mi_custom_mapping->to_json( iv_path = ls_next_prefix-path iv_name = ls_next_prefix-name ). - endif. + ENDIF. - if lv_mapping_prefix_name is not initial. + IF lv_mapping_prefix_name IS NOT INITIAL. ls_next_prefix-name = lv_mapping_prefix_name. - endif. + ENDIF. - if mv_keep_item_order = abap_true. + IF mv_keep_item_order = abap_true. lv_item_order = -children. - endif. + ENDIF. convert_any( - exporting + EXPORTING iv_data = io_type = -type is_prefix = ls_next_prefix iv_item_order = lv_item_order - changing + CHANGING ct_nodes = ct_nodes ). - endloop. + ENDLOOP. - endmethod. + ENDMETHOD. - method convert_table. + METHOD convert_table. - data lo_table type ref to cl_abap_tabledescr. - data lo_ltype type ref to cl_abap_typedescr. - data ls_next_prefix like is_prefix. - data lv_tabix type sy-tabix. - data ls_root like line of ct_nodes. + DATA lo_table TYPE REF TO cl_abap_tabledescr. + DATA lo_ltype TYPE REF TO cl_abap_typedescr. + DATA ls_next_prefix LIKE is_prefix. + DATA lv_tabix TYPE sy-tabix. + DATA ls_root LIKE LINE OF ct_nodes. - field-symbols like ls_root. - field-symbols type any table. - field-symbols type any. + FIELD-SYMBOLS LIKE ls_root. + FIELD-SYMBOLS TYPE ANY TABLE. + FIELD-SYMBOLS TYPE any. " Array root @@ -1584,17 +1611,17 @@ class lcl_abap_to_json implementation. ls_root-index = iv_index. ls_root-order = iv_item_order. - if mi_custom_mapping is bound. + IF mi_custom_mapping IS BOUND. ls_root-name = mi_custom_mapping->to_json( iv_path = is_prefix-path iv_name = is_prefix-name ). - endif. + ENDIF. - if ls_root-name is initial. + IF ls_root-name IS INITIAL. ls_root-name = is_prefix-name. - endif. + ENDIF. - append ls_root to ct_nodes assigning . + APPEND ls_root TO ct_nodes ASSIGNING . " Array items @@ -1602,78 +1629,78 @@ class lcl_abap_to_json implementation. lo_ltype = lo_table->get_table_line_type( ). ls_next_prefix-path = is_prefix-path && -name && '/'. - assign iv_data to . + ASSIGN iv_data TO . lv_tabix = 1. - loop at assigning . + LOOP AT ASSIGNING . ls_next_prefix-name = to_lower( |{ lv_tabix }| ). convert_any( - exporting + EXPORTING iv_data = io_type = lo_ltype is_prefix = ls_next_prefix iv_index = -children + 1 - changing + CHANGING ct_nodes = ct_nodes ). -children = -children + 1. lv_tabix = lv_tabix + 1. - endloop. + ENDLOOP. - endmethod. + ENDMETHOD. - method insert_with_type. + METHOD insert_with_type. - data lo_type type ref to cl_abap_typedescr. - data lo_converter type ref to lcl_abap_to_json. + DATA lo_type TYPE REF TO cl_abap_typedescr. + DATA lo_converter TYPE REF TO lcl_abap_to_json. lo_type = cl_abap_typedescr=>describe_by_data( iv_data ). - create object lo_converter. + CREATE OBJECT lo_converter. lo_converter->mi_custom_mapping = ii_custom_mapping. lo_converter->mv_keep_item_order = is_opts-keep_item_order. lo_converter->mv_format_datetime = is_opts-format_datetime. lo_converter->insert_value_with_type( - exporting + EXPORTING iv_data = iv_data iv_type = iv_type io_type = lo_type is_prefix = is_prefix iv_index = iv_array_index iv_item_order = iv_item_order - changing + CHANGING ct_nodes = rt_nodes ). - endmethod. + ENDMETHOD. - method insert_value_with_type. + METHOD insert_value_with_type. - data lv_prefix type string. - data ls_node like line of ct_nodes. + DATA lv_prefix TYPE string. + DATA ls_node LIKE LINE OF ct_nodes. lv_prefix = is_prefix-path && is_prefix-name. - if io_type->type_kind co lif_kind=>texts or - io_type->type_kind co lif_kind=>date or - io_type->type_kind co lif_kind=>time. - if iv_type = z2ui5_if_ajson_types=>node_type-boolean and iv_data <> 'true' and iv_data <> 'false'. - z2UI5_cx_ajson_error=>raise( |Unexpected boolean value [{ iv_data }] @{ lv_prefix }| ). - elseif iv_type = z2ui5_if_ajson_types=>node_type-null and iv_data is not initial. - z2UI5_cx_ajson_error=>raise( |Unexpected null value [{ iv_data }] @{ lv_prefix }| ). - elseif iv_type = z2ui5_if_ajson_types=>node_type-number and iv_data cn '0123456789. E+-'. - z2UI5_cx_ajson_error=>raise( |Unexpected numeric value [{ iv_data }] @{ lv_prefix }| ). - elseif iv_type <> z2ui5_if_ajson_types=>node_type-string and iv_type <> z2ui5_if_ajson_types=>node_type-boolean - and iv_type <> z2ui5_if_ajson_types=>node_type-null and iv_type <> z2ui5_if_ajson_types=>node_type-number. - z2UI5_cx_ajson_error=>raise( |Unexpected type for value [{ iv_type },{ iv_data }] @{ lv_prefix }| ). - endif. - elseif io_type->type_kind co lif_kind=>numeric. - if iv_type <> z2ui5_if_ajson_types=>node_type-number. - z2UI5_cx_ajson_error=>raise( |Unexpected value for numeric [{ iv_data }] @{ lv_prefix }| ). - endif. - else. - z2UI5_cx_ajson_error=>raise( |Unexpected type [{ io_type->type_kind }] @{ lv_prefix }| ). - endif. + IF io_type->type_kind CO lif_kind=>texts OR + io_type->type_kind CO lif_kind=>date OR + io_type->type_kind CO lif_kind=>time. + IF iv_type = z2ui5_if_ajson_types=>node_type-boolean AND iv_data <> 'true' AND iv_data <> 'false'. + z2ui5_cx_ajson_error=>raise( |Unexpected boolean value [{ iv_data }] @{ lv_prefix }| ). + ELSEIF iv_type = z2ui5_if_ajson_types=>node_type-null AND iv_data IS NOT INITIAL. + z2ui5_cx_ajson_error=>raise( |Unexpected null value [{ iv_data }] @{ lv_prefix }| ). + ELSEIF iv_type = z2ui5_if_ajson_types=>node_type-number AND iv_data CN '0123456789. E+-'. + z2ui5_cx_ajson_error=>raise( |Unexpected numeric value [{ iv_data }] @{ lv_prefix }| ). + ELSEIF iv_type <> z2ui5_if_ajson_types=>node_type-string AND iv_type <> z2ui5_if_ajson_types=>node_type-boolean + AND iv_type <> z2ui5_if_ajson_types=>node_type-null AND iv_type <> z2ui5_if_ajson_types=>node_type-number. + z2ui5_cx_ajson_error=>raise( |Unexpected type for value [{ iv_type },{ iv_data }] @{ lv_prefix }| ). + ENDIF. + ELSEIF io_type->type_kind CO lif_kind=>numeric. + IF iv_type <> z2ui5_if_ajson_types=>node_type-number. + z2ui5_cx_ajson_error=>raise( |Unexpected value for numeric [{ iv_data }] @{ lv_prefix }| ). + ENDIF. + ELSE. + z2ui5_cx_ajson_error=>raise( |Unexpected type [{ io_type->type_kind }] @{ lv_prefix }| ). + ENDIF. ls_node-path = is_prefix-path. ls_node-name = is_prefix-name. @@ -1682,324 +1709,324 @@ class lcl_abap_to_json implementation. ls_node-type = iv_type. ls_node-order = iv_item_order. - if mi_custom_mapping is bound. + IF mi_custom_mapping IS BOUND. ls_node-name = mi_custom_mapping->to_json( iv_path = is_prefix-path iv_name = is_prefix-name ). - endif. + ENDIF. - if ls_node-name is initial. + IF ls_node-name IS INITIAL. ls_node-name = is_prefix-name. - endif. + ENDIF. - append ls_node to ct_nodes. + APPEND ls_node TO ct_nodes. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * MUTATOR INTERFACE ********************************************************************** -interface lif_mutator_runner. - methods run - importing - it_source_tree type z2ui5_if_ajson_types=>ty_nodes_ts - exporting - et_dest_tree type z2ui5_if_ajson_types=>ty_nodes_ts - raising - z2UI5_cx_ajson_error. -endinterface. +INTERFACE lif_mutator_runner. + METHODS run + IMPORTING + it_source_tree TYPE z2ui5_if_ajson_types=>ty_nodes_ts + EXPORTING + et_dest_tree TYPE z2ui5_if_ajson_types=>ty_nodes_ts + RAISING + z2ui5_cx_ajson_error. +ENDINTERFACE. ********************************************************************** * FILTER RUNNER ********************************************************************** -class lcl_filter_runner definition final. - public section. - interfaces lif_mutator_runner. - class-methods new - importing - ii_filter type ref to z2ui5_if_ajson_filter - returning - value(ro_instance) type ref to lcl_filter_runner. - methods constructor - importing - ii_filter type ref to z2ui5_if_ajson_filter. +CLASS lcl_filter_runner DEFINITION FINAL. + PUBLIC SECTION. + INTERFACES lif_mutator_runner. + CLASS-METHODS new + IMPORTING + ii_filter TYPE REF TO z2ui5_if_ajson_filter + RETURNING + VALUE(ro_instance) TYPE REF TO lcl_filter_runner. + METHODS constructor + IMPORTING + ii_filter TYPE REF TO z2ui5_if_ajson_filter. - private section. - data mi_filter type ref to z2ui5_if_ajson_filter. - data mr_source_tree type ref to z2ui5_if_ajson_types=>ty_nodes_ts. - data mr_dest_tree type ref to z2ui5_if_ajson_types=>ty_nodes_ts. + PRIVATE SECTION. + DATA mi_filter TYPE REF TO z2ui5_if_ajson_filter. + DATA mr_source_tree TYPE REF TO z2ui5_if_ajson_types=>ty_nodes_ts. + DATA mr_dest_tree TYPE REF TO z2ui5_if_ajson_types=>ty_nodes_ts. - methods walk - importing - iv_path type string - changing - cs_parent type z2ui5_if_ajson_types=>ty_node optional - raising - z2UI5_cx_ajson_error. + METHODS walk + IMPORTING + iv_path TYPE string + CHANGING + cs_parent TYPE z2ui5_if_ajson_types=>ty_node OPTIONAL + RAISING + z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class lcl_filter_runner implementation. +CLASS lcl_filter_runner IMPLEMENTATION. - method new. - create object ro_instance exporting ii_filter = ii_filter. - endmethod. + METHOD new. + CREATE OBJECT ro_instance EXPORTING ii_filter = ii_filter. + ENDMETHOD. - method constructor. - assert ii_filter is bound. + METHOD constructor. + ASSERT ii_filter IS BOUND. mi_filter = ii_filter. - endmethod. + ENDMETHOD. - method lif_mutator_runner~run. + METHOD lif_mutator_runner~run. - clear et_dest_tree. - get reference of it_source_tree into mr_source_tree. - get reference of et_dest_tree into mr_dest_tree. + CLEAR et_dest_tree. + GET REFERENCE OF it_source_tree INTO mr_source_tree. + GET REFERENCE OF et_dest_tree INTO mr_dest_tree. walk( iv_path = '' ). - endmethod. + ENDMETHOD. - method walk. + METHOD walk. - data ls_node type z2ui5_if_ajson_types=>ty_node. + DATA ls_node TYPE z2ui5_if_ajson_types=>ty_node. - loop at mr_source_tree->* into ls_node where path = iv_path. - case ls_node-type. - when z2ui5_if_ajson_types=>node_type-boolean or z2ui5_if_ajson_types=>node_type-null - or z2ui5_if_ajson_types=>node_type-number or z2ui5_if_ajson_types=>node_type-string. + LOOP AT mr_source_tree->* INTO ls_node WHERE path = iv_path. + CASE ls_node-type. + WHEN z2ui5_if_ajson_types=>node_type-boolean OR z2ui5_if_ajson_types=>node_type-null + OR z2ui5_if_ajson_types=>node_type-number OR z2ui5_if_ajson_types=>node_type-string. - if mi_filter->keep_node( ls_node ) = abap_false. - continue. - endif. + IF mi_filter->keep_node( ls_node ) = abap_false. + CONTINUE. + ENDIF. - when z2ui5_if_ajson_types=>node_type-array or z2ui5_if_ajson_types=>node_type-object. + WHEN z2ui5_if_ajson_types=>node_type-array OR z2ui5_if_ajson_types=>node_type-object. - if mi_filter->keep_node( + IF mi_filter->keep_node( is_node = ls_node iv_visit = z2ui5_if_ajson_filter=>visit_type-open ) = abap_false. - continue. - endif. + CONTINUE. + ENDIF. " Intentionally clear AFTER "open" - clear ls_node-children. + CLEAR ls_node-children. walk( - exporting + EXPORTING iv_path = iv_path && ls_node-name && `/` - changing + CHANGING cs_parent = ls_node ). - if mi_filter->keep_node( + IF mi_filter->keep_node( is_node = ls_node iv_visit = z2ui5_if_ajson_filter=>visit_type-close ) = abap_false. - continue. - endif. + CONTINUE. + ENDIF. - when others. - z2UI5_cx_ajson_error=>raise( |Unexpected node type { ls_node-type }| ). - endcase. + WHEN OTHERS. + z2ui5_cx_ajson_error=>raise( |Unexpected node type { ls_node-type }| ). + ENDCASE. - if cs_parent is supplied. + IF cs_parent IS SUPPLIED. cs_parent-children = cs_parent-children + 1. - if cs_parent-type = z2ui5_if_ajson_types=>node_type-array. + IF cs_parent-type = z2ui5_if_ajson_types=>node_type-array. ls_node-name = |{ cs_parent-children }|. ls_node-index = cs_parent-children. - endif. - endif. - insert ls_node into table mr_dest_tree->*. + ENDIF. + ENDIF. + INSERT ls_node INTO TABLE mr_dest_tree->*. - endloop. + ENDLOOP. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * MAPPER RUNNER ********************************************************************** -class lcl_mapper_runner definition final. - public section. - interfaces lif_mutator_runner. - class-methods new - importing - ii_mapper type ref to z2ui5_if_ajson_mapping - returning - value(ro_instance) type ref to lcl_mapper_runner. - methods constructor - importing - ii_mapper type ref to z2ui5_if_ajson_mapping. +CLASS lcl_mapper_runner DEFINITION FINAL. + PUBLIC SECTION. + INTERFACES lif_mutator_runner. + CLASS-METHODS new + IMPORTING + ii_mapper TYPE REF TO z2ui5_if_ajson_mapping + RETURNING + VALUE(ro_instance) TYPE REF TO lcl_mapper_runner. + METHODS constructor + IMPORTING + ii_mapper TYPE REF TO z2ui5_if_ajson_mapping. - private section. - data mi_mapper type ref to z2ui5_if_ajson_mapping. - data mr_source_tree type ref to z2ui5_if_ajson_types=>ty_nodes_ts. - data mr_dest_tree type ref to z2ui5_if_ajson_types=>ty_nodes_ts. + PRIVATE SECTION. + DATA mi_mapper TYPE REF TO z2ui5_if_ajson_mapping. + DATA mr_source_tree TYPE REF TO z2ui5_if_ajson_types=>ty_nodes_ts. + DATA mr_dest_tree TYPE REF TO z2ui5_if_ajson_types=>ty_nodes_ts. - methods process_deep_node - importing - iv_path type string - iv_renamed_path type string - iv_node_type type z2ui5_if_ajson_types=>ty_node-type - raising - z2UI5_cx_ajson_error. + METHODS process_deep_node + IMPORTING + iv_path TYPE string + iv_renamed_path TYPE string + iv_node_type TYPE z2ui5_if_ajson_types=>ty_node-type + RAISING + z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class lcl_mapper_runner implementation. +CLASS lcl_mapper_runner IMPLEMENTATION. - method new. - create object ro_instance exporting ii_mapper = ii_mapper. - endmethod. + METHOD new. + CREATE OBJECT ro_instance EXPORTING ii_mapper = ii_mapper. + ENDMETHOD. - method constructor. - assert ii_mapper is bound. + METHOD constructor. + ASSERT ii_mapper IS BOUND. mi_mapper = ii_mapper. - endmethod. + ENDMETHOD. - method lif_mutator_runner~run. + METHOD lif_mutator_runner~run. - field-symbols like line of it_source_tree. + FIELD-SYMBOLS LIKE LINE OF it_source_tree. - read table it_source_tree with key path = `` name = `` assigning . - if sy-subrc <> 0 - or not ( -type = z2ui5_if_ajson_types=>node_type-array or -type = z2ui5_if_ajson_types=>node_type-object ). + READ TABLE it_source_tree WITH KEY path = `` name = `` ASSIGNING . + IF sy-subrc <> 0 + OR NOT ( -type = z2ui5_if_ajson_types=>node_type-array OR -type = z2ui5_if_ajson_types=>node_type-object ). " empty or one-value-only tree et_dest_tree = it_source_tree. - return. - endif. + RETURN. + ENDIF. - clear et_dest_tree. - get reference of it_source_tree into mr_source_tree. - get reference of et_dest_tree into mr_dest_tree. - insert into table et_dest_tree. + CLEAR et_dest_tree. + GET REFERENCE OF it_source_tree INTO mr_source_tree. + GET REFERENCE OF et_dest_tree INTO mr_dest_tree. + INSERT INTO TABLE et_dest_tree. process_deep_node( iv_path = `/` iv_renamed_path = `/` iv_node_type = -type ). - endmethod. + ENDMETHOD. - method process_deep_node. + METHOD process_deep_node. - field-symbols like line of mr_source_tree->*. - data ls_renamed_node like . + FIELD-SYMBOLS LIKE LINE OF mr_source_tree->*. + DATA ls_renamed_node LIKE . - loop at mr_source_tree->* assigning where path = iv_path. + LOOP AT mr_source_tree->* ASSIGNING WHERE path = iv_path. ls_renamed_node = . - if iv_node_type <> z2ui5_if_ajson_types=>node_type-array. + IF iv_node_type <> z2ui5_if_ajson_types=>node_type-array. " don't rename array item names -> they are numeric index mi_mapper->rename_node( - exporting + EXPORTING is_node = - changing + CHANGING cv_name = ls_renamed_node-name ). - if ls_renamed_node-name is initial. - z2UI5_cx_ajson_error=>raise( + IF ls_renamed_node-name IS INITIAL. + z2ui5_cx_ajson_error=>raise( iv_msg = 'Renamed node name cannot be empty' is_node = ). - endif. - endif. + ENDIF. + ENDIF. ls_renamed_node-path = iv_renamed_path. - insert ls_renamed_node into table mr_dest_tree->*. - if sy-subrc <> 0. " = 4 ? - z2UI5_cx_ajson_error=>raise( + INSERT ls_renamed_node INTO TABLE mr_dest_tree->*. + IF sy-subrc <> 0. " = 4 ? + z2ui5_cx_ajson_error=>raise( iv_msg = 'Renamed node has a duplicate' is_node = ls_renamed_node ). - endif. + ENDIF. " maybe also catch CX_SY_ITAB_DUPLICATE_KEY but secondary keys are not changed here, so not for now - if -type = z2ui5_if_ajson_types=>node_type-array or -type = z2ui5_if_ajson_types=>node_type-object. + IF -type = z2ui5_if_ajson_types=>node_type-array OR -type = z2ui5_if_ajson_types=>node_type-object. process_deep_node( iv_path = iv_path && -name && `/` iv_renamed_path = iv_renamed_path && ls_renamed_node-name && `/` iv_node_type = -type ). - endif. + ENDIF. - endloop. + ENDLOOP. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * MUTATOR QUEUE ********************************************************************** -class lcl_mutator_queue definition final. - public section. - interfaces lif_mutator_runner. - class-methods new - returning - value(ro_instance) type ref to lcl_mutator_queue. - methods add - importing - ii_mutator type ref to lif_mutator_runner - returning - value(ro_self) type ref to lcl_mutator_queue. +CLASS lcl_mutator_queue DEFINITION FINAL. + PUBLIC SECTION. + INTERFACES lif_mutator_runner. + CLASS-METHODS new + RETURNING + VALUE(ro_instance) TYPE REF TO lcl_mutator_queue. + METHODS add + IMPORTING + ii_mutator TYPE REF TO lif_mutator_runner + RETURNING + VALUE(ro_self) TYPE REF TO lcl_mutator_queue. - private section. - data mt_queue type standard table of ref to lif_mutator_runner. + PRIVATE SECTION. + DATA mt_queue TYPE STANDARD TABLE OF REF TO lif_mutator_runner. -endclass. +ENDCLASS. -class lcl_mutator_queue implementation. +CLASS lcl_mutator_queue IMPLEMENTATION. - method add. - if ii_mutator is bound. - append ii_mutator to mt_queue. - endif. + METHOD add. + IF ii_mutator IS BOUND. + APPEND ii_mutator TO mt_queue. + ENDIF. ro_self = me. - endmethod. + ENDMETHOD. - method new. - create object ro_instance. - endmethod. + METHOD new. + CREATE OBJECT ro_instance. + ENDMETHOD. - method lif_mutator_runner~run. + METHOD lif_mutator_runner~run. - data li_mutator type ref to lif_mutator_runner. - data lv_qsize type i. - field-symbols like it_source_tree. - field-symbols like it_source_tree. - data lr_buf type ref to z2ui5_if_ajson_types=>ty_nodes_ts. + DATA li_mutator TYPE REF TO lif_mutator_runner. + DATA lv_qsize TYPE i. + FIELD-SYMBOLS LIKE it_source_tree. + FIELD-SYMBOLS LIKE it_source_tree. + DATA lr_buf TYPE REF TO z2ui5_if_ajson_types=>ty_nodes_ts. lv_qsize = lines( mt_queue ). - if lv_qsize = 0. + IF lv_qsize = 0. et_dest_tree = it_source_tree. - return. - endif. + RETURN. + ENDIF. - loop at mt_queue into li_mutator. - if sy-tabix = 1. - assign it_source_tree to . - else. - assign lr_buf->* to . - endif. + LOOP AT mt_queue INTO li_mutator. + IF sy-tabix = 1. + ASSIGN it_source_tree TO . + ELSE. + ASSIGN lr_buf->* TO . + ENDIF. - if sy-tabix = lv_qsize. - assign et_dest_tree to . - else. - create data lr_buf. - assign lr_buf->* to . - endif. + IF sy-tabix = lv_qsize. + ASSIGN et_dest_tree TO . + ELSE. + CREATE DATA lr_buf. + ASSIGN lr_buf->* TO . + ENDIF. li_mutator->run( - exporting + EXPORTING it_source_tree = - importing + IMPORTING et_dest_tree = ). - endloop. + ENDLOOP. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. diff --git a/src/01/00/01/z2ui5_cl_ajson.clas.testclasses.abap b/src/01/00/01/z2ui5_cl_ajson.clas.testclasses.abap index 75a68df7..0492c13e 100644 --- a/src/01/00/01/z2ui5_cl_ajson.clas.testclasses.abap +++ b/src/01/00/01/z2ui5_cl_ajson.clas.testclasses.abap @@ -1,31 +1,31 @@ ********************************************************************** * UTIL ********************************************************************** -class lcl_nodes_helper definition final. - public section. +CLASS lcl_nodes_helper DEFINITION FINAL. + PUBLIC SECTION. - data mt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. - methods add - importing - iv_str type string. - methods clear. - methods sorted - returning - value(rt_nodes) type z2ui5_if_ajson_types=>ty_nodes_ts. + DATA mt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + METHODS add + IMPORTING + iv_str TYPE string. + METHODS clear. + METHODS sorted + RETURNING + VALUE(rt_nodes) TYPE z2ui5_if_ajson_types=>ty_nodes_ts. -endclass. +ENDCLASS. -class lcl_nodes_helper implementation. - method add. +CLASS lcl_nodes_helper IMPLEMENTATION. + METHOD add. - field-symbols like line of mt_nodes. - data lv_children type string. - data lv_index type string. - data lv_order type string. + FIELD-SYMBOLS LIKE LINE OF mt_nodes. + DATA lv_children TYPE string. + DATA lv_index TYPE string. + DATA lv_order TYPE string. - append initial line to mt_nodes assigning . + APPEND INITIAL LINE TO mt_nodes ASSIGNING . - split iv_str at '|' into + SPLIT iv_str AT '|' INTO -path -name -type @@ -33,73 +33,73 @@ class lcl_nodes_helper implementation. lv_index lv_children lv_order. - condense -path. - condense -name. - condense -type. - condense -value. + CONDENSE -path. + CONDENSE -name. + CONDENSE -type. + CONDENSE -value. -index = lv_index. -children = lv_children. -order = lv_order. - endmethod. + ENDMETHOD. - method sorted. + METHOD sorted. rt_nodes = mt_nodes. - endmethod. + ENDMETHOD. - method clear. - clear mt_nodes. - endmethod. -endclass. + METHOD clear. + CLEAR mt_nodes. + ENDMETHOD. +ENDCLASS. ********************************************************************** * PARSER ********************************************************************** -class ltcl_parser_test definition final - for testing - risk level harmless - duration short. +CLASS ltcl_parser_test DEFINITION FINAL + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. - public section. + PUBLIC SECTION. - class-methods sample_json - importing - iv_separator type string optional - returning - value(rv_json) type string. + CLASS-METHODS sample_json + IMPORTING + iv_separator TYPE string OPTIONAL + RETURNING + VALUE(rv_json) TYPE string. - private section. - data mo_cut type ref to lcl_json_parser. - data mo_nodes type ref to lcl_nodes_helper. + PRIVATE SECTION. + DATA mo_cut TYPE REF TO lcl_json_parser. + DATA mo_nodes TYPE REF TO lcl_nodes_helper. - methods setup. - methods parse for testing raising z2UI5_cx_ajson_error. - methods parse_keeping_order for testing raising z2UI5_cx_ajson_error. - methods parse_string for testing raising z2UI5_cx_ajson_error. - methods parse_number for testing raising z2UI5_cx_ajson_error. - methods parse_float for testing raising z2UI5_cx_ajson_error. - methods parse_boolean for testing raising z2UI5_cx_ajson_error. - methods parse_false for testing raising z2UI5_cx_ajson_error. - methods parse_null for testing raising z2UI5_cx_ajson_error. - methods parse_date for testing raising z2UI5_cx_ajson_error. - methods parse_bare_values for testing raising z2UI5_cx_ajson_error. - methods parse_error for testing raising z2UI5_cx_ajson_error. - methods duplicate_key for testing raising z2UI5_cx_ajson_error. - methods non_json for testing raising z2UI5_cx_ajson_error. + METHODS setup. + METHODS parse FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_keeping_order FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_string FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_number FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_float FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_boolean FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_false FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_null FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_date FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_bare_values FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS parse_error FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS duplicate_key FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS non_json FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class ltcl_parser_test implementation. +CLASS ltcl_parser_test IMPLEMENTATION. - method setup. - create object mo_cut. - create object mo_nodes. - endmethod. + METHOD setup. + CREATE OBJECT mo_cut. + CREATE OBJECT mo_nodes. + ENDMETHOD. - method parse_bare_values. + METHOD parse_bare_values. - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. mo_nodes->add( ' | |str |abc | |0' ). lt_act = mo_cut->parse( '"abc"' ). @@ -135,120 +135,120 @@ class ltcl_parser_test implementation. act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_error. + METHOD parse_error. - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. - data lx_err type ref to z2UI5_cx_ajson_error. - try. - lt_act = mo_cut->parse( 'abc' ). - cl_abap_unit_assert=>fail( 'Parsing of string w/o quotes must fail (spec)' ). - catch z2UI5_cx_ajson_error into lx_err. - cl_abap_unit_assert=>assert_char_cp( - act = lx_err->get_text( ) - exp = '*parsing error*' ). - cl_abap_unit_assert=>assert_char_cp( - act = lx_err->location - exp = 'Line 1, Offset 1' ). - endtry. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lx_err TYPE REF TO z2ui5_cx_ajson_error. + TRY. + lt_act = mo_cut->parse( 'abc' ). + cl_abap_unit_assert=>fail( 'Parsing of string w/o quotes must fail (spec)' ). + CATCH z2ui5_cx_ajson_error INTO lx_err. + cl_abap_unit_assert=>assert_char_cp( + act = lx_err->get_text( ) + exp = '*parsing error*' ). + cl_abap_unit_assert=>assert_char_cp( + act = lx_err->location + exp = 'Line 1, Offset 1' ). + ENDTRY. - try. - lt_act = mo_cut->parse( '{' && cl_abap_char_utilities=>newline - && '"ok": "abc",' && cl_abap_char_utilities=>newline - && '"error"' && cl_abap_char_utilities=>newline - && '}' ). - cl_abap_unit_assert=>fail( 'Parsing of invalid JSON must fail (spec)' ). - catch z2UI5_cx_ajson_error into lx_err. - cl_abap_unit_assert=>assert_char_cp( - act = lx_err->get_text( ) - exp = '*parsing error*' ). - cl_abap_unit_assert=>assert_char_cp( - act = lx_err->location - exp = 'Line 3, Offset 8' ). - endtry. + TRY. + lt_act = mo_cut->parse( '{' && cl_abap_char_utilities=>newline + && '"ok": "abc",' && cl_abap_char_utilities=>newline + && '"error"' && cl_abap_char_utilities=>newline + && '}' ). + cl_abap_unit_assert=>fail( 'Parsing of invalid JSON must fail (spec)' ). + CATCH z2ui5_cx_ajson_error INTO lx_err. + cl_abap_unit_assert=>assert_char_cp( + act = lx_err->get_text( ) + exp = '*parsing error*' ). + cl_abap_unit_assert=>assert_char_cp( + act = lx_err->location + exp = 'Line 3, Offset 8' ). + ENDTRY. - endmethod. + ENDMETHOD. - method parse_string. + METHOD parse_string. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |string |str |abc | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_act = mo_cut->parse( '{"string": "abc"}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_number. + METHOD parse_number. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |number |num |123 | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_act = mo_cut->parse( '{"number": 123}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_float. + METHOD parse_float. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |float |num |123.45 | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. - create object mo_cut. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + CREATE OBJECT mo_cut. lt_act = mo_cut->parse( '{"float": 123.45}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_boolean. + METHOD parse_boolean. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |boolean |bool |true | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_act = mo_cut->parse( '{"boolean": true}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_false. + METHOD parse_false. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |false |bool |false | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_act = mo_cut->parse( '{"false": false}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_null. + METHOD parse_null. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |null |null | | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_act = mo_cut->parse( '{"null": null}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_date. + METHOD parse_date. mo_nodes->add( ' | |object | | |1' ). mo_nodes->add( '/ |date |str |2020-03-15 | |0' ). - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_act = mo_cut->parse( '{"date": "2020-03-15"}' ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = mo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method sample_json. + METHOD sample_json. rv_json = '{\n' && @@ -289,17 +289,17 @@ class ltcl_parser_test implementation. ' ]\n' && '}'. - replace all occurrences of '\n' in rv_json with iv_separator. + REPLACE ALL OCCURRENCES OF '\n' IN rv_json WITH iv_separator. - endmethod. + ENDMETHOD. - method parse. + METHOD parse. - data lo_cut type ref to lcl_json_parser. - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_parser. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |8' ). lo_nodes->add( '/ |string |str |abc | |0' ). lo_nodes->add( '/ |number |num |123 | |0' ). @@ -330,7 +330,7 @@ class ltcl_parser_test implementation. lo_nodes->add( '/issues/2/end/ |col |num |22 | |0' ). lo_nodes->add( '/issues/2/ |filename |str |./zxxx.prog.abap | |0' ). - create object lo_cut. + CREATE OBJECT lo_cut. lt_act = lo_cut->parse( sample_json( ) ). cl_abap_unit_assert=>assert_equals( act = lt_act @@ -346,15 +346,15 @@ class ltcl_parser_test implementation. act = lt_act exp = lo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method parse_keeping_order. + METHOD parse_keeping_order. - data lo_cut type ref to lcl_json_parser. - data lt_act type z2ui5_if_ajson_types=>ty_nodes_tt. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_parser. + DATA lt_act TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |8 |0' ). lo_nodes->add( '/ |string |str |abc | |0 |1' ). lo_nodes->add( '/ |number |num |123 | |0 |2' ). @@ -385,7 +385,7 @@ class ltcl_parser_test implementation. lo_nodes->add( '/issues/2/end/ |col |num |22 | |0 |2' ). lo_nodes->add( '/issues/2/ |filename |str |./zxxx.prog.abap | |0 |5' ). - create object lo_cut. + CREATE OBJECT lo_cut. lt_act = lo_cut->parse( iv_json = sample_json( ) iv_keep_item_order = abap_true ). @@ -407,74 +407,74 @@ class ltcl_parser_test implementation. act = lt_act exp = lo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method duplicate_key. + METHOD duplicate_key. - data lo_cut type ref to lcl_json_parser. - data lx type ref to z2UI5_cx_ajson_error. + DATA lo_cut TYPE REF TO lcl_json_parser. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. - try. - create object lo_cut. - lo_cut->parse( '{ "a" = 1, "a" = 1 }' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_not_initial( lx ). - endtry. + TRY. + CREATE OBJECT lo_cut. + lo_cut->parse( '{ "a" = 1, "a" = 1 }' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_not_initial( lx ). + ENDTRY. - endmethod. + ENDMETHOD. - method non_json. + METHOD non_json. - data lo_cut type ref to lcl_json_parser. - data lx type ref to z2UI5_cx_ajson_error. + DATA lo_cut TYPE REF TO lcl_json_parser. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. - try. - create object lo_cut. - lo_cut->parse( 'X

Y

' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_not_initial( lx ). - endtry. + TRY. + CREATE OBJECT lo_cut. + lo_cut->parse( 'X

Y

' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_not_initial( lx ). + ENDTRY. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * SERIALIZER ********************************************************************** -class ltcl_serializer_test definition final - for testing - risk level harmless - duration short. +CLASS ltcl_serializer_test DEFINITION FINAL + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. - public section. + PUBLIC SECTION. - class-methods sample_json - returning - value(rv_json) type string. - class-methods sample_nodes - returning - value(rt_nodes) type z2ui5_if_ajson_types=>ty_nodes_ts. + CLASS-METHODS sample_json + RETURNING + VALUE(rv_json) TYPE string. + CLASS-METHODS sample_nodes + RETURNING + VALUE(rt_nodes) TYPE z2ui5_if_ajson_types=>ty_nodes_ts. - private section. + PRIVATE SECTION. - methods stringify_condensed for testing raising z2UI5_cx_ajson_error. - methods stringify_indented for testing raising z2UI5_cx_ajson_error. - methods array_index for testing raising z2UI5_cx_ajson_error. - methods item_order for testing raising z2UI5_cx_ajson_error. - methods simple_indented for testing raising z2UI5_cx_ajson_error. - methods empty_set for testing raising z2UI5_cx_ajson_error. - methods escape_string for testing raising z2UI5_cx_ajson_error. - methods empty for testing raising z2UI5_cx_ajson_error. + METHODS stringify_condensed FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS stringify_indented FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS array_index FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS item_order FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS simple_indented FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS empty_set FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS escape_string FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS empty FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class ltcl_serializer_test implementation. +CLASS ltcl_serializer_test IMPLEMENTATION. - method sample_json. + METHOD sample_json. rv_json = '{\n' && @@ -521,13 +521,13 @@ class ltcl_serializer_test implementation. with = cl_abap_char_utilities=>newline occ = 0 ). - endmethod. + ENDMETHOD. - method sample_nodes. + METHOD sample_nodes. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |8' ). lo_nodes->add( '/ |string |str |abc | |0' ). lo_nodes->add( '/ |number |num |123 | |0' ). @@ -560,12 +560,12 @@ class ltcl_serializer_test implementation. rt_nodes = lo_nodes->sorted( ). - endmethod. + ENDMETHOD. - method stringify_condensed. + METHOD stringify_condensed. - data lv_act type string. - data lv_exp type string. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. lv_act = lcl_json_serializer=>stringify( sample_nodes( ) ). lv_exp = sample_json( ). @@ -575,7 +575,7 @@ class ltcl_serializer_test implementation. sub = cl_abap_char_utilities=>newline with = '' occ = 0 ). - condense lv_exp. + CONDENSE lv_exp. lv_exp = replace( val = lv_exp sub = `: ` @@ -611,12 +611,12 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method stringify_indented. + METHOD stringify_indented. - data lv_act type string. - data lv_exp type string. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. lv_act = lcl_json_serializer=>stringify( it_json_tree = sample_nodes( ) @@ -627,15 +627,15 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method array_index. + METHOD array_index. - data lv_act type string. - data lv_exp type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | |3' ). lo_nodes->add( '/ |1 |str |abc |2 |0' ). lo_nodes->add( '/ |2 |num |123 |1 |0' ). @@ -648,15 +648,15 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method item_order. + METHOD item_order. - data lv_act type string. - data lv_exp type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |3 |0' ). lo_nodes->add( '/ |beta |str |b | |0 |3' ). lo_nodes->add( '/ |zulu |str |z | |0 |1' ). @@ -678,15 +678,15 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method simple_indented. + METHOD simple_indented. - data lv_act type string. - data lv_exp type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | |3' ). lo_nodes->add( '/ |1 |object | |2 |2' ). lo_nodes->add( '/1/ |a |num |1 | |0' ). @@ -715,15 +715,15 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method empty_set. + METHOD empty_set. - data lv_act type string. - data lv_exp type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | |0' ). lv_act = lcl_json_serializer=>stringify( @@ -744,16 +744,16 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method escape_string. + METHOD escape_string. - data lv_act type string. - data lv_exp type string. - data lv_val type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA lv_val TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lv_val = 'a' && '"' && '\' && cl_abap_char_utilities=>horizontal_tab && cl_abap_char_utilities=>cr_lf. lo_nodes->add( | \| \|str \|{ lv_val }\| \|0| ). @@ -764,15 +764,15 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method empty. + METHOD empty. - data lv_act type string. - data lv_exp type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lv_act = lcl_json_serializer=>stringify( lo_nodes->sorted( ) ). lv_exp = ''. @@ -781,61 +781,61 @@ class ltcl_serializer_test implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * UTILS ********************************************************************** -class ltcl_utils_test definition final - for testing - risk level harmless - duration short. +CLASS ltcl_utils_test DEFINITION FINAL + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. - private section. + PRIVATE SECTION. - methods normalize_path for testing. - methods split_path for testing. - methods validate_array_index for testing raising z2UI5_cx_ajson_error. - methods string_to_xstring_utf8 for testing. + METHODS normalize_path FOR TESTING. + METHODS split_path FOR TESTING. + METHODS validate_array_index FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS string_to_xstring_utf8 FOR TESTING. -endclass. +ENDCLASS. -class z2ui5_cl_ajson definition local friends ltcl_utils_test. +CLASS z2ui5_cl_ajson DEFINITION LOCAL FRIENDS ltcl_utils_test. -class ltcl_utils_test implementation. +CLASS ltcl_utils_test IMPLEMENTATION. - method string_to_xstring_utf8. + METHOD string_to_xstring_utf8. cl_abap_unit_assert=>assert_equals( act = lcl_utils=>string_to_xstring_utf8( '123' ) exp = '313233' ). - endmethod. + ENDMETHOD. - method validate_array_index. + METHOD validate_array_index. cl_abap_unit_assert=>assert_equals( act = lcl_utils=>validate_array_index( iv_path = 'x' iv_index = '123' ) exp = 123 ). - try. - lcl_utils=>validate_array_index( iv_path = 'x' iv_index = 'a' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + lcl_utils=>validate_array_index( iv_path = 'x' iv_index = 'a' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - try. - lcl_utils=>validate_array_index( iv_path = 'x' iv_index = '0' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + lcl_utils=>validate_array_index( iv_path = 'x' iv_index = '0' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - endmethod. + ENDMETHOD. - method normalize_path. + METHOD normalize_path. cl_abap_unit_assert=>assert_equals( act = lcl_utils=>normalize_path( '' ) @@ -856,12 +856,12 @@ class ltcl_utils_test implementation. act = lcl_utils=>normalize_path( '/abc/' ) exp = '/abc/' ). - endmethod. + ENDMETHOD. - method split_path. + METHOD split_path. - data ls_exp type z2ui5_if_ajson_types=>ty_path_name. - data lv_path type string. + DATA ls_exp TYPE z2ui5_if_ajson_types=>ty_path_name. + DATA lv_path TYPE string. lv_path = ''. " alias to root ls_exp-path = ''. @@ -919,46 +919,46 @@ class ltcl_utils_test implementation. act = lcl_utils=>split_path( lv_path ) exp = ls_exp ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * READER ********************************************************************** -class ltcl_reader_test definition final - for testing - risk level harmless - duration short. +CLASS ltcl_reader_test DEFINITION FINAL + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. - private section. + PRIVATE SECTION. - methods get_value for testing raising z2UI5_cx_ajson_error. - methods get_node_type for testing raising z2UI5_cx_ajson_error. - methods exists for testing raising z2UI5_cx_ajson_error. - methods value_integer for testing raising z2UI5_cx_ajson_error. - methods value_number for testing raising z2UI5_cx_ajson_error. - methods value_boolean for testing raising z2UI5_cx_ajson_error. - methods value_string for testing raising z2UI5_cx_ajson_error. - methods members for testing raising z2UI5_cx_ajson_error. - methods slice for testing raising z2UI5_cx_ajson_error. - methods array_to_string_table for testing raising z2UI5_cx_ajson_error. - methods get_date for testing raising z2UI5_cx_ajson_error. - methods get_timestamp for testing raising z2UI5_cx_ajson_error. + METHODS get_value FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS get_node_type FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS exists FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS value_integer FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS value_number FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS value_boolean FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS value_string FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS members FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS slice FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS array_to_string_table FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS get_date FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS get_timestamp FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class z2ui5_cl_ajson definition local friends ltcl_reader_test. +CLASS z2ui5_cl_ajson DEFINITION LOCAL FRIENDS ltcl_reader_test. -class ltcl_reader_test implementation. +CLASS ltcl_reader_test IMPLEMENTATION. - method slice. + METHOD slice. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | |2' ). lo_nodes->add( '/ |1 |object | |1 |5' ). lo_nodes->add( '/1/ |message |str |Indentation problem ... | |0' ). @@ -990,7 +990,7 @@ class ltcl_reader_test implementation. " ********************************************************************** - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |8' ). lo_nodes->add( '/ |string |str |abc | |0' ). lo_nodes->add( '/ |number |num |123 | |0' ). @@ -1029,7 +1029,7 @@ class ltcl_reader_test implementation. " ********************************************************************** - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |2' ). lo_nodes->add( '/ |row |num |3 | |0' ). lo_nodes->add( '/ |col |num |21 | |0' ). @@ -1040,11 +1040,11 @@ class ltcl_reader_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method get_value. + METHOD get_value. - data lo_cut type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). cl_abap_unit_assert=>assert_equals( @@ -1063,11 +1063,11 @@ class ltcl_reader_test implementation. act = lo_cut->get( '/issues/2/start/row' ) exp = '3' ). - endmethod. + ENDMETHOD. - method get_node_type. + METHOD get_node_type. - data li_cut type ref to z2ui5_if_ajson. + DATA li_cut TYPE REF TO z2ui5_if_ajson. li_cut = z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). cl_abap_unit_assert=>assert_equals( @@ -1098,18 +1098,18 @@ class ltcl_reader_test implementation. act = li_cut->get_node_type( '/issues' ) exp = z2ui5_if_ajson_types=>node_type-array ). - endmethod. + ENDMETHOD. - method get_date. + METHOD get_date. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes type ref to lcl_nodes_helper. - data lv_exp type d. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lv_exp TYPE d. - create object lo_cut. + CREATE OBJECT lo_cut. lv_exp = '20200728'. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |date1 |str |2020-07-28 | |0' ). lo_cut->mt_json_tree = lo_nodes->mt_nodes. @@ -1118,7 +1118,7 @@ class ltcl_reader_test implementation. act = lo_cut->z2ui5_if_ajson~get_date( '/date1' ) exp = lv_exp ). - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |date1 |str |2020-07-28T01:00:00Z | |0' ). lo_cut->mt_json_tree = lo_nodes->mt_nodes. @@ -1127,7 +1127,7 @@ class ltcl_reader_test implementation. act = lo_cut->z2ui5_if_ajson~get_date( '/date1' ) exp = lv_exp ). - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |date1 |str |20200728 | |0' ). lo_cut->mt_json_tree = lo_nodes->mt_nodes. @@ -1136,17 +1136,17 @@ class ltcl_reader_test implementation. act = lo_cut->z2ui5_if_ajson~get_date( '/date1' ) exp = '' ). - endmethod. + ENDMETHOD. - method get_timestamp. + METHOD get_timestamp. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes type ref to lcl_nodes_helper. - data lv_exp type timestamp value `20200728000000`. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lv_exp TYPE timestamp VALUE `20200728000000`. - create object lo_cut. + CREATE OBJECT lo_cut. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |timestamp|str |2020-07-28T00:00:00Z | |0' ). lo_cut->mt_json_tree = lo_nodes->mt_nodes. @@ -1155,11 +1155,11 @@ class ltcl_reader_test implementation. act = lo_cut->z2ui5_if_ajson~get_timestamp( '/timestamp' ) exp = lv_exp ). - endmethod. + ENDMETHOD. - method exists. + METHOD exists. - data lo_cut type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). @@ -1179,11 +1179,11 @@ class ltcl_reader_test implementation. act = lo_cut->exists( '/issues/2/start/row' ) exp = abap_true ). - endmethod. + ENDMETHOD. - method value_integer. + METHOD value_integer. - data lo_cut type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). cl_abap_unit_assert=>assert_equals( @@ -1198,11 +1198,11 @@ class ltcl_reader_test implementation. act = lo_cut->get_integer( '/float' ) exp = 123 ). - endmethod. + ENDMETHOD. - method value_number. + METHOD value_number. - data lo_cut type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). cl_abap_unit_assert=>assert_equals( @@ -1217,11 +1217,11 @@ class ltcl_reader_test implementation. act = lo_cut->get_number( '/float' ) exp = +'123.45' ). - endmethod. + ENDMETHOD. - method value_boolean. + METHOD value_boolean. - data lo_cut type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). cl_abap_unit_assert=>assert_equals( @@ -1240,11 +1240,11 @@ class ltcl_reader_test implementation. act = lo_cut->get_boolean( '/boolean' ) exp = abap_true ). - endmethod. + ENDMETHOD. - method value_string. + METHOD value_string. - data lo_cut type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). cl_abap_unit_assert=>assert_equals( @@ -1263,38 +1263,38 @@ class ltcl_reader_test implementation. act = lo_cut->get_string( '/boolean' ) exp = 'true' ). - endmethod. + ENDMETHOD. - method members. + METHOD members. - data lt_exp type string_table. - data lo_cut type ref to z2ui5_if_ajson. + DATA lt_exp TYPE string_table. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. lo_cut ?= z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). - clear lt_exp. - append '1' to lt_exp. - append '2' to lt_exp. + CLEAR lt_exp. + APPEND '1' TO lt_exp. + APPEND '2' TO lt_exp. cl_abap_unit_assert=>assert_equals( act = lo_cut->members( '/issues' ) exp = lt_exp ). - clear lt_exp. - append 'col' to lt_exp. - append 'row' to lt_exp. + CLEAR lt_exp. + APPEND 'col' TO lt_exp. + APPEND 'row' TO lt_exp. cl_abap_unit_assert=>assert_equals( act = lo_cut->members( '/issues/1/start/' ) exp = lt_exp ). - endmethod. + ENDMETHOD. - method array_to_string_table. + METHOD array_to_string_table. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes type ref to lcl_nodes_helper. - data lt_act type string_table. - data lt_exp type string_table. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lt_act TYPE string_table. + DATA lt_exp TYPE string_table. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | |6' ). lo_nodes->add( '/ |1 |num |123 |1|0' ). lo_nodes->add( '/ |2 |num |234 |2|0' ). @@ -1303,14 +1303,14 @@ class ltcl_reader_test implementation. lo_nodes->add( '/ |5 |bool |false |5|0' ). lo_nodes->add( '/ |6 |null |null |6|0' ). - append '123' to lt_exp. - append '234' to lt_exp. - append 'abc' to lt_exp. - append 'X' to lt_exp. - append '' to lt_exp. - append '' to lt_exp. + APPEND '123' TO lt_exp. + APPEND '234' TO lt_exp. + APPEND 'abc' TO lt_exp. + APPEND 'X' TO lt_exp. + APPEND '' TO lt_exp. + APPEND '' TO lt_exp. - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->mt_json_tree = lo_nodes->mt_nodes. lt_act = lo_cut->z2ui5_if_ajson~array_to_string_table( '/' ). @@ -1319,161 +1319,164 @@ class ltcl_reader_test implementation. exp = lt_exp ). " negative - data lx type ref to z2UI5_cx_ajson_error. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |a |str |abc | |0' ). lo_cut->mt_json_tree = lo_nodes->mt_nodes. - try. - lo_cut->z2ui5_if_ajson~array_to_string_table( '/x' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path not found: /x' ). - endtry. + TRY. + lo_cut->z2ui5_if_ajson~array_to_string_table( '/x' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path not found: /x' ). + ENDTRY. - try. - lo_cut->z2ui5_if_ajson~array_to_string_table( '/' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Array expected at: /' ). - endtry. + TRY. + lo_cut->z2ui5_if_ajson~array_to_string_table( '/' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Array expected at: /' ). + ENDTRY. - try. - lo_cut->z2ui5_if_ajson~array_to_string_table( '/a' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Array expected at: /a' ). - endtry. + TRY. + lo_cut->z2ui5_if_ajson~array_to_string_table( '/a' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Array expected at: /a' ). + ENDTRY. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | |1' ). lo_nodes->add( '/ |1 |object | |1|0' ). lo_cut->mt_json_tree = lo_nodes->mt_nodes. - try. - lo_cut->z2ui5_if_ajson~array_to_string_table( '/' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Cannot convert [object] to string at [/1]' ). - endtry. + TRY. + lo_cut->z2ui5_if_ajson~array_to_string_table( '/' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Cannot convert [object] to string at [/1]' ). + ENDTRY. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * JSON TO ABAP ********************************************************************** -class ltcl_json_to_abap definition - for testing - risk level harmless - duration short - final. +CLASS ltcl_json_to_abap DEFINITION + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT + FINAL. - private section. + PRIVATE SECTION. - types: - begin of ty_struc, - a type string, - b type i, - end of ty_struc, - tty_struc type standard table of ty_struc with key a, - tty_struc_sorted type sorted table of ty_struc with unique key a, - tty_struc_hashed type hashed table of ty_struc with unique key a, - begin of ty_complex, - str type string, - int type i, - float type f, - bool type abap_bool, - obj type ty_struc, - tab type tty_struc, - tab_plain type string_table, - tab_hashed type tty_struc_hashed, - oref type ref to object, - date1 type d, - date2 type d, - timestamp1 type timestamp, - timestamp2 type timestamp, - timestamp3 type timestamp, - end of ty_complex. + TYPES: + BEGIN OF ty_struc, + a TYPE string, + b TYPE i, + END OF ty_struc, + tty_struc TYPE STANDARD TABLE OF ty_struc WITH KEY a, + tty_struc_sorted TYPE SORTED TABLE OF ty_struc WITH UNIQUE KEY a, + tty_struc_hashed TYPE HASHED TABLE OF ty_struc WITH UNIQUE KEY a, + BEGIN OF ty_complex, + str TYPE string, + int TYPE i, + float TYPE f, + bool TYPE abap_bool, + obj TYPE ty_struc, + tab TYPE tty_struc, + tab_plain TYPE string_table, + tab_hashed TYPE tty_struc_hashed, + oref TYPE REF TO object, + date1 TYPE d, + date2 TYPE d, + timestamp1 TYPE timestamp, + timestamp2 TYPE timestamp, + timestamp3 TYPE timestamp, + END OF ty_complex. - methods to_abap_struc - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_timestamp_initial - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_value - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_array - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_array_of_arrays_simple - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_array_of_arrays - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_w_tab_of_struc - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_w_plain_tab - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_hashed_tab - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_sorted_tab - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_hashed_plain_tab - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_negative - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_corresponding - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_corresponding_negative - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_corresponding_public - for testing - raising z2UI5_cx_ajson_error. - methods to_abap_corresponding_pub_neg - for testing - raising z2UI5_cx_ajson_error. + METHODS to_abap_struc + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_timestamp_initial + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_value + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_array + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_array_of_arrays_simple + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_array_of_arrays + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_w_tab_of_struc + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_w_plain_tab + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_hashed_tab + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_sorted_tab + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_hashed_plain_tab + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_negative + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_corresponding + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_corresponding_negative + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_corresponding_public + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_corresponding_pub_neg + FOR TESTING + RAISING z2ui5_cx_ajson_error. + METHODS to_abap_time + FOR TESTING + RAISING cx_static_check. -endclass. +ENDCLASS. -class z2ui5_cl_ajson definition local friends ltcl_json_to_abap. +CLASS z2ui5_cl_ajson DEFINITION LOCAL FRIENDS ltcl_json_to_abap. -class ltcl_json_to_abap implementation. +CLASS ltcl_json_to_abap IMPLEMENTATION. - method to_abap_struc. + METHOD to_abap_struc. - data lo_cut type ref to lcl_json_to_abap. - data ls_mock type ty_complex. - data ls_exp type ty_complex. - data lv_exp_date type d value '20200728'. - data lv_exp_timestamp type timestamp value '20200728000000'. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA ls_mock TYPE ty_complex. + DATA ls_exp TYPE ty_complex. + DATA lv_exp_date TYPE d VALUE '20200728'. + DATA lv_exp_timestamp TYPE timestamp VALUE '20200728000000'. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |str |str |hello | ' ). lo_nodes->add( '/ |int |num |5 | ' ). @@ -1488,11 +1491,11 @@ class ltcl_json_to_abap implementation. lo_nodes->add( '/ |timestamp2 |str |2020-07-28T00:00:00Z | ' ). lo_nodes->add( '/ |timestamp3 |str |2020-07-28T01:00:00+01:00 | ' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = ls_mock ). ls_exp-str = 'hello'. @@ -1510,123 +1513,145 @@ class ltcl_json_to_abap implementation. act = ls_mock exp = ls_exp ). - endmethod. + ENDMETHOD. - method to_abap_timestamp_initial. + METHOD to_abap_timestamp_initial. - data lo_cut type ref to lcl_json_to_abap. - data lv_mock type timestamp. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lv_mock TYPE timestamp. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |str |0000-00-00T00:00:00Z| ' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lv_mock ). cl_abap_unit_assert=>assert_equals( act = lv_mock exp = 0 ). - endmethod. + ENDMETHOD. - method to_abap_value. + METHOD to_abap_time. - data lo_cut type ref to lcl_json_to_abap. - data lv_mock type string. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lv_mock TYPE t. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |str |11:11:11| ' ). + + CREATE OBJECT lo_cut. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = lv_mock ). + + cl_abap_unit_assert=>assert_equals( + act = lv_mock + exp = '111111' ). + + ENDMETHOD. + + METHOD to_abap_value. + + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lv_mock TYPE string. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |str |hello | ' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lv_mock ). cl_abap_unit_assert=>assert_equals( act = lv_mock exp = 'hello' ). - endmethod. + ENDMETHOD. - method to_abap_array. + METHOD to_abap_array. - data lo_cut type ref to lcl_json_to_abap. - data lt_mock type string_table. - data lt_exp type string_table. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lt_mock TYPE string_table. + DATA lt_exp TYPE string_table. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | ' ). lo_nodes->add( '/ |1 |str |One |1' ). lo_nodes->add( '/ |2 |str |Two |2' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lt_mock ). - append 'One' to lt_exp. - append 'Two' to lt_exp. + APPEND 'One' TO lt_exp. + APPEND 'Two' TO lt_exp. cl_abap_unit_assert=>assert_equals( act = lt_mock exp = lt_exp ). - endmethod. + ENDMETHOD. - method to_abap_array_of_arrays_simple. + METHOD to_abap_array_of_arrays_simple. - data lo_cut type ref to lcl_json_to_abap. - data lt_mock type table of string_table. - data lt_exp type table of string_table. - data lt_tmp type string_table. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lt_mock TYPE TABLE OF string_table. + DATA lt_exp TYPE TABLE OF string_table. + DATA lt_tmp TYPE string_table. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | ' ). lo_nodes->add( '/ |1 |array | |1' ). lo_nodes->add( '/ |2 |array | |2' ). lo_nodes->add( '/1/ |1 |str |One |1' ). lo_nodes->add( '/2/ |1 |str |Two |1' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lt_mock ). - append 'One' to lt_tmp. - append lt_tmp to lt_exp. - clear lt_tmp. - append 'Two' to lt_tmp. - append lt_tmp to lt_exp. + APPEND 'One' TO lt_tmp. + APPEND lt_tmp TO lt_exp. + CLEAR lt_tmp. + APPEND 'Two' TO lt_tmp. + APPEND lt_tmp TO lt_exp. cl_abap_unit_assert=>assert_equals( act = lt_mock exp = lt_exp ). - endmethod. + ENDMETHOD. - method to_abap_array_of_arrays. + METHOD to_abap_array_of_arrays. - data lo_cut type ref to lcl_json_to_abap. - data lt_mock type table of string_table. - data lt_exp type table of string_table. - data lt_tmp type string_table. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lt_mock TYPE TABLE OF string_table. + DATA lt_exp TYPE TABLE OF string_table. + DATA lt_tmp TYPE string_table. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | ' ). lo_nodes->add( '/ |1 |array | |1' ). lo_nodes->add( '/ |2 |array | |2' ). @@ -1635,35 +1660,35 @@ class ltcl_json_to_abap implementation. lo_nodes->add( '/2/ |1 |str |Three |1' ). lo_nodes->add( '/2/ |2 |str |Four |2' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lt_mock ). - append 'One' to lt_tmp. - append 'Two' to lt_tmp. - append lt_tmp to lt_exp. - clear lt_tmp. - append 'Three' to lt_tmp. - append 'Four' to lt_tmp. - append lt_tmp to lt_exp. + APPEND 'One' TO lt_tmp. + APPEND 'Two' TO lt_tmp. + APPEND lt_tmp TO lt_exp. + CLEAR lt_tmp. + APPEND 'Three' TO lt_tmp. + APPEND 'Four' TO lt_tmp. + APPEND lt_tmp TO lt_exp. cl_abap_unit_assert=>assert_equals( act = lt_mock exp = lt_exp ). - endmethod. + ENDMETHOD. - method to_abap_w_tab_of_struc. + METHOD to_abap_w_tab_of_struc. - data lo_cut type ref to lcl_json_to_abap. - data ls_mock type ty_complex. - data ls_exp type ty_complex. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA ls_mock TYPE ty_complex. + DATA ls_exp TYPE ty_complex. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |tab |array | | ' ). lo_nodes->add( '/tab/ |1 |object | |1' ). @@ -1671,90 +1696,90 @@ class ltcl_json_to_abap implementation. lo_nodes->add( '/tab/ |2 |object | |2' ). lo_nodes->add( '/tab/2/|a |str |Two | ' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = ls_mock ). - data ls_elem like line of ls_exp-tab. + DATA ls_elem LIKE LINE OF ls_exp-tab. ls_elem-a = 'One'. - append ls_elem to ls_exp-tab. + APPEND ls_elem TO ls_exp-tab. ls_elem-a = 'Two'. - append ls_elem to ls_exp-tab. + APPEND ls_elem TO ls_exp-tab. cl_abap_unit_assert=>assert_equals( act = ls_mock exp = ls_exp ). - endmethod. + ENDMETHOD. - method to_abap_w_plain_tab. + METHOD to_abap_w_plain_tab. - data lo_cut type ref to lcl_json_to_abap. - data ls_mock type ty_complex. - data ls_exp type ty_complex. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA ls_mock TYPE ty_complex. + DATA ls_exp TYPE ty_complex. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |tab_plain |array | | ' ). lo_nodes->add( '/tab_plain/ |1 |str |One |1' ). lo_nodes->add( '/tab_plain/ |2 |str |Two |2' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = ls_mock ). - append 'One' to ls_exp-tab_plain. - append 'Two' to ls_exp-tab_plain. + APPEND 'One' TO ls_exp-tab_plain. + APPEND 'Two' TO ls_exp-tab_plain. cl_abap_unit_assert=>assert_equals( act = ls_mock exp = ls_exp ). - endmethod. + ENDMETHOD. - method to_abap_hashed_plain_tab. + METHOD to_abap_hashed_plain_tab. - data lo_cut type ref to lcl_json_to_abap. - data lt_mock type hashed table of string with unique key table_line. - data lt_exp type hashed table of string with unique key table_line. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lt_mock TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line. + DATA lt_exp TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line. - data lo_nodes type ref to lcl_nodes_helper. - create object lo_nodes. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | ' ). lo_nodes->add( '/ |1 |str |One |1' ). lo_nodes->add( '/ |2 |str |Two |2' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lt_mock ). - insert `One` into table lt_exp. - insert `Two` into table lt_exp. + INSERT `One` INTO TABLE lt_exp. + INSERT `Two` INTO TABLE lt_exp. cl_abap_unit_assert=>assert_equals( act = lt_mock exp = lt_exp ). - endmethod. + ENDMETHOD. - method to_abap_hashed_tab. + METHOD to_abap_hashed_tab. - data lo_cut type ref to lcl_json_to_abap. - data lt_mock type tty_struc_hashed. - data lt_exp type tty_struc_hashed. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lt_mock TYPE tty_struc_hashed. + DATA lt_exp TYPE tty_struc_hashed. - data lo_nodes type ref to lcl_nodes_helper. - create object lo_nodes. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | ' ). lo_nodes->add( '/ |1 |object | |1' ). lo_nodes->add( '/ |2 |object | |2' ). @@ -1763,35 +1788,35 @@ class ltcl_json_to_abap implementation. lo_nodes->add( '/2/ |a |str |Two | ' ). lo_nodes->add( '/2/ |b |num |2 | ' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lt_mock ). - data ls_elem like line of lt_exp. + DATA ls_elem LIKE LINE OF lt_exp. ls_elem-a = 'One'. ls_elem-b = 1. - insert ls_elem into table lt_exp. + INSERT ls_elem INTO TABLE lt_exp. ls_elem-a = 'Two'. ls_elem-b = 2. - insert ls_elem into table lt_exp. + INSERT ls_elem INTO TABLE lt_exp. cl_abap_unit_assert=>assert_equals( act = lt_mock exp = lt_exp ). - endmethod. + ENDMETHOD. - method to_abap_sorted_tab. + METHOD to_abap_sorted_tab. - data lo_cut type ref to lcl_json_to_abap. - data lt_mock type tty_struc_sorted. - data lt_exp type tty_struc_sorted. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lt_mock TYPE tty_struc_sorted. + DATA lt_exp TYPE tty_struc_sorted. - data lo_nodes type ref to lcl_nodes_helper. - create object lo_nodes. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | | ' ). lo_nodes->add( '/ |1 |object | |1' ). lo_nodes->add( '/ |2 |object | |2' ). @@ -1800,234 +1825,234 @@ class ltcl_json_to_abap implementation. lo_nodes->add( '/2/ |a |str |Two | ' ). lo_nodes->add( '/2/ |b |num |2 | ' ). - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = lt_mock ). - data ls_elem like line of lt_exp. + DATA ls_elem LIKE LINE OF lt_exp. ls_elem-a = 'One'. ls_elem-b = 1. - insert ls_elem into table lt_exp. + INSERT ls_elem INTO TABLE lt_exp. ls_elem-a = 'Two'. ls_elem-b = 2. - insert ls_elem into table lt_exp. + INSERT ls_elem INTO TABLE lt_exp. cl_abap_unit_assert=>assert_equals( act = lt_mock exp = lt_exp ). - endmethod. + ENDMETHOD. - method to_abap_negative. + METHOD to_abap_negative. - data lo_cut type ref to lcl_json_to_abap. - data lx type ref to z2UI5_cx_ajson_error. - data ls_mock type ty_complex. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. + DATA ls_mock TYPE ty_complex. - create object lo_cut. + CREATE OBJECT lo_cut. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - try. - create object lo_nodes. - lo_nodes->add( ' | |object | ' ). - lo_nodes->add( '/ |str |object | ' ). + TRY. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |object | ' ). + lo_nodes->add( '/ |str |object | ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = ls_mock ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Expected structure' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = ls_mock ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Expected structure' ). + ENDTRY. - try. - create object lo_nodes. - lo_nodes->add( ' | |object | ' ). - lo_nodes->add( '/ |str |array | ' ). + TRY. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |object | ' ). + lo_nodes->add( '/ |str |array | ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = ls_mock ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Expected table' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = ls_mock ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Expected table' ). + ENDTRY. - try. - create object lo_nodes. - lo_nodes->add( ' | |object | ' ). - lo_nodes->add( '/ |int |str |hello ' ). + TRY. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |object | ' ). + lo_nodes->add( '/ |int |str |hello ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = ls_mock ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Source is not a number' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = ls_mock ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Source is not a number' ). + ENDTRY. - try. - create object lo_nodes. - lo_nodes->add( ' | |object | ' ). - lo_nodes->add( '/ |date1 |str |baddate ' ). + TRY. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |object | ' ). + lo_nodes->add( '/ |date1 |str |baddate ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = ls_mock ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Unexpected date format' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = ls_mock ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Unexpected date format' ). + ENDTRY. - try. - create object lo_nodes. - lo_nodes->add( ' | |object | ' ). - lo_nodes->add( '/ |missing |str |123 ' ). + TRY. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |object | ' ). + lo_nodes->add( '/ |missing |str |123 ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = ls_mock ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path not found' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = ls_mock ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path not found' ). + ENDTRY. - try. - data lt_str type string_table. - create object lo_nodes. - lo_nodes->add( ' | |array | | ' ). - lo_nodes->add( '/ |a |str |hello |1' ). + TRY. + DATA lt_str TYPE string_table. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |array | | ' ). + lo_nodes->add( '/ |a |str |hello |1' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = lt_str ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Need index to access tables' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = lt_str ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Need index to access tables' ). + ENDTRY. - try. - data lr_obj type ref to object. - create object lo_nodes. - lo_nodes->add( ' | |str |hello | ' ). + TRY. + DATA lr_obj TYPE REF TO object. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |str |hello | ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = lr_obj ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Cannot assign to ref' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = lr_obj ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Cannot assign to ref' ). + ENDTRY. - try. - data lr_data type ref to data. - create object lo_nodes. - lo_nodes->add( ' | |str |hello | ' ). + TRY. + DATA lr_data TYPE REF TO data. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |str |hello | ' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = lr_data ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Cannot assign to ref' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = lr_data ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Cannot assign to ref' ). + ENDTRY. - try. - data lt_hashed type hashed table of string with unique key table_line. - create object lo_nodes. - lo_nodes->add( ' | |array | | ' ). - lo_nodes->add( '/ |1 |str |One |1' ). - lo_nodes->add( '/ |2 |str |One |2' ). + TRY. + DATA lt_hashed TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line. + CREATE OBJECT lo_nodes. + lo_nodes->add( ' | |array | | ' ). + lo_nodes->add( '/ |1 |str |One |1' ). + lo_nodes->add( '/ |2 |str |One |2' ). - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = lt_hashed ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Duplicate insertion' ). - endtry. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = lt_hashed ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Duplicate insertion' ). + ENDTRY. - endmethod. + ENDMETHOD. - method to_abap_corresponding. + METHOD to_abap_corresponding. - data lo_cut type ref to lcl_json_to_abap. - data ls_act type ty_struc. - data ls_exp type ty_struc. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA ls_act TYPE ty_struc. + DATA ls_exp TYPE ty_struc. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |a |str |test | ' ). lo_nodes->add( '/ |c |num |24022022 | ' ). ls_exp-a = 'test'. - create object lo_cut - exporting + CREATE OBJECT lo_cut + EXPORTING iv_corresponding = abap_true. lo_cut->to_abap( - exporting + EXPORTING it_nodes = lo_nodes->sorted( ) - changing + CHANGING c_container = ls_act ). cl_abap_unit_assert=>assert_equals( act = ls_act exp = ls_exp ). - endmethod. + ENDMETHOD. - method to_abap_corresponding_negative. + METHOD to_abap_corresponding_negative. - data lo_cut type ref to lcl_json_to_abap. - data ls_act type ty_struc. - data ls_exp type ty_struc. - data lo_nodes type ref to lcl_nodes_helper. - data lx type ref to z2UI5_cx_ajson_error. + DATA lo_cut TYPE REF TO lcl_json_to_abap. + DATA ls_act TYPE ty_struc. + DATA ls_exp TYPE ty_struc. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |a |str |test | ' ). lo_nodes->add( '/ |c |num |24022022 | ' ). @@ -2035,156 +2060,156 @@ class ltcl_json_to_abap implementation. ls_exp-a = 'test'. ls_exp-b = 24022022. - try. - create object lo_cut. - lo_cut->to_abap( - exporting - it_nodes = lo_nodes->sorted( ) - changing - c_container = ls_act ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path not found' ). - endtry. + TRY. + CREATE OBJECT lo_cut. + lo_cut->to_abap( + EXPORTING + it_nodes = lo_nodes->sorted( ) + CHANGING + c_container = ls_act ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path not found' ). + ENDTRY. - endmethod. + ENDMETHOD. - method to_abap_corresponding_public. + METHOD to_abap_corresponding_public. - data lo_cut type ref to z2ui5_cl_ajson. - data ls_act type ty_struc. - data ls_exp type ty_struc. - data li_json type ref to z2ui5_if_ajson. - data lo_nodes type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA ls_act TYPE ty_struc. + DATA ls_exp TYPE ty_struc. + DATA li_json TYPE REF TO z2ui5_if_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |a |str |test | ' ). lo_nodes->add( '/ |c |num |24022022 | ' ). ls_exp-a = 'test'. - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->mt_json_tree = lo_nodes->mt_nodes. lo_cut->to_abap( - exporting + EXPORTING iv_corresponding = abap_true - importing + IMPORTING ev_container = ls_act ). cl_abap_unit_assert=>assert_equals( act = ls_act exp = ls_exp ). - clear ls_act. + CLEAR ls_act. li_json = lo_cut->to_abap_corresponding_only( ). - li_json->to_abap( importing ev_container = ls_act ). + li_json->to_abap( IMPORTING ev_container = ls_act ). cl_abap_unit_assert=>assert_equals( act = ls_act exp = ls_exp ). - endmethod. + ENDMETHOD. - method to_abap_corresponding_pub_neg. + METHOD to_abap_corresponding_pub_neg. - data lo_cut type ref to z2ui5_cl_ajson. - data ls_act type ty_struc. - data ls_exp type ty_struc. - data lo_nodes type ref to lcl_nodes_helper. - data lx type ref to z2UI5_cx_ajson_error. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA ls_act TYPE ty_struc. + DATA ls_exp TYPE ty_struc. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | ' ). lo_nodes->add( '/ |a |str |test | ' ). lo_nodes->add( '/ |c |num |24022022 | ' ). ls_exp-a = 'test'. - create object lo_cut. + CREATE OBJECT lo_cut. lo_cut->mt_json_tree = lo_nodes->mt_nodes. - try. - lo_cut->to_abap( importing ev_container = ls_act ). + TRY. + lo_cut->to_abap( IMPORTING ev_container = ls_act ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path not found' ). - endtry. + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path not found' ). + ENDTRY. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * WRITER ********************************************************************** -class ltcl_writer_test definition final - for testing - risk level harmless - duration short. +CLASS ltcl_writer_test DEFINITION FINAL + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT. - private section. + PRIVATE SECTION. - methods set_ajson for testing raising z2UI5_cx_ajson_error. - methods set_value for testing raising z2UI5_cx_ajson_error. - methods ignore_empty for testing raising z2UI5_cx_ajson_error. - methods set_obj for testing raising z2UI5_cx_ajson_error. - methods set_obj_w_date_time for testing raising z2UI5_cx_ajson_error. - methods set_tab for testing raising z2UI5_cx_ajson_error. - methods set_tab_hashed for testing raising z2UI5_cx_ajson_error. - methods set_tab_nested_struct for testing raising z2UI5_cx_ajson_error. - methods prove_path_exists for testing raising z2UI5_cx_ajson_error. - methods delete_subtree for testing raising z2UI5_cx_ajson_error. - methods delete for testing raising z2UI5_cx_ajson_error. - methods arrays for testing raising z2UI5_cx_ajson_error. - methods arrays_negative for testing raising z2UI5_cx_ajson_error. - methods root_assignment for testing raising z2UI5_cx_ajson_error. - methods set_bool_abap_bool for testing raising z2UI5_cx_ajson_error. - methods set_bool_int for testing raising z2UI5_cx_ajson_error. - methods set_bool_tab for testing raising z2UI5_cx_ajson_error. - methods set_str for testing raising z2UI5_cx_ajson_error. - methods set_int for testing raising z2UI5_cx_ajson_error. - methods set_date for testing raising z2UI5_cx_ajson_error. - methods set_timestamp for testing raising z2UI5_cx_ajson_error. - methods read_only for testing raising z2UI5_cx_ajson_error. - methods set_array_obj for testing raising z2UI5_cx_ajson_error. - methods set_with_type for testing raising z2UI5_cx_ajson_error. - methods overwrite_w_keep_order_touch for testing raising z2UI5_cx_ajson_error. - methods overwrite_w_keep_order_set for testing raising z2UI5_cx_ajson_error. - methods setx for testing raising z2UI5_cx_ajson_error. - methods setx_float for testing raising z2UI5_cx_ajson_error. - methods setx_complex for testing raising z2UI5_cx_ajson_error. - methods setx_complex_w_keep_order for testing raising z2UI5_cx_ajson_error. + METHODS set_ajson FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS ignore_empty FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_obj FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_obj_w_date_time FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_tab FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_tab_hashed FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_tab_nested_struct FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS prove_path_exists FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS delete_subtree FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS delete FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS arrays FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS arrays_negative FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS root_assignment FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_bool_abap_bool FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_bool_int FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_bool_tab FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_str FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_int FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_date FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_timestamp FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS read_only FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_array_obj FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_with_type FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS overwrite_w_keep_order_touch FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS overwrite_w_keep_order_set FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS setx FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS setx_float FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS setx_complex FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS setx_complex_w_keep_order FOR TESTING RAISING z2ui5_cx_ajson_error. - methods set_with_type_slice - importing - io_json_in type ref to z2ui5_cl_ajson - io_json_out type ref to z2ui5_if_ajson - iv_path type string - raising - z2UI5_cx_ajson_error. + METHODS set_with_type_slice + IMPORTING + io_json_in TYPE REF TO z2ui5_cl_ajson + io_json_out TYPE REF TO z2ui5_if_ajson + iv_path TYPE string + RAISING + z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class z2ui5_cl_ajson definition local friends ltcl_writer_test. +CLASS z2ui5_cl_ajson DEFINITION LOCAL FRIENDS ltcl_writer_test. -class ltcl_writer_test implementation. +CLASS ltcl_writer_test IMPLEMENTATION. - method prove_path_exists. + METHOD prove_path_exists. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_cut = z2ui5_cl_ajson=>create_empty( ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||1' ). lo_nodes_exp->add( '/a/ |b |object | ||1' ). @@ -2196,7 +2221,7 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||1' ). lo_nodes_exp->add( '/a/ |b |object | ||1' ). @@ -2205,16 +2230,16 @@ class ltcl_writer_test implementation. lo_nodes_exp->add( '/a/b/c/d |e |object | ||0' ). lo_cut->prove_path_exists( '/a/b/c/d/e/' ). - endmethod. + ENDMETHOD. - method delete_subtree. + METHOD delete_subtree. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_cut = z2ui5_cl_ajson=>create_empty( ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||1' ). lo_nodes_exp->add( '/a/ |b |object | ||1' ). @@ -2223,7 +2248,7 @@ class ltcl_writer_test implementation. lo_cut->mt_json_tree = lo_nodes_exp->mt_nodes. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||0' ). @@ -2235,16 +2260,16 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method delete. + METHOD delete. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_cut = z2ui5_cl_ajson=>create_empty( ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||1' ). lo_nodes_exp->add( '/a/ |b |object | ||1' ). @@ -2253,7 +2278,7 @@ class ltcl_writer_test implementation. lo_cut->mt_json_tree = lo_nodes_exp->mt_nodes. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||0' ). @@ -2263,7 +2288,7 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||1' ). lo_nodes_exp->add( '/a/ |b |object | ||1' ). @@ -2272,7 +2297,7 @@ class ltcl_writer_test implementation. lo_cut->mt_json_tree = lo_nodes_exp->mt_nodes. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |object | ||0' ). @@ -2282,21 +2307,21 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_ajson. + METHOD set_ajson. - data lo_nodes type ref to lcl_nodes_helper. - data lo_src type ref to z2ui5_cl_ajson. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_src TYPE REF TO z2ui5_cl_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_src = z2ui5_cl_ajson=>create_empty( ). lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. " Prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |x |object | ||2' ). lo_nodes->add( '/x/ |b |str |abc ||0' ). @@ -2319,7 +2344,7 @@ class ltcl_writer_test implementation. exp = lo_nodes->sorted( ) ). " Test 2 - assign deep - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |a |object | ||1' ). lo_nodes->add( '/a/ |b |object | ||1' ). @@ -2337,7 +2362,7 @@ class ltcl_writer_test implementation. exp = lo_nodes->sorted( ) ). " Test 3 - assign rewrite - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |a |object | ||1' ). lo_nodes->add( '/a/ |b |object | ||1' ). @@ -2352,19 +2377,19 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method set_value. + METHOD set_value. - data lo_nodes type ref to lcl_nodes_helper. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. " Prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |x |object | ||2' ). lo_nodes->add( '/x/ |b |str |abc ||0' ). @@ -2383,16 +2408,16 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method ignore_empty. + METHOD ignore_empty. - data lo_nodes type ref to lcl_nodes_helper. - data li_cut type ref to z2ui5_if_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA li_cut TYPE REF TO z2ui5_if_ajson. li_cut = z2ui5_cl_ajson=>create_empty( ). - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |a |num |1 ||0' ). @@ -2406,7 +2431,7 @@ class ltcl_writer_test implementation. act = li_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||2' ). lo_nodes->add( '/ |a |num |1 ||0' ). lo_nodes->add( '/ |b |num |0 ||0' ). @@ -2419,26 +2444,26 @@ class ltcl_writer_test implementation. act = li_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method set_obj. + METHOD set_obj. - data lo_nodes type ref to lcl_nodes_helper. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. - data: - begin of ls_struc, - b type string value 'abc', - c type i value 10, - d type d value '20220401', - end of ls_struc. + DATA: + BEGIN OF ls_struc, + b TYPE string VALUE 'abc', + c TYPE i VALUE 10, + d TYPE d VALUE '20220401', + END OF ls_struc. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. " Prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |x |object | ||3' ). lo_nodes->add( '/x/ |b |str |abc ||0' ). @@ -2452,29 +2477,29 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method set_obj_w_date_time. + METHOD set_obj_w_date_time. - data lo_nodes type ref to lcl_nodes_helper. - data lo_cut type ref to z2ui5_if_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_if_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. - data: - begin of ls_struc, - d type d value '20220401', - d_empty type d, - t type t value '200103', - t_empty type t, - ts type timestamp value '20220401200103', - p(5) type p decimals 2 value '123.45', - end of ls_struc. + DATA: + BEGIN OF ls_struc, + d TYPE d VALUE '20220401', + d_empty TYPE d, + t TYPE t VALUE '200103', + t_empty TYPE t, + ts TYPE timestamp VALUE '20220401200103', + p(5) TYPE p DECIMALS 2 VALUE '123.45', + END OF ls_struc. lo_cut = z2ui5_cl_ajson=>create_empty( )->format_datetime( ). li_writer = lo_cut. " Prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||6' ). lo_nodes->add( '/ |d |str |2022-04-01 ||0' ). lo_nodes->add( '/ |d_empty |str | ||0' ). @@ -2490,23 +2515,23 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method set_tab. + METHOD set_tab. - data lo_nodes type ref to lcl_nodes_helper. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. - data lt_tab type string_table. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lt_tab TYPE string_table. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - append 'hello' to lt_tab. - append 'world' to lt_tab. + APPEND 'hello' TO lt_tab. + APPEND 'world' TO lt_tab. " Prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |x |array | | |2' ). lo_nodes->add( '/x/ |1 |str |hello|1|0' ). @@ -2519,23 +2544,23 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method set_tab_hashed. + METHOD set_tab_hashed. - data lo_nodes type ref to lcl_nodes_helper. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. - data lt_tab type hashed table of string with unique key table_line. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lt_tab TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - insert `hello` into table lt_tab. - insert `world` into table lt_tab. + INSERT `hello` INTO TABLE lt_tab. + INSERT `world` INTO TABLE lt_tab. " Prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | | |1' ). lo_nodes->add( '/ |x |array | | |2' ). lo_nodes->add( '/x/ |1 |str |hello|1|0' ). @@ -2548,39 +2573,39 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method set_tab_nested_struct. + METHOD set_tab_nested_struct. - types: - begin of ty_include, - str type string, - int type i, - end of ty_include, - begin of ty_struct. - include type ty_include. - types: dat type xstring, - end of ty_struct, - ty_tab type standard table of ty_struct with key str. + TYPES: + BEGIN OF ty_include, + str TYPE string, + int TYPE i, + END OF ty_include, + BEGIN OF ty_struct. + INCLUDE TYPE ty_include. + TYPES: dat TYPE xstring, + END OF ty_struct, + ty_tab TYPE STANDARD TABLE OF ty_struct WITH KEY str. - data lo_nodes type ref to lcl_nodes_helper. - data li_cut type ref to z2ui5_if_ajson. - data ls_tab type ty_struct. - data lt_tab type ty_tab. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA li_cut TYPE REF TO z2ui5_if_ajson. + DATA ls_tab TYPE ty_struct. + DATA lt_tab TYPE ty_tab. li_cut = z2ui5_cl_ajson=>create_empty( ). ls_tab-str = 'hello'. ls_tab-int = 123. ls_tab-dat = '4041'. - insert ls_tab into table lt_tab. + INSERT ls_tab INTO TABLE lt_tab. ls_tab-str = 'world'. ls_tab-int = 456. ls_tab-dat = '6061'. - insert ls_tab into table lt_tab. + INSERT ls_tab INTO TABLE lt_tab. " prepare source - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |array | |0|2' ). lo_nodes->add( '/ |1 |object | |1|3' ). lo_nodes->add( '/ |2 |object | |2|3' ). @@ -2598,19 +2623,19 @@ class ltcl_writer_test implementation. act = li_cut->mt_json_tree exp = lo_nodes->sorted( ) ). - endmethod. + ENDMETHOD. - method arrays. + METHOD arrays. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. " touch - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |a |array | | |0' ). @@ -2621,7 +2646,7 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " add string - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |a |array | | |1' ). lo_nodes_exp->add( '/a/ |1 |str |hello|1|0' ). @@ -2635,17 +2660,17 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " add obj - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |a |array | | |2' ). lo_nodes_exp->add( '/a/ |1 |str |hello|1|0' ). lo_nodes_exp->add( '/a/ |2 |object | |2|1' ). lo_nodes_exp->add( '/a/2/ |x |str |world| |0' ). - data: - begin of ls_dummy, - x type string value 'world', - end of ls_dummy. + DATA: + BEGIN OF ls_dummy, + x TYPE string VALUE 'world', + END OF ls_dummy. li_writer->push( iv_path = '/a' @@ -2663,7 +2688,7 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " re-touch with clear - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |a |array | | |0' ). @@ -2676,7 +2701,7 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " free-add array item (index must be updated) - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |a |array | | |2' ). lo_nodes_exp->add( '/a/ |1 |object | |1|1' ). @@ -2694,12 +2719,12 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method arrays_negative. + METHOD arrays_negative. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. @@ -2710,93 +2735,93 @@ class ltcl_writer_test implementation. iv_val = 123 ). " touch another node - data lx type ref to z2UI5_cx_ajson_error. - try. - li_writer->touch_array( iv_path = '/a/1' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path [/a/1] already used and is not array' ). - endtry. + DATA lx TYPE REF TO z2ui5_cx_ajson_error. + TRY. + li_writer->touch_array( iv_path = '/a/1' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path [/a/1] already used and is not array' ). + ENDTRY. " push to not array - try. - li_writer->push( - iv_path = '/a/1' - iv_val = 123 ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path [/a/1] is not array' ). - endtry. + TRY. + li_writer->push( + iv_path = '/a/1' + iv_val = 123 ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path [/a/1] is not array' ). + ENDTRY. " push to not array - try. - li_writer->push( - iv_path = '/x' - iv_val = 123 ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Path [/x] does not exist' ). - endtry. + TRY. + li_writer->push( + iv_path = '/x' + iv_val = 123 ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Path [/x] does not exist' ). + ENDTRY. " set array item with non-numeric key - try. - li_writer->set( - iv_path = '/a/abc/x' - iv_val = 123 ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Cannot add non-numeric key [abc] to array [/a/]' ). - endtry. + TRY. + li_writer->set( + iv_path = '/a/abc/x' + iv_val = 123 ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Cannot add non-numeric key [abc] to array [/a/]' ). + ENDTRY. - try. - li_writer->set( - iv_path = '/a/abc' - iv_val = 123 ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Cannot add non-numeric key [abc] to array [/a/]' ). - endtry. + TRY. + li_writer->set( + iv_path = '/a/abc' + iv_val = 123 ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Cannot add non-numeric key [abc] to array [/a/]' ). + ENDTRY. " set array item with zero key - try. - li_writer->set( - iv_path = '/a/0' - iv_val = 123 ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx. - cl_abap_unit_assert=>assert_equals( - act = lx->message - exp = 'Cannot add zero key to array [/a/]' ). - endtry. + TRY. + li_writer->set( + iv_path = '/a/0' + iv_val = 123 ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx. + cl_abap_unit_assert=>assert_equals( + act = lx->message + exp = 'Cannot add zero key to array [/a/]' ). + ENDTRY. - endmethod. + ENDMETHOD. - method root_assignment. + METHOD root_assignment. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. - data: - begin of ls_dummy, - x type string value 'hello', - end of ls_dummy. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA: + BEGIN OF ls_dummy, + x TYPE string VALUE 'hello', + END OF ls_dummy. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. " object - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |x |str |hello||0' ). @@ -2809,7 +2834,7 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " object empty path - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |x |str |hello||0' ). @@ -2823,7 +2848,7 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " array - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |array | | |1' ). lo_nodes_exp->add( '/ |1 |str |hello|1|0' ). @@ -2838,7 +2863,7 @@ class ltcl_writer_test implementation. exp = lo_nodes_exp->sorted( ) ). " value - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |str |hello||0' ). li_writer->clear( ). @@ -2850,18 +2875,18 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_bool_abap_bool. + METHOD set_bool_abap_bool. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. " abap_bool lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||2' ). lo_nodes_exp->add( '/ |a |bool |true ||0' ). lo_nodes_exp->add( '/ |b |bool |false ||0' ). @@ -2877,18 +2902,18 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_bool_int. + METHOD set_bool_int. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. " int lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||2' ). lo_nodes_exp->add( '/ |a |bool |true ||0' ). lo_nodes_exp->add( '/ |b |bool |false ||0' ). @@ -2904,28 +2929,28 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_bool_tab. + METHOD set_bool_tab. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. - data lt_tab type string_table. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lt_tab TYPE string_table. " tab lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||2' ). lo_nodes_exp->add( '/ |a |bool |true ||0' ). lo_nodes_exp->add( '/ |b |bool |false ||0' ). - append 'hello' to lt_tab. + APPEND 'hello' TO lt_tab. li_writer->set_boolean( iv_path = '/a' iv_val = lt_tab ). - clear lt_tab. + CLEAR lt_tab. li_writer->set_boolean( iv_path = '/b' iv_val = lt_tab ). @@ -2934,18 +2959,18 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_str. + METHOD set_str. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. - data lv_date type d. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lv_date TYPE d. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||3' ). lo_nodes_exp->add( '/ |a |str |123 ||0' ). lo_nodes_exp->add( '/ |b |str |X ||0' ). @@ -2966,17 +2991,17 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_int. + METHOD set_int. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |num |123 ||0' ). @@ -2988,18 +3013,18 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_date. + METHOD set_date. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. - data lv_date type d. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lv_date TYPE d. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||2' ). lo_nodes_exp->add( '/ |a |str |2020-07-05 ||0' ). lo_nodes_exp->add( '/ |b |str | ||0' ). @@ -3009,7 +3034,7 @@ class ltcl_writer_test implementation. iv_path = '/a' iv_val = lv_date ). - clear lv_date. + CLEAR lv_date. li_writer->set_date( iv_path = '/b' iv_val = lv_date ). @@ -3018,18 +3043,18 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_timestamp. + METHOD set_timestamp. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. - data lv_timestamp type timestamp. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lv_timestamp TYPE timestamp. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||1' ). lo_nodes_exp->add( '/ |a |str |2021-05-05T12:00:00Z ||0' ). @@ -3042,12 +3067,12 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method read_only. + METHOD read_only. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_cut = z2ui5_cl_ajson=>create_empty( ). li_writer = lo_cut. @@ -3063,49 +3088,49 @@ class ltcl_writer_test implementation. lo_cut->freeze( ). - try. - li_writer->set( - iv_path = '/c' - iv_val = 'abc' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + li_writer->set( + iv_path = '/c' + iv_val = 'abc' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - try. - li_writer->touch_array( iv_path = '/d' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + li_writer->touch_array( iv_path = '/d' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - try. - li_writer->push( - iv_path = '/b' - iv_val = 'xyz' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + li_writer->push( + iv_path = '/b' + iv_val = 'xyz' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - try. - li_writer->delete( iv_path = '/a' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + li_writer->delete( iv_path = '/a' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - try. - li_writer->clear( ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + li_writer->clear( ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - endmethod. + ENDMETHOD. - method set_array_obj. + METHOD set_array_obj. - data lo_cut type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA li_writer TYPE REF TO z2ui5_if_ajson. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |issues |array | | |2' ). lo_nodes_exp->add( '/issues/ |1 |object | |1 |1' ). @@ -3138,13 +3163,13 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method set_with_type. + METHOD set_with_type. - data lo_sample type ref to z2ui5_cl_ajson. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. + DATA lo_sample TYPE REF TO z2ui5_cl_ajson. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. lo_sample = z2ui5_cl_ajson=>parse( ltcl_parser_test=>sample_json( ) ). @@ -3159,44 +3184,44 @@ class ltcl_writer_test implementation. act = lo_cut->mt_json_tree exp = lo_sample->mt_json_tree ). - endmethod. + ENDMETHOD. - method set_with_type_slice. + METHOD set_with_type_slice. - data lv_path type string. + DATA lv_path TYPE string. - field-symbols like line of io_json_in->mt_json_tree. + FIELD-SYMBOLS LIKE LINE OF io_json_in->mt_json_tree. - loop at io_json_in->mt_json_tree assigning where path = iv_path. + LOOP AT io_json_in->mt_json_tree ASSIGNING WHERE path = iv_path. lv_path = -path && -name && '/'. - case -type. - when z2ui5_if_ajson_types=>node_type-array. + CASE -type. + WHEN z2ui5_if_ajson_types=>node_type-array. io_json_out->touch_array( lv_path ). set_with_type_slice( io_json_in = io_json_in io_json_out = io_json_out iv_path = lv_path ). - when z2ui5_if_ajson_types=>node_type-object. + WHEN z2ui5_if_ajson_types=>node_type-object. set_with_type_slice( io_json_in = io_json_in io_json_out = io_json_out iv_path = lv_path ). - when others. + WHEN OTHERS. io_json_out->set( iv_path = lv_path iv_val = -value iv_node_type = -type ). - endcase. - endloop. + ENDCASE. + ENDLOOP. - endmethod. + ENDMETHOD. - method overwrite_w_keep_order_set. + METHOD overwrite_w_keep_order_set. - data li_cut type ref to z2ui5_if_ajson. - data: - begin of ls_dummy, - b type i, - a type i, - end of ls_dummy. + DATA li_cut TYPE REF TO z2ui5_if_ajson. + DATA: + BEGIN OF ls_dummy, + b TYPE i, + a TYPE i, + END OF ls_dummy. li_cut = z2ui5_cl_ajson=>create_empty( )->set( @@ -3227,16 +3252,16 @@ class ltcl_writer_test implementation. act = li_cut->stringify( ) exp = '{"b":0,"a":1}' ). " still ordered after overwrite - endmethod. + ENDMETHOD. - method overwrite_w_keep_order_touch. + METHOD overwrite_w_keep_order_touch. - data li_cut type ref to z2ui5_if_ajson. - data: - begin of ls_dummy, - b type i, - a type string_table, - end of ls_dummy. + DATA li_cut TYPE REF TO z2ui5_if_ajson. + DATA: + BEGIN OF ls_dummy, + b TYPE i, + a TYPE string_table, + END OF ls_dummy. li_cut = z2ui5_cl_ajson=>create_empty( )->set( @@ -3267,9 +3292,9 @@ class ltcl_writer_test implementation. act = li_cut->stringify( ) exp = '{"b":0,"a":[]}' ). " still ordered after touch with clear - endmethod. + ENDMETHOD. - method setx. + METHOD setx. cl_abap_unit_assert=>assert_equals( act = z2ui5_cl_ajson=>new( )->setx( '/a:1' )->stringify( ) @@ -3327,9 +3352,9 @@ class ltcl_writer_test implementation. act = z2ui5_cl_ajson=>new( )->setx( '/a:""' )->stringify( ) exp = '{"a":""}' ). - endmethod. + ENDMETHOD. - method setx_float. + METHOD setx_float. cl_abap_unit_assert=>assert_equals( act = z2ui5_cl_ajson=>new( )->setx( '/a:1.123' )->stringify( ) @@ -3351,9 +3376,9 @@ class ltcl_writer_test implementation. act = z2ui5_cl_ajson=>new( )->setx( '/a:1..123' )->stringify( ) exp = '{"a":"1..123"}' ). - endmethod. + ENDMETHOD. - method setx_complex. + METHOD setx_complex. cl_abap_unit_assert=>assert_equals( act = z2ui5_cl_ajson=>new( )->setx( '/a:{"b" : 1}' )->stringify( ) @@ -3371,28 +3396,28 @@ class ltcl_writer_test implementation. act = z2ui5_cl_ajson=>new( )->setx( '/a:[]' )->stringify( ) exp = '{"a":[]}' ). - try. - z2ui5_cl_ajson=>new( )->setx( '/a:{"b" : 1' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + z2ui5_cl_ajson=>new( )->setx( '/a:{"b" : 1' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - try. - z2ui5_cl_ajson=>new( )->setx( '/a:[1, 2' ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error. - endtry. + TRY. + z2ui5_cl_ajson=>new( )->setx( '/a:[1, 2' ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error. + ENDTRY. - endmethod. + ENDMETHOD. - method setx_complex_w_keep_order. + METHOD setx_complex_w_keep_order. - data li_cut type ref to z2ui5_if_ajson. - data: - begin of ls_dummy, - f type i value 5, - e type i value 6, - end of ls_dummy. + DATA li_cut TYPE REF TO z2ui5_if_ajson. + DATA: + BEGIN OF ls_dummy, + f TYPE i VALUE 5, + e TYPE i VALUE 6, + END OF ls_dummy. li_cut = z2ui5_cl_ajson=>new( iv_keep_item_order = abap_true ). li_cut->setx( '/c:3' ). @@ -3420,119 +3445,119 @@ class ltcl_writer_test implementation. act = li_cut->stringify( ) exp = '{"c":3,"b":{"z":9,"y":8},"a":1,"0":9}' ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * INTEGRATED ********************************************************************** -class ltcl_integrated definition - for testing - risk level harmless - duration short - final. +CLASS ltcl_integrated DEFINITION + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT + FINAL. - private section. + PRIVATE SECTION. - types: - begin of ty_loc, - row type i, - col type i, - end of ty_loc, - begin of ty_issue, - message type string, - key type string, - filename type string, - start type ty_loc, - end type ty_loc, - end of ty_issue, - tt_issues type standard table of ty_issue with key message key, - begin of ty_target, - string type string, - number type i, - float type f, - boolean type abap_bool, - false type abap_bool, - null type string, - date type string, " ??? TODO - issues type tt_issues, - end of ty_target. + TYPES: + BEGIN OF ty_loc, + row TYPE i, + col TYPE i, + END OF ty_loc, + BEGIN OF ty_issue, + message TYPE string, + key TYPE string, + filename TYPE string, + start TYPE ty_loc, + end TYPE ty_loc, + END OF ty_issue, + tt_issues TYPE STANDARD TABLE OF ty_issue WITH KEY message key, + BEGIN OF ty_target, + string TYPE string, + number TYPE i, + float TYPE f, + boolean TYPE abap_bool, + false TYPE abap_bool, + null TYPE string, + date TYPE string, " ??? TODO + issues TYPE tt_issues, + END OF ty_target. - methods reader for testing raising z2UI5_cx_ajson_error. - methods array_index for testing raising z2UI5_cx_ajson_error. - methods array_simple for testing raising z2UI5_cx_ajson_error. - methods stringify for testing raising z2UI5_cx_ajson_error. - methods item_order_integrated for testing raising z2UI5_cx_ajson_error. - methods chaining for testing raising z2UI5_cx_ajson_error. - methods push_json for testing raising z2UI5_cx_ajson_error. - methods is_empty for testing raising z2UI5_cx_ajson_error. + METHODS reader FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS array_index FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS array_simple FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS stringify FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS item_order_integrated FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS chaining FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS push_json FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS is_empty FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class ltcl_integrated implementation. +CLASS ltcl_integrated IMPLEMENTATION. - method array_simple. + METHOD array_simple. - data lt_act type string_table. - data lt_exp type string_table. - data lv_exp type string. + DATA lt_act TYPE string_table. + DATA lt_exp TYPE string_table. + DATA lv_exp TYPE string. - data lv_src type string. + DATA lv_src TYPE string. lv_src = '['. - do 10 times. - if sy-index <> 1. + DO 10 TIMES. + IF sy-index <> 1. lv_src = lv_src && `, `. - endif. + ENDIF. lv_src = lv_src && |"{ sy-index }"|. lv_exp = |{ sy-index }|. - append lv_exp to lt_exp. - enddo. + APPEND lv_exp TO lt_exp. + ENDDO. lv_src = lv_src && ']'. - data li_reader type ref to z2ui5_if_ajson. + DATA li_reader TYPE REF TO z2ui5_if_ajson. li_reader = z2ui5_cl_ajson=>parse( lv_src ). - li_reader->to_abap( importing ev_container = lt_act ). + li_reader->to_abap( IMPORTING ev_container = lt_act ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = lt_exp ). - endmethod. + ENDMETHOD. - method array_index. + METHOD array_index. - data lt_act type table of ty_loc. - data lt_exp type table of ty_loc. - data ls_exp type ty_loc. + DATA lt_act TYPE TABLE OF ty_loc. + DATA lt_exp TYPE TABLE OF ty_loc. + DATA ls_exp TYPE ty_loc. - data lv_src type string. + DATA lv_src TYPE string. lv_src = '['. - do 10 times. - if sy-index <> 1. + DO 10 TIMES. + IF sy-index <> 1. lv_src = lv_src && `, `. - endif. + ENDIF. lv_src = lv_src && |\{ "row": { sy-index } \}|. ls_exp-row = sy-index. - append ls_exp to lt_exp. - enddo. + APPEND ls_exp TO lt_exp. + ENDDO. lv_src = lv_src && ']'. - data li_reader type ref to z2ui5_if_ajson. + DATA li_reader TYPE REF TO z2ui5_if_ajson. li_reader = z2ui5_cl_ajson=>parse( lv_src ). - li_reader->to_abap( importing ev_container = lt_act ). + li_reader->to_abap( IMPORTING ev_container = lt_act ). cl_abap_unit_assert=>assert_equals( act = lt_act exp = lt_exp ). - endmethod. + ENDMETHOD. - method reader. + METHOD reader. - data lv_source type string. - data li_reader type ref to z2ui5_if_ajson. + DATA lv_source TYPE string. + DATA li_reader TYPE REF TO z2ui5_if_ajson. lv_source = ltcl_parser_test=>sample_json( ). li_reader = z2ui5_cl_ajson=>parse( lv_source ). @@ -3541,9 +3566,9 @@ class ltcl_integrated implementation. act = li_reader->get( '/string' ) exp = 'abc' ). - data ls_act type ty_target. - data ls_exp type ty_target. - field-symbols like line of ls_exp-issues. + DATA ls_act TYPE ty_target. + DATA ls_exp TYPE ty_target. + FIELD-SYMBOLS LIKE LINE OF ls_exp-issues. ls_exp-string = 'abc'. ls_exp-number = 123. @@ -3552,7 +3577,7 @@ class ltcl_integrated implementation. ls_exp-false = abap_false. ls_exp-date = '2020-03-15'. - append initial line to ls_exp-issues assigning . + APPEND INITIAL LINE TO ls_exp-issues ASSIGNING . -message = 'Indentation problem ...'. -key = 'indentation'. -filename = './zxxx.prog.abap'. @@ -3561,7 +3586,7 @@ class ltcl_integrated implementation. -end-row = 4. -end-col = 26. - append initial line to ls_exp-issues assigning . + APPEND INITIAL LINE TO ls_exp-issues ASSIGNING . -message = 'Remove space before XXX'. -key = 'space_before_dot'. -filename = './zxxx.prog.abap'. @@ -3570,21 +3595,21 @@ class ltcl_integrated implementation. -end-row = 3. -end-col = 22. - li_reader->to_abap( importing ev_container = ls_act ). + li_reader->to_abap( IMPORTING ev_container = ls_act ). cl_abap_unit_assert=>assert_equals( act = ls_act exp = ls_exp ). - endmethod. + ENDMETHOD. - method stringify. + METHOD stringify. - data lo_cut type ref to z2ui5_cl_ajson. - data li_writer type ref to z2ui5_if_ajson. - data lv_exp type string. - data: begin of ls_dummy, x type i, end of ls_dummy. - data: begin of ls_data, str type string, cls type ref to z2ui5_cl_ajson, end of ls_data. + DATA lo_cut TYPE REF TO z2ui5_cl_ajson. + DATA li_writer TYPE REF TO z2ui5_if_ajson. + DATA lv_exp TYPE string. + DATA: BEGIN OF ls_dummy, x TYPE i, END OF ls_dummy. + DATA: BEGIN OF ls_data, str TYPE string, cls TYPE REF TO z2ui5_cl_ajson, END OF ls_data. ls_dummy-x = 1. lo_cut = z2ui5_cl_ajson=>create_empty( ). @@ -3665,20 +3690,20 @@ class ltcl_integrated implementation. act = lo_cut->stringify( ) exp = lv_exp ). - endmethod. + ENDMETHOD. - method item_order_integrated. + METHOD item_order_integrated. - data: - begin of ls_dummy, - zulu type string, - alpha type string, - beta type string, - end of ls_dummy. + DATA: + BEGIN OF ls_dummy, + zulu TYPE string, + alpha TYPE string, + beta TYPE string, + END OF ls_dummy. - data lv_act type string. - data lv_exp type string. - data li_cut type ref to z2ui5_if_ajson. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. + DATA li_cut TYPE REF TO z2ui5_if_ajson. ls_dummy-alpha = 'a'. ls_dummy-beta = 'b'. @@ -3711,11 +3736,11 @@ class ltcl_integrated implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method chaining. + METHOD chaining. - data li_cut type ref to z2ui5_if_ajson. + DATA li_cut TYPE REF TO z2ui5_if_ajson. li_cut = z2ui5_cl_ajson=>create_empty( ). @@ -3735,14 +3760,14 @@ class ltcl_integrated implementation. cl_abap_unit_assert=>assert_bound( li_cut->keep_item_order( ) ). - endmethod. + ENDMETHOD. - method push_json. + METHOD push_json. - data li_cut type ref to z2ui5_if_ajson. - data li_sub type ref to z2ui5_if_ajson. - data lv_act type string. - data lv_exp type string. + DATA li_cut TYPE REF TO z2ui5_if_ajson. + DATA li_sub TYPE REF TO z2ui5_if_ajson. + DATA lv_act TYPE string. + DATA lv_exp TYPE string. li_cut = z2ui5_cl_ajson=>create_empty( ). li_sub = z2ui5_cl_ajson=>create_empty( )->set( @@ -3771,11 +3796,11 @@ class ltcl_integrated implementation. act = lv_act exp = lv_exp ). - endmethod. + ENDMETHOD. - method is_empty. + METHOD is_empty. - data li_cut type ref to z2ui5_if_ajson. + DATA li_cut TYPE REF TO z2ui5_if_ajson. li_cut = z2ui5_cl_ajson=>create_empty( ). @@ -3791,95 +3816,95 @@ class ltcl_integrated implementation. exp = abap_false act = li_cut->is_empty( ) ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * ABAP TO JSON ********************************************************************** -class ltcl_abap_to_json definition - for testing - risk level harmless - duration short - final. +CLASS ltcl_abap_to_json DEFINITION + FOR TESTING + RISK LEVEL HARMLESS + DURATION SHORT + FINAL. - private section. + PRIVATE SECTION. - types: - begin of ty_struc, - a type string, - b type i, - c type abap_bool, - d type xsdboolean, - end of ty_struc, - tt_struc type standard table of ty_struc with key a, - begin of ty_struc_complex. - include type ty_struc. - types: - el type string, - struc type ty_struc, - tab type tt_struc, - stab type string_table, - end of ty_struc_complex. + TYPES: + BEGIN OF ty_struc, + a TYPE string, + b TYPE i, + c TYPE abap_bool, + d TYPE xsdboolean, + END OF ty_struc, + tt_struc TYPE STANDARD TABLE OF ty_struc WITH KEY a, + BEGIN OF ty_struc_complex. + INCLUDE TYPE ty_struc. + TYPES: + el TYPE string, + struc TYPE ty_struc, + tab TYPE tt_struc, + stab TYPE string_table, + END OF ty_struc_complex. - types - begin of ty_named_include. - include type ty_struc as named_with_suffix renaming with suffix _suf. - types: - el type string, - end of ty_named_include. + TYPES + BEGIN OF ty_named_include. + INCLUDE TYPE ty_struc AS named_with_suffix RENAMING WITH SUFFIX _suf. + TYPES: + el TYPE string, + END OF ty_named_include. - methods set_ajson for testing raising z2UI5_cx_ajson_error. - methods set_value_number for testing raising z2UI5_cx_ajson_error. - methods set_value_string for testing raising z2UI5_cx_ajson_error. - methods set_value_true for testing raising z2UI5_cx_ajson_error. - methods set_value_false for testing raising z2UI5_cx_ajson_error. - methods set_value_xsdboolean for testing raising z2UI5_cx_ajson_error. - methods set_value_timestamp for testing raising z2UI5_cx_ajson_error. - methods set_value_timestamp_initial for testing raising z2UI5_cx_ajson_error. - methods set_null for testing raising z2UI5_cx_ajson_error. - methods set_obj for testing raising z2UI5_cx_ajson_error. - methods set_array for testing raising z2UI5_cx_ajson_error. - methods set_complex_obj for testing raising z2UI5_cx_ajson_error. - methods set_include_with_suffix for testing raising z2UI5_cx_ajson_error. - methods prefix for testing raising z2UI5_cx_ajson_error. + METHODS set_ajson FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_number FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_string FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_true FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_false FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_xsdboolean FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_timestamp FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_value_timestamp_initial FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_null FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_obj FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_array FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_complex_obj FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS set_include_with_suffix FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS prefix FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class z2ui5_cl_ajson definition local friends ltcl_abap_to_json. +CLASS z2ui5_cl_ajson DEFINITION LOCAL FRIENDS ltcl_abap_to_json. -class ltcl_abap_to_json implementation. +CLASS ltcl_abap_to_json IMPLEMENTATION. - method set_ajson. + METHOD set_ajson. - data lo_nodes type ref to lcl_nodes_helper. - data lo_src type ref to z2ui5_cl_ajson. + DATA lo_nodes TYPE REF TO lcl_nodes_helper. + DATA lo_src TYPE REF TO z2ui5_cl_ajson. lo_src = z2ui5_cl_ajson=>create_empty( ). - create object lo_nodes. + CREATE OBJECT lo_nodes. lo_nodes->add( ' | |object | ||1' ). lo_nodes->add( '/ |a |object | ||1' ). lo_nodes->add( '/a/ |b |object | ||1' ). lo_nodes->add( '/a/b/ |c |object | ||0' ). lo_src->mt_json_tree = lo_nodes->mt_nodes. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. lt_nodes = lcl_abap_to_json=>convert( iv_data = lo_src ). cl_abap_unit_assert=>assert_equals( act = lt_nodes exp = lo_nodes->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_number. + METHOD set_value_number. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. " number - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |num |1 ||' ). lt_nodes = lcl_abap_to_json=>convert( iv_data = 1 ). @@ -3888,15 +3913,15 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_string. + METHOD set_value_string. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. " string - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |str |abc ||' ). lt_nodes = lcl_abap_to_json=>convert( iv_data = 'abc' ). @@ -3905,15 +3930,15 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_true. + METHOD set_value_true. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. " true - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |bool |true ||' ). lt_nodes = lcl_abap_to_json=>convert( iv_data = abap_true ). @@ -3922,15 +3947,15 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_false. + METHOD set_value_false. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. " false - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |bool |false ||' ). lt_nodes = lcl_abap_to_json=>convert( iv_data = abap_false ). @@ -3939,15 +3964,15 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_xsdboolean. + METHOD set_value_xsdboolean. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. - data lv_xsdboolean type xsdboolean. - create object lo_nodes_exp. + DATA lv_xsdboolean TYPE xsdboolean. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |bool |true ||' ). lv_xsdboolean = 'X'. @@ -3957,16 +3982,16 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_null. + METHOD set_null. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. - data lv_null_ref type ref to data. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lv_null_ref TYPE REF TO data. " null - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |null |null ||' ). lt_nodes = lcl_abap_to_json=>convert( iv_data = lv_null_ref ). @@ -3975,35 +4000,35 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_timestamp. + METHOD set_value_timestamp. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. - data lv_timezone type timezone value ''. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lv_timezone TYPE timezone VALUE ''. - data lv_timestamp type timestamp. - create object lo_nodes_exp. + DATA lv_timestamp TYPE timestamp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |str |2022-08-31T00:00:00Z||' ). - convert date '20220831' time '000000' - into time stamp lv_timestamp time zone lv_timezone. + CONVERT DATE '20220831' TIME '000000' + INTO TIME STAMP lv_timestamp TIME ZONE lv_timezone. lt_nodes = lcl_abap_to_json=>convert( lcl_abap_to_json=>format_timestamp( lv_timestamp ) ). cl_abap_unit_assert=>assert_equals( act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_value_timestamp_initial. + METHOD set_value_timestamp_initial. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. - data lv_timestamp type timestamp. - create object lo_nodes_exp. + DATA lv_timestamp TYPE timestamp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |str |0000-00-00T00:00:00Z||' ). lv_timestamp = 0. @@ -4013,17 +4038,17 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method prefix. + METHOD prefix. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. - data ls_prefix type z2ui5_if_ajson_types=>ty_path_name. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + DATA ls_prefix TYPE z2ui5_if_ajson_types=>ty_path_name. ls_prefix-path = '/a/'. ls_prefix-name = 'b'. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( '/a/ |b |num |1 ||' ). lt_nodes = lcl_abap_to_json=>convert( @@ -4034,20 +4059,20 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_obj. + METHOD set_obj. - data lo_nodes_exp type ref to lcl_nodes_helper. - data ls_struc type ty_struc. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA ls_struc TYPE ty_struc. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. ls_struc-a = 'abc'. ls_struc-b = 10. ls_struc-c = abap_true. ls_struc-d = 'X'. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||4' ). lo_nodes_exp->add( '/ |a |str |abc ||0' ). lo_nodes_exp->add( '/ |b |num |10 ||0' ). @@ -4060,14 +4085,14 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_complex_obj. + METHOD set_complex_obj. - data lo_nodes_exp type ref to lcl_nodes_helper. - data ls_struc type ty_struc_complex. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. - field-symbols like line of ls_struc-tab. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA ls_struc TYPE ty_struc_complex. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. + FIELD-SYMBOLS LIKE LINE OF ls_struc-tab. ls_struc-a = 'abc'. ls_struc-b = 10. @@ -4078,15 +4103,15 @@ class ltcl_abap_to_json implementation. ls_struc-struc-a = 'deep'. ls_struc-struc-b = 123. - append 'hello' to ls_struc-stab. - append 'world' to ls_struc-stab. + APPEND 'hello' TO ls_struc-stab. + APPEND 'world' TO ls_struc-stab. - append initial line to ls_struc-tab assigning . + APPEND INITIAL LINE TO ls_struc-tab ASSIGNING . -a = 'abc'. - append initial line to ls_struc-tab assigning . + APPEND INITIAL LINE TO ls_struc-tab ASSIGNING . -a = 'bcd'. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||8' ). lo_nodes_exp->add( '/ |a |str |abc ||0' ). lo_nodes_exp->add( '/ |b |num |10 ||0' ). @@ -4121,13 +4146,13 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_include_with_suffix. + METHOD set_include_with_suffix. - data lo_nodes_exp type ref to lcl_nodes_helper. - data ls_struc type ty_named_include. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA ls_struc TYPE ty_named_include. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. ls_struc-a_suf = 'abc'. ls_struc-b_suf = 10. @@ -4135,7 +4160,7 @@ class ltcl_abap_to_json implementation. ls_struc-d_suf = 'X'. ls_struc-el = 'elem'. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | ||5' ). lo_nodes_exp->add( '/ |a_suf |str |abc ||0' ). lo_nodes_exp->add( '/ |b_suf |num |10 ||0' ). @@ -4149,24 +4174,24 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. - method set_array. + METHOD set_array. - data lo_nodes_exp type ref to lcl_nodes_helper. - data lt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. + DATA lt_nodes TYPE z2ui5_if_ajson_types=>ty_nodes_tt. - data lt_tab type table of ty_struc. - field-symbols like line of lt_tab. + DATA lt_tab TYPE TABLE OF ty_struc. + FIELD-SYMBOLS LIKE LINE OF lt_tab. - append initial line to lt_tab assigning . + APPEND INITIAL LINE TO lt_tab ASSIGNING . -a = 'abc'. -b = 10. - append initial line to lt_tab assigning . + APPEND INITIAL LINE TO lt_tab ASSIGNING . -a = 'bcd'. -b = 20. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |array | | |2' ). lo_nodes_exp->add( '/ |1 |object | |1|4' ). lo_nodes_exp->add( '/1/ |a |str |abc | |0' ). @@ -4185,11 +4210,11 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - data lt_strtab type string_table. - append 'abc' to lt_strtab. - append 'bcd' to lt_strtab. + DATA lt_strtab TYPE string_table. + APPEND 'abc' TO lt_strtab. + APPEND 'bcd' TO lt_strtab. - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |array | | |2' ). lo_nodes_exp->add( '/ |1 |str |abc |1|0' ). lo_nodes_exp->add( '/ |2 |str |bcd |2|0' ). @@ -4200,60 +4225,60 @@ class ltcl_abap_to_json implementation. act = lt_nodes exp = lo_nodes_exp->mt_nodes ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * FILTER TEST ********************************************************************** -class ltcl_filter_test definition final - for testing - duration short - risk level harmless. +CLASS ltcl_filter_test DEFINITION FINAL + FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. - public section. - interfaces z2ui5_if_ajson_filter. + PUBLIC SECTION. + INTERFACES z2ui5_if_ajson_filter. - private section. + PRIVATE SECTION. - types: - begin of ty_visit_history, - path type string, - type type z2ui5_if_ajson_filter=>ty_visit_type, - end of ty_visit_history. + TYPES: + BEGIN OF ty_visit_history, + path TYPE string, + type TYPE z2ui5_if_ajson_filter=>ty_visit_type, + END OF ty_visit_history. - data mt_visit_history type table of ty_visit_history. + DATA mt_visit_history TYPE TABLE OF ty_visit_history. - methods simple_test for testing raising z2UI5_cx_ajson_error. - methods array_test for testing raising z2UI5_cx_ajson_error. - methods visit_types for testing raising z2UI5_cx_ajson_error. + METHODS simple_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS array_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS visit_types FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class ltcl_filter_test implementation. +CLASS ltcl_filter_test IMPLEMENTATION. - method z2ui5_if_ajson_filter~keep_node. + METHOD z2ui5_if_ajson_filter~keep_node. - data ls_visit_history like line of mt_visit_history. + DATA ls_visit_history LIKE LINE OF mt_visit_history. - if iv_visit > 0. + IF iv_visit > 0. ls_visit_history-type = iv_visit. ls_visit_history-path = is_node-path && is_node-name && '/'. - append ls_visit_history to mt_visit_history. - endif. + APPEND ls_visit_history TO mt_visit_history. + ENDIF. - rv_keep = boolc( not is_node-name ca 'xX' and not is_node-value ca 'xX' ). + rv_keep = boolc( NOT is_node-name CA 'xX' AND NOT is_node-value CA 'xX' ). - endmethod. + ENDMETHOD. - method simple_test. + METHOD simple_test. - data lo_json type ref to z2ui5_cl_ajson. - data lo_json_filtered type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lo_json_filtered TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->set( @@ -4276,7 +4301,7 @@ class ltcl_filter_test implementation. ii_source_json = lo_json ii_filter = me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |3' ). lo_nodes_exp->add( '/ |a |num |1 | |0' ). lo_nodes_exp->add( '/ |b |num |1 | |0' ). @@ -4287,13 +4312,13 @@ class ltcl_filter_test implementation. act = lo_json_filtered->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method array_test. + METHOD array_test. - data lo_json type ref to z2ui5_cl_ajson. - data lo_json_filtered type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lo_json_filtered TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->touch_array( '/' ). @@ -4311,7 +4336,7 @@ class ltcl_filter_test implementation. ii_source_json = lo_json ii_filter = me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |array | | |2' ). lo_nodes_exp->add( '/ |1 |str |a |1|0' ). lo_nodes_exp->add( '/ |2 |str |b |2|0' ). @@ -4320,23 +4345,23 @@ class ltcl_filter_test implementation. act = lo_json_filtered->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method visit_types. + METHOD visit_types. - data lo_json type ref to z2ui5_cl_ajson. - data lo_json_filtered type ref to z2ui5_cl_ajson. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lo_json_filtered TYPE REF TO z2ui5_cl_ajson. - data lt_visits_exp like mt_visit_history. - field-symbols like line of lt_visits_exp. + DATA lt_visits_exp LIKE mt_visit_history. + FIELD-SYMBOLS LIKE LINE OF lt_visits_exp. - data: - begin of ls_dummy, - d type i value 10, - e type i value 20, - end of ls_dummy. + DATA: + BEGIN OF ls_dummy, + d TYPE i VALUE 10, + e TYPE i VALUE 20, + END OF ls_dummy. - clear mt_visit_history. + CLEAR mt_visit_history. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->touch_array( '/' ). @@ -4354,16 +4379,16 @@ class ltcl_filter_test implementation. ii_source_json = lo_json ii_filter = me ). - append initial line to lt_visits_exp assigning . + APPEND INITIAL LINE TO lt_visits_exp ASSIGNING . -path = '/'. -type = z2ui5_if_ajson_filter=>visit_type-open. - append initial line to lt_visits_exp assigning . + APPEND INITIAL LINE TO lt_visits_exp ASSIGNING . -path = '/3/'. -type = z2ui5_if_ajson_filter=>visit_type-open. - append initial line to lt_visits_exp assigning . + APPEND INITIAL LINE TO lt_visits_exp ASSIGNING . -path = '/3/'. -type = z2ui5_if_ajson_filter=>visit_type-close. - append initial line to lt_visits_exp assigning . + APPEND INITIAL LINE TO lt_visits_exp ASSIGNING . -path = '/'. -type = z2ui5_if_ajson_filter=>visit_type-close. @@ -4371,58 +4396,58 @@ class ltcl_filter_test implementation. act = mt_visit_history exp = lt_visits_exp ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * MAPPER TEST ********************************************************************** -class ltcl_mapper_test definition final - for testing - duration short - risk level harmless. +CLASS ltcl_mapper_test DEFINITION FINAL + FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. - public section. - interfaces z2ui5_if_ajson_mapping. + PUBLIC SECTION. + INTERFACES z2ui5_if_ajson_mapping. - private section. + PRIVATE SECTION. - methods simple_test for testing raising z2UI5_cx_ajson_error. - methods array_test for testing raising z2UI5_cx_ajson_error. - methods duplication_test for testing raising z2UI5_cx_ajson_error. - methods empty_name_test for testing raising z2UI5_cx_ajson_error. - methods trivial for testing raising z2UI5_cx_ajson_error. + METHODS simple_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS array_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS duplication_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS empty_name_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS trivial FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class ltcl_mapper_test implementation. +CLASS ltcl_mapper_test IMPLEMENTATION. - method z2ui5_if_ajson_mapping~rename_node. - if cv_name+0(1) = 'a'. + METHOD z2ui5_if_ajson_mapping~rename_node. + IF cv_name+0(1) = 'a'. cv_name = to_upper( cv_name ). - endif. - if cv_name = 'set_this_empty'. - clear cv_name. - endif. + ENDIF. + IF cv_name = 'set_this_empty'. + CLEAR cv_name. + ENDIF. " watch dog for array - if is_node-index <> 0. + IF is_node-index <> 0. cl_abap_unit_assert=>fail( 'rename must not be called for direct array items' ). - endif. - endmethod. + ENDIF. + ENDMETHOD. - method z2ui5_if_ajson_mapping~to_abap. - endmethod. + METHOD z2ui5_if_ajson_mapping~to_abap. + ENDMETHOD. - method z2ui5_if_ajson_mapping~to_json. - endmethod. + METHOD z2ui5_if_ajson_mapping~to_json. + ENDMETHOD. - method simple_test. + METHOD simple_test. - data lo_json type ref to z2ui5_cl_ajson. - data lo_json_filtered type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lo_json_filtered TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->set( @@ -4448,7 +4473,7 @@ class ltcl_mapper_test implementation. ii_source_json = lo_json ii_mapper = me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |4' ). lo_nodes_exp->add( '/ |AB |num |1 | |0' ). lo_nodes_exp->add( '/ |bc |num |2 | |0' ). @@ -4463,13 +4488,13 @@ class ltcl_mapper_test implementation. act = lo_json_filtered->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method array_test. + METHOD array_test. - data lo_json type ref to z2ui5_cl_ajson. - data lo_json_filtered type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lo_json_filtered TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->touch_array( iv_path = '/' ). @@ -4490,7 +4515,7 @@ class ltcl_mapper_test implementation. ii_source_json = lo_json ii_mapper = me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |array | | |2' ). lo_nodes_exp->add( '/ |1 |object | |1|2' ). lo_nodes_exp->add( '/ |2 |object | |2|2' ). @@ -4502,12 +4527,12 @@ class ltcl_mapper_test implementation. cl_abap_unit_assert=>assert_equals( act = lo_json_filtered->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method duplication_test. + METHOD duplication_test. - data lo_json type ref to z2ui5_cl_ajson. - data lx_err type ref to z2UI5_cx_ajson_error. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lx_err TYPE REF TO z2ui5_cx_ajson_error. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->set( @@ -4517,24 +4542,24 @@ class ltcl_mapper_test implementation. iv_path = '/AB' iv_val = 2 ). - try. - z2ui5_cl_ajson=>create_from( - ii_source_json = lo_json - ii_mapper = me ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx_err. - cl_abap_unit_assert=>assert_char_cp( - act = lx_err->get_text( ) - exp = 'Renamed node has a duplicate @/AB' ). - endtry. + TRY. + z2ui5_cl_ajson=>create_from( + ii_source_json = lo_json + ii_mapper = me ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx_err. + cl_abap_unit_assert=>assert_char_cp( + act = lx_err->get_text( ) + exp = 'Renamed node has a duplicate @/AB' ). + ENDTRY. - endmethod. + ENDMETHOD. - method trivial. + METHOD trivial. - data lo_json type ref to z2ui5_cl_ajson. - data lo_json_filtered type ref to z2ui5_cl_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lo_json_filtered TYPE REF TO z2ui5_cl_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json_filtered = z2ui5_cl_ajson=>create_from( @@ -4549,69 +4574,69 @@ class ltcl_mapper_test implementation. ii_source_json = lo_json ii_mapper = me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |num |1 | |0' ). cl_abap_unit_assert=>assert_equals( act = lo_json_filtered->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method empty_name_test. + METHOD empty_name_test. - data lo_json type ref to z2ui5_cl_ajson. - data lx_err type ref to z2UI5_cx_ajson_error. + DATA lo_json TYPE REF TO z2ui5_cl_ajson. + DATA lx_err TYPE REF TO z2ui5_cx_ajson_error. lo_json = z2ui5_cl_ajson=>create_empty( ). lo_json->set( iv_path = '/set_this_empty' iv_val = 1 ). - try. - z2ui5_cl_ajson=>create_from( - ii_source_json = lo_json - ii_mapper = me ). - cl_abap_unit_assert=>fail( ). - catch z2UI5_cx_ajson_error into lx_err. - cl_abap_unit_assert=>assert_char_cp( - act = lx_err->get_text( ) - exp = 'Renamed node name cannot be empty @/set_this_empty' ). - endtry. + TRY. + z2ui5_cl_ajson=>create_from( + ii_source_json = lo_json + ii_mapper = me ). + cl_abap_unit_assert=>fail( ). + CATCH z2ui5_cx_ajson_error INTO lx_err. + cl_abap_unit_assert=>assert_char_cp( + act = lx_err->get_text( ) + exp = 'Renamed node name cannot be empty @/set_this_empty' ). + ENDTRY. - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. ********************************************************************** * CLONING TEST ********************************************************************** -class ltcl_cloning_test definition final - for testing - duration short - risk level harmless. +CLASS ltcl_cloning_test DEFINITION FINAL + FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. - public section. - interfaces z2ui5_if_ajson_mapping. - interfaces z2ui5_if_ajson_filter. + PUBLIC SECTION. + INTERFACES z2ui5_if_ajson_mapping. + INTERFACES z2ui5_if_ajson_filter. - private section. + PRIVATE SECTION. - methods clone_test for testing raising z2UI5_cx_ajson_error. - methods filter_test for testing raising z2UI5_cx_ajson_error. - methods mapper_test for testing raising z2UI5_cx_ajson_error. - methods mapper_and_filter for testing raising z2UI5_cx_ajson_error. - methods opts_copying for testing raising z2UI5_cx_ajson_error. + METHODS clone_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS filter_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS mapper_test FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS mapper_and_filter FOR TESTING RAISING z2ui5_cx_ajson_error. + METHODS opts_copying FOR TESTING RAISING z2ui5_cx_ajson_error. -endclass. +ENDCLASS. -class ltcl_cloning_test implementation. +CLASS ltcl_cloning_test IMPLEMENTATION. - method clone_test. + METHOD clone_test. - data li_json type ref to z2ui5_if_ajson. - data li_json_new type ref to z2ui5_if_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA li_json TYPE REF TO z2ui5_if_ajson. + DATA li_json_new TYPE REF TO z2ui5_if_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. li_json = z2ui5_cl_ajson=>create_empty( ). li_json->set( @@ -4623,7 +4648,7 @@ class ltcl_cloning_test implementation. li_json_new = li_json->clone( ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |2' ). lo_nodes_exp->add( '/ |ab |num |1 | |0' ). lo_nodes_exp->add( '/ |xy |num |2 | |0' ). @@ -4646,13 +4671,13 @@ class ltcl_cloning_test implementation. act = li_json_new->get_integer( '/ab' ) exp = 1 ). - endmethod. + ENDMETHOD. - method filter_test. + METHOD filter_test. - data li_json type ref to z2ui5_if_ajson. - data li_json_new type ref to z2ui5_if_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA li_json TYPE REF TO z2ui5_if_ajson. + DATA li_json_new TYPE REF TO z2ui5_if_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. li_json = z2ui5_cl_ajson=>create_empty( ). li_json->set( @@ -4664,7 +4689,7 @@ class ltcl_cloning_test implementation. li_json_new = li_json->filter( me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |1' ). lo_nodes_exp->add( '/ |ab |num |1 | |0' ). @@ -4672,13 +4697,13 @@ class ltcl_cloning_test implementation. act = li_json_new->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method mapper_test. + METHOD mapper_test. - data li_json type ref to z2ui5_if_ajson. - data li_json_new type ref to z2ui5_if_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA li_json TYPE REF TO z2ui5_if_ajson. + DATA li_json_new TYPE REF TO z2ui5_if_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. li_json = z2ui5_cl_ajson=>create_empty( ). li_json->set( @@ -4690,7 +4715,7 @@ class ltcl_cloning_test implementation. li_json_new = li_json->map( me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |2' ). lo_nodes_exp->add( '/ |AB |num |1 | |0' ). lo_nodes_exp->add( '/ |xy |num |2 | |0' ). @@ -4699,31 +4724,31 @@ class ltcl_cloning_test implementation. act = li_json_new->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method z2ui5_if_ajson_mapping~rename_node. - if cv_name+0(1) = 'a'. + METHOD z2ui5_if_ajson_mapping~rename_node. + IF cv_name+0(1) = 'a'. cv_name = to_upper( cv_name ). - endif. - endmethod. + ENDIF. + ENDMETHOD. - method z2ui5_if_ajson_mapping~to_abap. + METHOD z2ui5_if_ajson_mapping~to_abap. - endmethod. + ENDMETHOD. - method z2ui5_if_ajson_mapping~to_json. + METHOD z2ui5_if_ajson_mapping~to_json. - endmethod. + ENDMETHOD. - method z2ui5_if_ajson_filter~keep_node. - rv_keep = boolc( is_node-name is initial or is_node-name+0(1) <> 'x' ). - endmethod. + METHOD z2ui5_if_ajson_filter~keep_node. + rv_keep = boolc( is_node-name IS INITIAL OR is_node-name+0(1) <> 'x' ). + ENDMETHOD. - method mapper_and_filter. + METHOD mapper_and_filter. - data li_json type ref to z2ui5_if_ajson. - data li_json_new type ref to z2ui5_if_ajson. - data lo_nodes_exp type ref to lcl_nodes_helper. + DATA li_json TYPE REF TO z2ui5_if_ajson. + DATA li_json_new TYPE REF TO z2ui5_if_ajson. + DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper. li_json = z2ui5_cl_ajson=>new( ). li_json->set( @@ -4741,7 +4766,7 @@ class ltcl_cloning_test implementation. ii_filter = me ii_mapper = me ). - create object lo_nodes_exp. + CREATE OBJECT lo_nodes_exp. lo_nodes_exp->add( ' | |object | | |2' ). lo_nodes_exp->add( '/ |AB |num |1 | |0' ). lo_nodes_exp->add( '/ |bc |num |2 | |0' ). @@ -4750,12 +4775,12 @@ class ltcl_cloning_test implementation. act = li_json_new->mt_json_tree exp = lo_nodes_exp->sorted( ) ). - endmethod. + ENDMETHOD. - method opts_copying. + METHOD opts_copying. - data li_json type ref to z2ui5_if_ajson. - data li_json_new type ref to z2ui5_if_ajson. + DATA li_json TYPE REF TO z2ui5_if_ajson. + DATA li_json_new TYPE REF TO z2ui5_if_ajson. li_json = z2ui5_cl_ajson=>new( )->keep_item_order( ). li_json->set( @@ -4768,6 +4793,6 @@ class ltcl_cloning_test implementation. act = li_json_new->opts( )-keep_item_order exp = abap_true ). - endmethod. + ENDMETHOD. -endclass. +ENDCLASS. diff --git a/src/01/01/z2ui5_cl_util_func.clas.abap b/src/01/01/z2ui5_cl_util_func.clas.abap index 49634d96..e8c881a7 100644 --- a/src/01/01/z2ui5_cl_util_func.clas.abap +++ b/src/01/01/z2ui5_cl_util_func.clas.abap @@ -414,7 +414,7 @@ ENDCLASS. -CLASS Z2UI5_CL_UTIL_FUNC IMPLEMENTATION. +CLASS z2ui5_cl_util_func IMPLEMENTATION. METHOD app_get_url. @@ -857,7 +857,7 @@ CLASS Z2UI5_CL_UTIL_FUNC IMPLEMENTATION. result = result && cl_abap_char_utilities=>cr_lf. - data lr_row type ref to data. + DATA lr_row TYPE REF TO data. LOOP AT REFERENCE INTO lr_row. DATA(lv_index) = 1. @@ -1244,6 +1244,10 @@ CLASS Z2UI5_CL_UTIL_FUNC IMPLEMENTATION. METHOD trans_json_2_any. +* IF z2ui5_cl_fw_controller=>cv_check_ajson = abap_true. +* ASSERT 1 = 0. +* ENDIF. + /ui2/cl_json=>deserialize( EXPORTING json = CONV string( val ) @@ -1256,6 +1260,10 @@ CLASS Z2UI5_CL_UTIL_FUNC IMPLEMENTATION. METHOD trans_json_by_any. +* IF z2ui5_cl_fw_controller=>cv_check_ajson = abap_true. +* ASSERT 1 = 0. +* ENDIF. + CASE compress_mode. WHEN z2ui5_if_client=>cs_compress_mode-full. @@ -1440,14 +1448,14 @@ CLASS Z2UI5_CL_UTIL_FUNC IMPLEMENTATION. " support for ISO8601 => https://en.wikipedia.org/wiki/ISO_8601 REPLACE FIRST OCCURRENCE OF REGEX `^(\d{4})-(\d{2})-(\d{2})` IN WITH `$1$2$3` - REPLACEMENT LENGTH match. "#EC NOTEXT + REPLACEMENT LENGTH match. "#EC NOTEXT = . WHEN `\TYPE=T`. " support for ISO8601 => https://en.wikipedia.org/wiki/ISO_8601 REPLACE FIRST OCCURRENCE OF REGEX `^(\d{2}):(\d{2}):(\d{2})` IN WITH `$1$2$3` - REPLACEMENT LENGTH match. "#EC NOTEXT + REPLACEMENT LENGTH match. "#EC NOTEXT = . WHEN OTHERS. diff --git a/src/01/02/z2ui5_cl_fw_binding.clas.abap b/src/01/02/z2ui5_cl_fw_binding.clas.abap index e93a7840..d03e2b80 100644 --- a/src/01/02/z2ui5_cl_fw_binding.clas.abap +++ b/src/01/02/z2ui5_cl_fw_binding.clas.abap @@ -29,7 +29,9 @@ CLASS z2ui5_cl_fw_binding DEFINITION viewname TYPE string, pretty_name TYPE abap_bool, compress TYPE string, + compress_custom TYPE string, depth TYPE i, + ajson_local TYPE REF TO z2ui5_if_ajson, END OF ty_s_attri. TYPES ty_t_attri TYPE SORTED TABLE OF ty_s_attri WITH UNIQUE KEY name. @@ -43,6 +45,7 @@ CLASS z2ui5_cl_fw_binding DEFINITION view TYPE clike OPTIONAL pretty_name TYPE clike OPTIONAL compress TYPE clike OPTIONAL + compress_custom TYPE clike OPTIONAL RETURNING VALUE(r_result) TYPE REF TO z2ui5_cl_fw_binding. @@ -58,6 +61,7 @@ CLASS z2ui5_cl_fw_binding DEFINITION DATA mv_view TYPE string. DATA mv_pretty_name TYPE string. DATA mv_compress TYPE string. + DATA mv_compress_custom TYPE string. CLASS-METHODS update_attri IMPORTING @@ -147,7 +151,6 @@ CLASS z2ui5_cl_fw_binding IMPLEMENTATION. RETURN. ENDIF. - GET REFERENCE OF INTO lr_ref. IF mr_data <> lr_ref. @@ -174,31 +177,74 @@ CLASS z2ui5_cl_fw_binding IMPLEMENTATION. bind->bind_type = mv_type. bind->pretty_name = mv_pretty_name. bind->compress = mv_compress. - bind->name_front = name_front_create( bind->name ). bind->viewname = mv_view. + bind->compress_custom = mv_compress_custom. - result = COND #( WHEN mv_type = cs_bind_type-two_way THEN `/` && cv_model_edit_name && `/` ELSE `/` ) && bind->name_front. - IF strlen( result ) > 30. - bind->name_front = z2ui5_cl_util_func=>uuid_get_c22( ). + IF z2ui5_cl_fw_controller=>cv_check_ajson = abap_false. + + bind->name_front = name_front_create( bind->name ). result = COND #( WHEN mv_type = cs_bind_type-two_way THEN `/` && cv_model_edit_name && `/` ELSE `/` ) && bind->name_front. + IF strlen( result ) > 30. + bind->name_front = z2ui5_cl_util_func=>uuid_get_c22( ). + result = COND #( WHEN mv_type = cs_bind_type-two_way THEN `/` && cv_model_edit_name && `/` ELSE `/` ) && bind->name_front. + ENDIF. + + ELSE. + + bind->name_front = replace( val = bind->name sub = `-` with = `/` ). + bind->name_front = replace( val = bind->name_front sub = `>` with = `` ). + result = `/` && COND #( WHEN mv_type = cs_bind_type-two_way THEN cv_model_edit_name && `/` ) && bind->name_front. ENDIF. ENDMETHOD. METHOD bind_local. + TRY. - FIELD-SYMBOLS TYPE any. - ASSIGN mr_data->* TO . - DATA(lv_id) = z2ui5_cl_util_func=>uuid_get_c22( ). + FIELD-SYMBOLS TYPE any. + ASSIGN mr_data->* TO . + DATA(lv_id) = to_upper( z2ui5_cl_util_func=>uuid_get_c22( ) ). - INSERT VALUE #( name = lv_id - data_stringify = z2ui5_cl_util_func=>trans_json_by_any( any = mr_data - compress_mode = me->mv_compress ) - bind_type = cs_bind_type-one_time ) - INTO TABLE mt_attri. - result = |/{ lv_id }|. + IF z2ui5_cl_fw_controller=>cv_check_ajson = abap_false. + INSERT VALUE #( name = lv_id + data_stringify = z2ui5_cl_util_func=>trans_json_by_any( any = mr_data + compress_mode = me->mv_compress ) + bind_type = cs_bind_type-one_time ) + INTO TABLE mt_attri. + + ELSE. + + "(1) set pretty mode + CASE mv_pretty_name. + + WHEN z2ui5_if_client=>cs_pretty_mode-none. + DATA(ajson) = CAST z2ui5_if_ajson( z2ui5_cl_ajson=>create_empty( ii_custom_mapping = z2ui5_cl_ajson_mapping=>create_upper_case( ) ) ). + + WHEN z2ui5_if_client=>cs_pretty_mode-camel_case. + ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ) ). + + WHEN OTHERS. + ASSERT `` = `ERROR_UNKNOWN_PRETTY_MODE`. + ENDCASE. + + INSERT VALUE #( name_front = lv_id + name = lv_id + ajson_local = ajson->set( iv_path = `/` iv_val = ) + bind_type = cs_bind_type-one_time + pretty_name = mv_pretty_name + compress = mv_compress + ) + INTO TABLE mt_attri. + + ENDIF. + + result = |/{ lv_id }|. + + CATCH cx_root INTO DATA(x). + ASSERT x IS NOT BOUND. + ENDTRY. ENDMETHOD. @@ -275,6 +321,7 @@ CLASS z2ui5_cl_fw_binding IMPLEMENTATION. r_result->mv_view = view. r_result->mv_pretty_name = pretty_name. r_result->mv_compress = compress. + r_result->mv_compress_custom = to_upper( compress_custom ). IF z2ui5_cl_util_func=>rtti_check_type_kind_dref( data ). diff --git a/src/01/02/z2ui5_cl_fw_client.clas.abap b/src/01/02/z2ui5_cl_fw_client.clas.abap index 5378008a..91e7f052 100644 --- a/src/01/02/z2ui5_cl_fw_client.clas.abap +++ b/src/01/02/z2ui5_cl_fw_client.clas.abap @@ -334,7 +334,9 @@ CLASS z2ui5_cl_fw_client IMPLEMENTATION. type = z2ui5_cl_fw_binding=>cs_bind_type-one_way data = val pretty_name = pretty_mode - compress = compress_mode ). + compress = compress_mode + compress_custom = compress_custom + ). result = lo_binder->main( ). mo_handler->ms_db-t_attri = lo_binder->mt_attri. @@ -407,7 +409,8 @@ CLASS z2ui5_cl_fw_client IMPLEMENTATION. data = val view = view pretty_name = pretty_mode - compress = compress_mode ). + compress = compress_mode + compress_custom = compress_custom ). result = lo_binder->main( ). mo_handler->ms_db-t_attri = lo_binder->mt_attri. @@ -429,7 +432,8 @@ CLASS z2ui5_cl_fw_client IMPLEMENTATION. type = z2ui5_cl_fw_binding=>cs_bind_type-one_time data = val pretty_name = pretty_mode - compress = compress_mode ). + compress = compress_mode + compress_custom = compress_custom ). result = lo_binder->main( ). mo_handler->ms_db-t_attri = lo_binder->mt_attri. diff --git a/src/01/02/z2ui5_cl_fw_controller.clas.abap b/src/01/02/z2ui5_cl_fw_controller.clas.abap index b18f8fa8..206b8902 100644 --- a/src/01/02/z2ui5_cl_fw_controller.clas.abap +++ b/src/01/02/z2ui5_cl_fw_controller.clas.abap @@ -4,8 +4,7 @@ CLASS z2ui5_cl_fw_controller DEFINITION CREATE PUBLIC. PUBLIC SECTION. - - CONSTANTS cv_check_ajson TYPE abap_bool VALUE abap_false. + class-data cv_check_ajson TYPE abap_bool VALUE abap_true. TYPES: BEGIN OF ty_s_next2, @@ -146,63 +145,21 @@ ENDCLASS. -CLASS z2ui5_cl_fw_controller IMPLEMENTATION. +CLASS Z2UI5_CL_FW_CONTROLLER IMPLEMENTATION. - METHOD main. - TRY. - DATA(lo_handler) = request_begin( body ). - CATCH cx_root INTO DATA(x). - lo_handler = app_system_factory( x ). - ENDTRY. + METHOD app_call_factory. - DO. - TRY. + result = app_next_factory( ms_next-o_app_call ). + result->ms_db-id_prev_app_stack = ms_db-id. - ROLLBACK WORK. - CAST z2ui5_if_app( lo_handler->ms_db-app )->main( NEW z2ui5_cl_fw_client( lo_handler ) ). - ROLLBACK WORK. + CLEAR ms_next. + IF check_no_db_save = abap_false. + z2ui5_cl_fw_db=>create( id = ms_db-id + db = ms_db ). + ENDIF. - IF lo_handler->ms_next-o_app_leave IS NOT INITIAL. - lo_handler = lo_handler->app_leave_factory( ). - CONTINUE. - ENDIF. - - IF lo_handler->ms_next-o_app_call IS NOT INITIAL. - lo_handler = lo_handler->app_call_factory( ). - CONTINUE. - ENDIF. - - result = lo_handler->request_end( ). - - CATCH cx_root INTO x. - lo_handler = app_system_factory( x ). - CONTINUE. - ENDTRY. - - EXIT. - ENDDO. - - ENDMETHOD. - - METHOD app_next_factory. - - app->id_draft = COND #( WHEN app->id_draft IS INITIAL THEN z2ui5_cl_util_func=>uuid_get_c32( ) ELSE app->id_draft ). - - r_result = NEW #( ). - r_result->ms_db-app = app. - r_result->ms_db-id = app->id_draft. - r_result->ms_db-id_prev = ms_db-id. - r_result->ms_db-id_prev_app = ms_db-id. - r_result->ms_actual-check_launchpad_active = ms_actual-check_launchpad_active. - r_result->ms_actual-check_on_navigated = abap_true. - r_result->ms_next-s_set = ms_next-s_set. - - TRY. - DATA(ls_db_next) = z2ui5_cl_fw_db=>load_app( app->id_draft ). - r_result->ms_db-t_attri = ls_db_next-t_attri. - CATCH cx_root. - ENDTRY. + CLEAR result->ms_db-t_attri. ENDMETHOD. @@ -249,6 +206,199 @@ CLASS z2ui5_cl_fw_controller IMPLEMENTATION. ENDMETHOD. + METHOD app_client_begin_factory. + + result = NEW #( ). + result->ms_db = z2ui5_cl_fw_db=>load_app( id_prev ). + result->ms_db-id = z2ui5_cl_util_func=>uuid_get_c32( ). + result->ms_db-id_prev = id_prev. + + TRY. + result->ms_actual-viewname = so_body->get_attribute( `VIEWNAME` )->get_val( ). + CATCH cx_root. + ENDTRY. + + ENDMETHOD. + + + METHOD app_client_begin_model. + + IF cv_check_ajson = abap_false. + + TRY. + DATA(lo_model) = z2ui5_cl_fw_model=>factory( + viewname = ms_actual-viewname + app = ms_db-app + attri = ms_db-t_attri ). + + lo_model->main_set_backend( + so_body->get_attribute( ss_config-view_model_edit_name )->mr_actual ). + + CATCH cx_root. + ENDTRY. + + ELSE. + + z2ui5_cl_fw_model_ajson=>front_to_back( + viewname = ms_actual-viewname + app = ms_db-app + t_attri = ms_db-t_attri + json_string = ss_config-body + ). + + ENDIF. + + ENDMETHOD. + + + METHOD app_client_end_db. + + z2ui5_cl_fw_db=>create( id = ms_db-id + db = ms_db ). + + ENDMETHOD. + + + METHOD app_client_end_model. + + IF cv_check_ajson = abap_false. + + DATA(lo_binder) = z2ui5_cl_fw_model=>factory( + viewname = ms_actual-viewname + app = ms_db-app + attri = ms_db-t_attri ). + + rv_viewmodel = lo_binder->main_set_frontend( ). + + ELSE. + + rv_viewmodel = z2ui5_cl_fw_model_ajson=>back_to_front( + app = ms_db-app + t_attri = ms_db-t_attri + ). + + ENDIF. + + ENDMETHOD. + + + METHOD app_client_end_response. + + DATA(lo_resp) = z2ui5_cl_util_tree_json=>factory( ). + + lo_resp->add_attribute( n = `OVIEWMODEL` + v = iv_viewmodel + apos_active = abap_false ). + + lo_resp->add_attribute( n = `PARAMS` + v = z2ui5_cl_util_func=>trans_json_by_any( ms_next-s_set ) + apos_active = abap_false ). + + lo_resp->add_attribute( n = `ID` + v = ms_db-id ). + + r_result = lo_resp->mo_root->stringify( ). + + ENDMETHOD. + + + METHOD app_leave_factory. + + result = app_next_factory( ms_next-o_app_leave ). + + TRY. + DATA(ls_draft) = z2ui5_cl_fw_db=>read( id = result->ms_db-id + check_load_app = abap_false ). + result->ms_db-id_prev_app_stack = ls_draft-id_prev_app_stack. + CATCH cx_root. + result->ms_db-id_prev_app_stack = ms_db-id_prev_app_stack. + ENDTRY. + + CLEAR ms_next. + IF check_no_db_save = abap_false. + z2ui5_cl_fw_db=>create( id = ms_db-id + db = ms_db ). + ENDIF. + + ENDMETHOD. + + + METHOD app_next_factory. + + app->id_draft = COND #( WHEN app->id_draft IS INITIAL THEN z2ui5_cl_util_func=>uuid_get_c32( ) ELSE app->id_draft ). + + r_result = NEW #( ). + r_result->ms_db-app = app. + r_result->ms_db-id = app->id_draft. + r_result->ms_db-id_prev = ms_db-id. + r_result->ms_db-id_prev_app = ms_db-id. + r_result->ms_actual-check_launchpad_active = ms_actual-check_launchpad_active. + r_result->ms_actual-check_on_navigated = abap_true. + r_result->ms_next-s_set = ms_next-s_set. + + TRY. + DATA(ls_db_next) = z2ui5_cl_fw_db=>load_app( app->id_draft ). + r_result->ms_db-t_attri = ls_db_next-t_attri. + CATCH cx_root. + ENDTRY. + + ENDMETHOD. + + + METHOD app_start_factory. + + TRY. + DATA(lv_classname) = to_upper( so_body->get_attribute( `APP_START` )->get_val( ) ). + lv_classname = z2ui5_cl_util_func=>c_trim( lv_classname ). + CATCH cx_root. + ENDTRY. + + IF lv_classname IS INITIAL. + lv_classname = z2ui5_cl_util_func=>url_param_get( val = `app_start` + url = ss_config-search ). + ENDIF. + + IF lv_classname IS INITIAL. + result = app_system_factory( ). + RETURN. + ENDIF. + + TRY. + result = NEW #( ). + result->ms_db-id = z2ui5_cl_util_func=>uuid_get_c32( ). + + lv_classname = z2ui5_cl_util_func=>c_trim_upper( lv_classname ). + CREATE OBJECT result->ms_db-app TYPE (lv_classname). + result->ms_db-app->id_draft = result->ms_db-id. + + CATCH cx_root. + result = app_system_factory( error_text = `App with name ` && lv_classname && ` not found...` ). + ENDTRY. + + ENDMETHOD. + + + METHOD app_system_factory. + + result = NEW #( ). + result->ms_db-id = z2ui5_cl_util_func=>uuid_get_c32( ). + + IF ix IS NOT BOUND AND error_text IS NOT INITIAL. + ix = NEW z2ui5_cx_util_error( val = error_text ). + ENDIF. + + IF ix IS BOUND. + result->ms_next-o_app_call = z2ui5_cl_fw_app_error=>factory( ix ). + result = result->app_call_factory( abap_true ). + RETURN. + ENDIF. + + result->ms_db-app = z2ui5_cl_fw_app_startup=>factory( ). + result->ms_db-app->id_draft = result->ms_db-id. + + ENDMETHOD. + + METHOD body_read_location. FIELD-SYMBOLS TYPE any. @@ -313,6 +463,44 @@ CLASS z2ui5_cl_fw_controller IMPLEMENTATION. ENDMETHOD. + METHOD main. + + TRY. + DATA(lo_handler) = request_begin( body ). + CATCH cx_root INTO DATA(x). + lo_handler = app_system_factory( x ). + ENDTRY. + + DO. + TRY. + + ROLLBACK WORK. + CAST z2ui5_if_app( lo_handler->ms_db-app )->main( NEW z2ui5_cl_fw_client( lo_handler ) ). + ROLLBACK WORK. + + IF lo_handler->ms_next-o_app_leave IS NOT INITIAL. + lo_handler = lo_handler->app_leave_factory( ). + CONTINUE. + ENDIF. + + IF lo_handler->ms_next-o_app_call IS NOT INITIAL. + lo_handler = lo_handler->app_call_factory( ). + CONTINUE. + ENDIF. + + result = lo_handler->request_end( ). + + CATCH cx_root INTO x. + lo_handler = app_system_factory( x ). + CONTINUE. + ENDTRY. + + EXIT. + ENDDO. + + ENDMETHOD. + + METHOD request_begin. ss_config-body = body. @@ -349,141 +537,6 @@ CLASS z2ui5_cl_fw_controller IMPLEMENTATION. ENDMETHOD. - METHOD app_call_factory. - - result = app_next_factory( ms_next-o_app_call ). - result->ms_db-id_prev_app_stack = ms_db-id. - - CLEAR ms_next. - IF check_no_db_save = abap_false. - z2ui5_cl_fw_db=>create( id = ms_db-id - db = ms_db ). - ENDIF. - - CLEAR result->ms_db-t_attri. - - ENDMETHOD. - - - METHOD app_client_begin_factory. - - result = NEW #( ). - result->ms_db = z2ui5_cl_fw_db=>load_app( id_prev ). - result->ms_db-id = z2ui5_cl_util_func=>uuid_get_c32( ). - result->ms_db-id_prev = id_prev. - - TRY. - result->ms_actual-viewname = so_body->get_attribute( `VIEWNAME` )->get_val( ). - CATCH cx_root. - ENDTRY. - - ENDMETHOD. - - - METHOD app_leave_factory. - - result = app_next_factory( ms_next-o_app_leave ). - - TRY. - DATA(ls_draft) = z2ui5_cl_fw_db=>read( id = result->ms_db-id - check_load_app = abap_false ). - result->ms_db-id_prev_app_stack = ls_draft-id_prev_app_stack. - CATCH cx_root. - result->ms_db-id_prev_app_stack = ms_db-id_prev_app_stack. - ENDTRY. - - CLEAR ms_next. - IF check_no_db_save = abap_false. - z2ui5_cl_fw_db=>create( id = ms_db-id - db = ms_db ). - ENDIF. - - ENDMETHOD. - - - METHOD app_start_factory. - - TRY. - DATA(lv_classname) = to_upper( so_body->get_attribute( `APP_START` )->get_val( ) ). - lv_classname = z2ui5_cl_util_func=>c_trim( lv_classname ). - CATCH cx_root. - ENDTRY. - - IF lv_classname IS INITIAL. - lv_classname = z2ui5_cl_util_func=>url_param_get( val = `app_start` - url = ss_config-search ). - ENDIF. - - IF lv_classname IS INITIAL. - result = app_system_factory( ). - RETURN. - ENDIF. - - TRY. - result = NEW #( ). - result->ms_db-id = z2ui5_cl_util_func=>uuid_get_c32( ). - - lv_classname = z2ui5_cl_util_func=>c_trim_upper( lv_classname ). - CREATE OBJECT result->ms_db-app TYPE (lv_classname). - result->ms_db-app->id_draft = result->ms_db-id. - - CATCH cx_root. - result = app_system_factory( error_text = `App with name ` && lv_classname && ` not found...` ). - ENDTRY. - - ENDMETHOD. - - - METHOD app_system_factory. - - result = NEW #( ). - result->ms_db-id = z2ui5_cl_util_func=>uuid_get_c32( ). - - IF ix IS NOT BOUND AND error_text IS NOT INITIAL. - ix = NEW z2ui5_cx_util_error( val = error_text ). - ENDIF. - - IF ix IS BOUND. - result->ms_next-o_app_call = z2ui5_cl_fw_app_error=>factory( ix ). - result = result->app_call_factory( abap_true ). - RETURN. - ENDIF. - - result->ms_db-app = z2ui5_cl_fw_app_startup=>factory( ). - result->ms_db-app->id_draft = result->ms_db-id. - - ENDMETHOD. - - METHOD app_client_begin_model. - - IF cv_check_ajson = abap_false. - - TRY. - DATA(lo_model) = z2ui5_cl_fw_model=>factory( - viewname = ms_actual-viewname - app = ms_db-app - attri = ms_db-t_attri ). - - lo_model->main_set_backend( - so_body->get_attribute( ss_config-view_model_edit_name )->mr_actual ). - - CATCH cx_root. - ENDTRY. - - ELSE. - - z2ui5_cl_fw_model_ajson=>front_to_back( - viewname = ms_actual-viewname - app = ms_db-app - t_attri = ms_db-t_attri - json_string = ss_config-body - ). - - ENDIF. - - ENDMETHOD. - - METHOD _get_id. TRY. @@ -492,56 +545,4 @@ CLASS z2ui5_cl_fw_controller IMPLEMENTATION. ENDTRY. ENDMETHOD. - - - METHOD app_client_end_model. - - IF cv_check_ajson = abap_false. - - DATA(lo_binder) = z2ui5_cl_fw_model=>factory( - viewname = ms_actual-viewname - app = ms_db-app - attri = ms_db-t_attri ). - - rv_viewmodel = lo_binder->main_set_frontend( ). - - ELSE. - - rv_viewmodel = z2ui5_cl_fw_model_ajson=>back_to_front( - app = ms_db-app - t_attri = ms_db-t_attri - ). - - ENDIF. - - ENDMETHOD. - - - METHOD app_client_end_response. - - DATA(lo_resp) = z2ui5_cl_util_tree_json=>factory( ). - - lo_resp->add_attribute( n = `OVIEWMODEL` - v = iv_viewmodel - apos_active = abap_false ). - - lo_resp->add_attribute( n = `PARAMS` - v = z2ui5_cl_util_func=>trans_json_by_any( ms_next-s_set ) - apos_active = abap_false ). - - lo_resp->add_attribute( n = `ID` - v = ms_db-id ). - - r_result = lo_resp->mo_root->stringify( ). - - ENDMETHOD. - - - METHOD app_client_end_db. - - z2ui5_cl_fw_db=>create( id = ms_db-id - db = ms_db ). - - ENDMETHOD. - ENDCLASS. diff --git a/src/01/02/z2ui5_cl_fw_index_html.clas.abap b/src/01/02/z2ui5_cl_fw_index_html.clas.abap index 95eeab62..2d6a42f7 100644 --- a/src/01/02/z2ui5_cl_fw_index_html.clas.abap +++ b/src/01/02/z2ui5_cl_fw_index_html.clas.abap @@ -51,8 +51,8 @@ CLASS Z2UI5_CL_FW_INDEX_HTML IMPLEMENTATION. IF lt_config IS INITIAL. lt_config = VALUE #( * ( n = `src` v = `https://sdk.openui5.org/nightly/2/resources/sap-ui-core.js` ) - ( n = `src` v = `https://sdk.openui5.org/resources/sap-ui-cachebuster/sap-ui-core.js` ) -* ( n = `src` v = `https://ui5.sap.com/1.120.0/resources/sap-ui-core.js` ) +* ( n = `src` v = `https://sdk.openui5.org/resources/sap-ui-cachebuster/sap-ui-core.js` ) + ( n = `src` v = `https://ui5.sap.com/1.120.0/resources/sap-ui-core.js` ) ( n = `data-sap-ui-theme` v = `sap_horizon` ) ( n = `data-sap-ui-async` v = `true` ) ( n = `data-sap-ui-bindingSyntax` v = `complex` ) @@ -177,7 +177,6 @@ CLASS Z2UI5_CL_FW_INDEX_HTML IMPLEMENTATION. ` const oFragment = await Fragment.load({` && |\n| && ` definition: xml,` && |\n| && ` controller: sap.z2ui5.oControllerPopup,` && |\n| && - ` id: "popupId"` && |\n| && ` });` && |\n| && ` let oview_model = new JSONModel(sap.z2ui5.oResponse.OVIEWMODEL);` && |\n| && ` oview_model.setSizeLimit(sap.z2ui5.JSON_MODEL_LIMIT);` && |\n| && @@ -194,7 +193,6 @@ CLASS Z2UI5_CL_FW_INDEX_HTML IMPLEMENTATION. ` const oFragment = await Fragment.load({` && |\n| && ` definition: xml,` && |\n| && ` controller: sap.z2ui5.oControllerPopover,` && |\n| && - ` id: "popoverId"` && |\n| && ` });` && |\n| && ` let oview_model = new JSONModel(sap.z2ui5.oResponse.OVIEWMODEL);` && |\n| && ` oview_model.setSizeLimit(sap.z2ui5.JSON_MODEL_LIMIT);` && |\n| && @@ -354,11 +352,6 @@ CLASS Z2UI5_CL_FW_INDEX_HTML IMPLEMENTATION. ` navConTo = sap.z2ui5.oViewNest2.byId(args[2]);` && |\n| && ` navCon.to(navConTo);` && |\n| && ` break;` && |\n| && - ` case 'POPUP_NAV_CONTAINER_TO':` && |\n| && - ` navCon = Fragment.byId("popupId",args[1]);` && |\n| && - ` navConTo = Fragment.byId("popupId",args[2]);` && |\n| && - ` navCon.to(navConTo);` && |\n| && - ` break;` && |\n| && ` }` && |\n| && ` },` && |\n| && ` onEvent(...args) {` && |\n| && diff --git a/src/01/02/z2ui5_cl_fw_model_ajson.clas.abap b/src/01/02/z2ui5_cl_fw_model_ajson.clas.abap index 59a92a21..f2a36ba8 100644 --- a/src/01/02/z2ui5_cl_fw_model_ajson.clas.abap +++ b/src/01/02/z2ui5_cl_fw_model_ajson.clas.abap @@ -24,10 +24,97 @@ CLASS z2ui5_cl_fw_model_ajson DEFINITION ENDCLASS. + CLASS z2ui5_cl_fw_model_ajson IMPLEMENTATION. + + METHOD back_to_front. + TRY. + + DATA(ajson_result) = CAST z2ui5_if_ajson( z2ui5_cl_ajson=>create_empty( ) ). + + LOOP AT t_attri REFERENCE INTO DATA(lr_attri) WHERE bind_type <> ``. + + + "(1) set pretty mode + CASE lr_attri->pretty_name. + + WHEN z2ui5_if_client=>cs_pretty_mode-none. + DATA(ajson) = CAST z2ui5_if_ajson( z2ui5_cl_ajson=>create_empty( ii_custom_mapping = z2ui5_cl_ajson_mapping=>create_upper_case( ) ) ). + + WHEN z2ui5_if_client=>cs_pretty_mode-camel_case. + ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ) ). + + WHEN OTHERS. + ASSERT `` = `ERROR_UNKNOWN_PRETTY_MODE`. + ENDCASE. + + + "(2) read attribute of end-user app + IF lr_attri->bind_type = z2ui5_cl_fw_binding=>cs_bind_type-one_way + OR lr_attri->bind_type = z2ui5_cl_fw_binding=>cs_bind_type-two_way. + DATA(lv_name_back) = `APP->` && lr_attri->name. + FIELD-SYMBOLS TYPE any. + ASSIGN (lv_name_back) TO . + ASSERT sy-subrc = 0. + ENDIF. + + + "(3) write into json + CASE lr_attri->bind_type. + + WHEN z2ui5_cl_fw_binding=>cs_bind_type-one_time. + DATA(lv_path) = lr_attri->name_front. + ajson->set( iv_ignore_empty = abap_false iv_path = `/` iv_val = lr_attri->ajson_local ). + + WHEN z2ui5_cl_fw_binding=>cs_bind_type-one_way. + lv_path = lr_attri->name_front. + ajson->set( iv_ignore_empty = abap_false iv_path = `/` iv_val = ). + + WHEN z2ui5_cl_fw_binding=>cs_bind_type-two_way. + lv_path = z2ui5_cl_fw_binding=>cv_model_edit_name && `/` && lr_attri->name_front. + ajson->set( iv_ignore_empty = abap_false iv_path = `/` iv_val = ). + + WHEN OTHERS. + ASSERT `` = `ERROR_UNKNOWN_BIND_MODE`. + ENDCASE. + + + "(4) set compress mode + "todo performance - add and filter in a single loop + IF lr_attri->compress_custom IS NOT INITIAL. + DATA li_filter TYPE REF TO z2ui5_if_ajson_filter. + CREATE OBJECT li_filter TYPE (lr_attri->compress_custom). + ajson = ajson->filter( li_filter ). + + ELSEIF lr_attri->compress = z2ui5_if_client=>cs_compress_mode-full. + "obsolete - is this still needed? use compress_custom instead + ASSERT `` = `OBSOLET_COMPRESS_MODE_USE_CUSTOM_INSTEAD`. + + ELSEIF lr_attri->compress = z2ui5_if_client=>cs_compress_mode-standard. + ajson = ajson->filter( z2ui5_cl_ajson_filter_lib=>create_empty_filter( ) ). + + ELSE. + ASSERT `` = `ERROR_UNKNOW_COMPRESS_MODE`. + ENDIF. + + + "(5) write into result + "todo performance - write directly into result + ajson_result->set( iv_path = `/` && lv_path iv_val = ajson ). + ENDLOOP. + + result = ajson_result->stringify( ). + + CATCH cx_root INTO DATA(x). + ASSERT x IS NOT BOUND. + ENDTRY. + ENDMETHOD. + + METHOD front_to_back. TRY. + DATA(ajson) = z2ui5_cl_ajson=>parse( json_string )->slice( `/EDIT` ). LOOP AT t_attri REFERENCE INTO DATA(lr_attri) @@ -42,6 +129,19 @@ CLASS z2ui5_cl_fw_model_ajson IMPLEMENTATION. DATA(ajson_val) = ajson->slice( `/` && lr_attri->name_front ). TRY. + + CASE lr_attri->pretty_name. + + WHEN z2ui5_if_client=>cs_pretty_mode-none. + + + WHEN z2ui5_if_client=>cs_pretty_mode-camel_case. + ajson_val = ajson_val->map( z2ui5_cl_ajson_mapping=>create_to_snake_case( ) ). + + WHEN OTHERS. + ASSERT `` = `ToDo -> UNKNOWN_PRETTY_MODE`. + ENDCASE. + ajson_val->to_abap( IMPORTING ev_container = ). @@ -51,40 +151,8 @@ CLASS z2ui5_cl_fw_model_ajson IMPLEMENTATION. ENDTRY. ENDLOOP. - CATCH cx_root. - ENDTRY. - - ENDMETHOD. - - METHOD back_to_front. - TRY. - - DATA(ajson) = z2ui5_cl_ajson=>create_empty( ). - - LOOP AT t_attri REFERENCE INTO DATA(lr_attri) WHERE bind_type <> ``. - - IF lr_attri->bind_type = z2ui5_cl_fw_binding=>cs_bind_type-one_time. - ajson->set( iv_path = `/` iv_val = z2ui5_cl_ajson=>parse( lr_attri->data_stringify ) ). - CONTINUE. - ENDIF. - - DATA(lv_name_back) = `APP->` && lr_attri->name. - FIELD-SYMBOLS TYPE any. - ASSIGN (lv_name_back) TO . - ASSERT 1 = 0. - - CASE lr_attri->bind_type. - WHEN z2ui5_cl_fw_binding=>cs_bind_type-one_way. - ajson->set( iv_path = `/` iv_val = ). - WHEN OTHERS. - ajson->set( iv_path = `/` && z2ui5_cl_fw_binding=>cv_model_edit_name iv_val = ). - ENDCASE. - - ENDLOOP. - - result = ajson->stringify( ). - - CATCH cx_root. + CATCH cx_root INTO DATA(x). + ASSERT x IS NOT BOUND. ENDTRY. ENDMETHOD. diff --git a/src/01/05/z2ui5_cl_cc_chartjs.clas.abap b/src/01/05/z2ui5_cl_cc_chartjs.clas.abap index fd53c2f4..3157571d 100644 --- a/src/01/05/z2ui5_cl_cc_chartjs.clas.abap +++ b/src/01/05/z2ui5_cl_cc_chartjs.clas.abap @@ -4,6 +4,9 @@ CLASS z2ui5_cl_cc_chartjs DEFINITION CREATE PUBLIC . PUBLIC SECTION. + + INTERFACES z2ui5_if_ajson_filter. + " Data TYPES: BEGIN OF ty_x_y_r_data, @@ -428,8 +431,8 @@ CLASS z2ui5_cl_cc_chartjs DEFINITION stack_weight TYPE i, stack TYPE string, position TYPE string, - ticks TYPE ty_ticks, - border TYPE ty_border, + ticks TYPE ty_ticks, + border TYPE ty_border, grid TYPE ty_grid, offset TYPE abap_bool, axis TYPE string, @@ -542,8 +545,8 @@ CLASS z2ui5_cl_cc_chartjs DEFINITION TYPES: BEGIN OF ty_options, - scales TYPE ty_scales, - responsive TYPE abap_bool, + scales TYPE ty_scales, + responsive TYPE abap_bool, plugins TYPE ty_plugins, hover TYPE ty_hover, interaction TYPE ty_interaction, @@ -551,14 +554,13 @@ CLASS z2ui5_cl_cc_chartjs DEFINITION layout TYPE ty_layout, elements TYPE ty_elements, index_axis TYPE string, - events TYPE string_table, + events TYPE string_table, END OF ty_options . "ChartJS Configuration TYPES: BEGIN OF ty_chart ##NEEDED, type TYPE string, -* plugins TYPE string_table, data TYPE ty_data, options TYPE ty_options, END OF ty_chart. @@ -609,8 +611,41 @@ ENDCLASS. -CLASS Z2UI5_CL_CC_CHARTJS IMPLEMENTATION. +CLASS z2ui5_cl_cc_chartjs IMPLEMENTATION. + METHOD z2ui5_if_ajson_filter~keep_node. + + rv_keep = abap_true. + + + CASE iv_visit. + + WHEN z2ui5_if_ajson_filter=>visit_type-value. + + CASE is_node-type. + WHEN z2ui5_if_ajson_types=>node_type-boolean. + IF is_node-value = `false`. + rv_keep = abap_false. + ENDIF. + WHEN z2ui5_if_ajson_types=>node_type-number. + IF is_node-value = `0`. + rv_keep = abap_false. + ENDIF. + WHEN z2ui5_if_ajson_types=>node_type-string. + IF is_node-value = ``. + rv_keep = abap_false. + ENDIF. + ENDCASE. + + WHEN z2ui5_if_ajson_filter=>visit_type-close. + + IF is_node-children = 0. + rv_keep = abap_false. + ENDIF. + + ENDCASE. + + ENDMETHOD. METHOD get_chartjs_local. result = ``. diff --git a/src/02/z2ui5_cl_fw_http_handler.clas.abap b/src/02/z2ui5_cl_fw_http_handler.clas.abap index 50a4137f..0c30f359 100644 --- a/src/02/z2ui5_cl_fw_http_handler.clas.abap +++ b/src/02/z2ui5_cl_fw_http_handler.clas.abap @@ -6,9 +6,10 @@ CLASS z2ui5_cl_fw_http_handler DEFINITION CLASS-METHODS http_post IMPORTING - body TYPE string + body TYPE string + check_old_json TYPE abap_bool DEFAULT abap_true RETURNING - VALUE(result) TYPE string. + VALUE(result) TYPE string. CLASS-METHODS http_get IMPORTING @@ -44,6 +45,8 @@ CLASS z2ui5_cl_fw_http_handler IMPLEMENTATION. METHOD http_post. + z2ui5_cl_fw_controller=>cv_check_ajson = xsdbool( check_old_json = abap_false ). + result = z2ui5_cl_fw_controller=>main( body ). ENDMETHOD. diff --git a/src/02/z2ui5_if_client.intf.abap b/src/02/z2ui5_if_client.intf.abap index 0962fc31..013cb360 100644 --- a/src/02/z2ui5_if_client.intf.abap +++ b/src/02/z2ui5_if_client.intf.abap @@ -176,15 +176,16 @@ INTERFACE z2ui5_if_client METHODS _bind IMPORTING - val TYPE data - path TYPE abap_bool DEFAULT abap_false - pretty_mode TYPE clike DEFAULT cs_pretty_mode-none - compress_mode TYPE clike DEFAULT cs_compress_mode-standard - tab TYPE STANDARD TABLE OPTIONAL - tab_index TYPE i OPTIONAL - struc TYPE data OPTIONAL + val TYPE data + path TYPE abap_bool DEFAULT abap_false + pretty_mode TYPE clike DEFAULT cs_pretty_mode-none + compress_mode TYPE clike DEFAULT cs_compress_mode-standard + compress_custom TYPE clike OPTIONAL + tab TYPE STANDARD TABLE OPTIONAL + tab_index TYPE i OPTIONAL + struc TYPE data OPTIONAL RETURNING - VALUE(result) TYPE string. + VALUE(result) TYPE string. METHODS _bind_edit IMPORTING @@ -193,6 +194,7 @@ INTERFACE z2ui5_if_client view TYPE string DEFAULT cs_view-main pretty_mode TYPE clike DEFAULT cs_pretty_mode-none compress_mode TYPE clike DEFAULT cs_compress_mode-standard + compress_custom TYPE clike OPTIONAL tab TYPE STANDARD TABLE OPTIONAL tab_index TYPE i OPTIONAL struc TYPE data OPTIONAL @@ -201,10 +203,11 @@ INTERFACE z2ui5_if_client METHODS _bind_local IMPORTING - val TYPE data - path TYPE abap_bool DEFAULT abap_false - pretty_mode TYPE clike DEFAULT cs_pretty_mode-none - compress_mode TYPE clike DEFAULT cs_compress_mode-standard + val TYPE data + path TYPE abap_bool DEFAULT abap_false + pretty_mode TYPE clike DEFAULT cs_pretty_mode-none + compress_custom TYPE clike OPTIONAL + compress_mode TYPE clike DEFAULT cs_compress_mode-standard RETURNING VALUE(result) TYPE string.