mirror of
https://github.com/abap2UI5/abap2UI5.git
synced 2025-04-29 02:58:20 +08:00
added ajson (#833)
* ajson-added * Update abaplint.jsonc * Update abaplint.jsonc * Update abaplint.jsonc * Update abaplint.jsonc
This commit is contained in:
parent
4144455e5f
commit
80b3828e9a
|
@ -20,7 +20,7 @@
|
|||
"select_single_full_key" : true,
|
||||
"strict_sql" : true,
|
||||
"easy_to_find_messages" : true,
|
||||
"fully_type_itabs" : true,
|
||||
"fully_type_itabs" : false,
|
||||
"align_parameters": false,
|
||||
"smim_consistency": true,
|
||||
"allowed_object_naming": true,
|
||||
|
@ -47,7 +47,7 @@
|
|||
"skipNames": []
|
||||
},
|
||||
"check_abstract": true,
|
||||
"check_comments": true,
|
||||
"check_comments": false,
|
||||
"check_ddic": true,
|
||||
"check_include": true,
|
||||
"check_subrc": false,
|
||||
|
@ -117,7 +117,7 @@
|
|||
},
|
||||
"global_class": true,
|
||||
"identical_conditions": true,
|
||||
"identical_contents": true,
|
||||
"identical_contents": false,
|
||||
"identical_descriptions": true,
|
||||
"identical_form_names": true,
|
||||
"if_in_if": true,
|
||||
|
@ -155,7 +155,7 @@
|
|||
"depth": 7
|
||||
},
|
||||
"newline_between_methods": false,
|
||||
"no_aliases": true,
|
||||
"no_aliases": false,
|
||||
"no_chained_assignment": true,
|
||||
"no_external_form_calls": true,
|
||||
"no_inline_in_optional_branches": false,
|
||||
|
@ -197,10 +197,10 @@
|
|||
"pragma_style": true,
|
||||
"prefer_corresponding": true,
|
||||
"prefer_inline": false,
|
||||
"prefer_is_not": true,
|
||||
"prefer_is_not": false,
|
||||
"prefer_raise_exception_new": true,
|
||||
"prefer_returning_to_exporting": false,
|
||||
"prefer_xsdbool": true,
|
||||
"prefer_xsdbool": false,
|
||||
"preferred_compare_operator": true,
|
||||
"prefix_is_current_class": {
|
||||
"severity": "Warning"
|
||||
|
@ -238,11 +238,8 @@
|
|||
"type_form_parameters": true,
|
||||
"types_naming": false,
|
||||
"uncaught_exception": true,
|
||||
"unknown_types": {
|
||||
"exclude": [],
|
||||
"severity": "Error"
|
||||
},
|
||||
"unnecessary_chaining": true,
|
||||
"unknown_types": false,
|
||||
"unnecessary_chaining": false,
|
||||
"unnecessary_pragma": true,
|
||||
"unnecessary_return": true,
|
||||
"unreachable_code": {
|
||||
|
@ -259,8 +256,8 @@
|
|||
},
|
||||
"use_bool_expression": true,
|
||||
"use_class_based_exceptions": true,
|
||||
"use_line_exists": true,
|
||||
"use_new": true,
|
||||
"use_line_exists": false,
|
||||
"use_new": false,
|
||||
"when_others_last": true,
|
||||
"whitespace_end": true,
|
||||
"xml_consistency": true,
|
||||
|
|
964
src/01/00/01/z2ui5_cl_ajson.clas.abap
Normal file
964
src/01/00/01/z2ui5_cl_ajson.clas.abap
Normal file
|
@ -0,0 +1,964 @@
|
|||
class z2ui5_cl_ajson definition
|
||||
public
|
||||
create public .
|
||||
|
||||
public section.
|
||||
|
||||
interfaces z2ui5_if_ajson .
|
||||
|
||||
aliases:
|
||||
is_empty for z2ui5_if_ajson~is_empty,
|
||||
exists for z2ui5_if_ajson~exists,
|
||||
members for z2ui5_if_ajson~members,
|
||||
get for z2ui5_if_ajson~get,
|
||||
get_boolean for z2ui5_if_ajson~get_boolean,
|
||||
get_integer for z2ui5_if_ajson~get_integer,
|
||||
get_number for z2ui5_if_ajson~get_number,
|
||||
get_date for z2ui5_if_ajson~get_date,
|
||||
get_timestamp for z2ui5_if_ajson~get_timestamp,
|
||||
get_string for z2ui5_if_ajson~get_string,
|
||||
slice for z2ui5_if_ajson~slice,
|
||||
to_abap for z2ui5_if_ajson~to_abap,
|
||||
array_to_string_table for z2ui5_if_ajson~array_to_string_table.
|
||||
|
||||
aliases:
|
||||
clear for z2ui5_if_ajson~clear,
|
||||
set for z2ui5_if_ajson~set,
|
||||
setx for z2ui5_if_ajson~setx,
|
||||
set_boolean for z2ui5_if_ajson~set_boolean,
|
||||
set_string for z2ui5_if_ajson~set_string,
|
||||
set_integer for z2ui5_if_ajson~set_integer,
|
||||
set_date for z2ui5_if_ajson~set_date,
|
||||
set_timestamp for z2ui5_if_ajson~set_timestamp,
|
||||
set_null for z2ui5_if_ajson~set_null,
|
||||
delete for z2ui5_if_ajson~delete,
|
||||
touch_array for z2ui5_if_ajson~touch_array,
|
||||
push for z2ui5_if_ajson~push,
|
||||
stringify for z2ui5_if_ajson~stringify.
|
||||
|
||||
aliases:
|
||||
clone for z2ui5_if_ajson~clone,
|
||||
filter for z2ui5_if_ajson~filter,
|
||||
map for z2ui5_if_ajson~map.
|
||||
|
||||
aliases:
|
||||
mt_json_tree for z2ui5_if_ajson~mt_json_tree,
|
||||
keep_item_order for z2ui5_if_ajson~keep_item_order,
|
||||
format_datetime for z2ui5_if_ajson~format_datetime,
|
||||
to_abap_corresponding_only for z2ui5_if_ajson~to_abap_corresponding_only,
|
||||
freeze for z2ui5_if_ajson~freeze.
|
||||
|
||||
class-methods parse
|
||||
importing
|
||||
!iv_json type string
|
||||
!iv_freeze type abap_bool default abap_false
|
||||
!ii_custom_mapping type ref to z2ui5_if_ajson_mapping optional
|
||||
!iv_keep_item_order type abap_bool default abap_false
|
||||
returning
|
||||
value(ro_instance) type ref to z2ui5_cl_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
|
||||
class-methods create_empty " Might be deprecated, prefer using new( ) or create object
|
||||
importing
|
||||
!ii_custom_mapping type ref to z2ui5_if_ajson_mapping optional
|
||||
iv_keep_item_order type abap_bool default abap_false
|
||||
iv_format_datetime type abap_bool default abap_true
|
||||
iv_to_abap_corresponding_only type abap_bool default abap_false
|
||||
returning
|
||||
value(ro_instance) type ref to z2ui5_cl_ajson.
|
||||
|
||||
" Experimental ! May change
|
||||
class-methods create_from " TODO, rename to 'from' ?
|
||||
importing
|
||||
!ii_source_json type ref to z2ui5_if_ajson
|
||||
!ii_filter type ref to z2ui5_if_ajson_filter optional " Might be deprecated, use filter() instead
|
||||
!ii_mapper type ref to z2ui5_if_ajson_mapping optional " Might be deprecated, use map() instead
|
||||
returning
|
||||
value(ro_instance) type ref to z2ui5_cl_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
iv_keep_item_order type abap_bool default abap_false
|
||||
iv_format_datetime type abap_bool default abap_true
|
||||
iv_to_abap_corresponding_only type abap_bool default abap_false.
|
||||
class-methods new
|
||||
importing
|
||||
iv_keep_item_order type abap_bool default abap_false
|
||||
iv_format_datetime type abap_bool default abap_true
|
||||
iv_to_abap_corresponding_only type abap_bool default abap_false
|
||||
returning
|
||||
value(ro_instance) type ref to z2ui5_cl_ajson.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
|
||||
class-data go_float_regex type ref to cl_abap_regex.
|
||||
|
||||
data ms_opts type z2ui5_if_ajson=>ty_opts.
|
||||
data mi_custom_mapping type ref to z2ui5_if_ajson_mapping. " DEPRECATED, will be removed
|
||||
|
||||
methods get_item
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_item) type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
methods prove_path_exists
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rr_end_node) type ref to z2ui5_if_ajson_types=>ty_node
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
methods delete_subtree
|
||||
importing
|
||||
iv_path type string
|
||||
iv_name type string
|
||||
ir_parent type ref to z2ui5_if_ajson_types=>ty_node optional
|
||||
returning
|
||||
value(rs_top_node) type z2ui5_if_ajson_types=>ty_node.
|
||||
methods read_only_watchdog
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
|
||||
CLASS Z2UI5_CL_AJSON IMPLEMENTATION.
|
||||
|
||||
|
||||
method constructor.
|
||||
ms_opts-keep_item_order = iv_keep_item_order.
|
||||
ms_opts-to_abap_corresponding_only = iv_to_abap_corresponding_only.
|
||||
format_datetime( iv_format_datetime ).
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_empty.
|
||||
create object ro_instance
|
||||
exporting
|
||||
iv_to_abap_corresponding_only = iv_to_abap_corresponding_only
|
||||
iv_format_datetime = iv_format_datetime
|
||||
iv_keep_item_order = iv_keep_item_order.
|
||||
ro_instance->mi_custom_mapping = ii_custom_mapping.
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_from.
|
||||
|
||||
data lo_mutator_queue type ref to lcl_mutator_queue.
|
||||
|
||||
if ii_source_json is not bound.
|
||||
z2UI5_cx_ajson_error=>raise( 'Source not bound' ).
|
||||
endif.
|
||||
|
||||
create object ro_instance
|
||||
exporting
|
||||
iv_to_abap_corresponding_only = ii_source_json->opts( )-to_abap_corresponding_only
|
||||
iv_format_datetime = ii_source_json->opts( )-format_datetime
|
||||
iv_keep_item_order = ii_source_json->opts( )-keep_item_order.
|
||||
|
||||
if ii_filter is not bound and ii_mapper is not bound.
|
||||
ro_instance->mt_json_tree = ii_source_json->mt_json_tree.
|
||||
else.
|
||||
create object lo_mutator_queue.
|
||||
if ii_mapper is bound.
|
||||
" Mapping goes first. But maybe it should be a freely definable queue of processors ?
|
||||
lo_mutator_queue->add( lcl_mapper_runner=>new( ii_mapper ) ).
|
||||
endif.
|
||||
if ii_filter is bound.
|
||||
lo_mutator_queue->add( lcl_filter_runner=>new( ii_filter ) ).
|
||||
endif.
|
||||
lo_mutator_queue->lif_mutator_runner~run(
|
||||
exporting
|
||||
it_source_tree = ii_source_json->mt_json_tree
|
||||
importing
|
||||
et_dest_tree = ro_instance->mt_json_tree ).
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method delete_subtree.
|
||||
|
||||
data lv_parent_path type string.
|
||||
data lr_parent like ir_parent.
|
||||
|
||||
read table mt_json_tree into rs_top_node
|
||||
with key
|
||||
path = iv_path
|
||||
name = iv_name.
|
||||
if sy-subrc <> 0.
|
||||
return. " Not found ? nothing to delete !
|
||||
endif.
|
||||
|
||||
delete mt_json_tree index sy-tabix. " where path = iv_path and name = iv_name.
|
||||
|
||||
if rs_top_node-children > 0. " only for objects and arrays
|
||||
lv_parent_path = iv_path && iv_name && '/*'.
|
||||
delete mt_json_tree where path cp lv_parent_path.
|
||||
endif.
|
||||
|
||||
" decrement parent children
|
||||
if ir_parent is supplied.
|
||||
ir_parent->children = ir_parent->children - 1.
|
||||
else.
|
||||
lr_parent = get_item( iv_path ).
|
||||
if lr_parent is not initial.
|
||||
lr_parent->children = lr_parent->children - 1.
|
||||
endif.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method get_item.
|
||||
|
||||
field-symbols <item> like line of mt_json_tree.
|
||||
data ls_path_name type z2ui5_if_ajson_types=>ty_path_name.
|
||||
ls_path_name = lcl_utils=>split_path( iv_path ).
|
||||
|
||||
read table mt_json_tree
|
||||
assigning <item>
|
||||
with key
|
||||
path = ls_path_name-path
|
||||
name = ls_path_name-name.
|
||||
if sy-subrc = 0.
|
||||
get reference of <item> into rv_item.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method new.
|
||||
create object ro_instance
|
||||
exporting
|
||||
iv_to_abap_corresponding_only = iv_to_abap_corresponding_only
|
||||
iv_format_datetime = iv_format_datetime
|
||||
iv_keep_item_order = iv_keep_item_order.
|
||||
endmethod.
|
||||
|
||||
|
||||
method parse.
|
||||
|
||||
data lo_parser type ref to lcl_json_parser.
|
||||
|
||||
create object ro_instance.
|
||||
create object lo_parser.
|
||||
ro_instance->mt_json_tree = lo_parser->parse(
|
||||
iv_json = iv_json
|
||||
iv_keep_item_order = iv_keep_item_order ).
|
||||
ro_instance->mi_custom_mapping = ii_custom_mapping.
|
||||
ro_instance->ms_opts-keep_item_order = iv_keep_item_order.
|
||||
|
||||
if iv_freeze = abap_true.
|
||||
ro_instance->freeze( ).
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method prove_path_exists.
|
||||
|
||||
data lt_path type string_table.
|
||||
data lr_node_parent like rr_end_node.
|
||||
data lv_cur_path type string.
|
||||
data lv_cur_name type string.
|
||||
data ls_new_node like line of mt_json_tree.
|
||||
|
||||
split iv_path at '/' into table lt_path.
|
||||
delete lt_path where table_line is initial.
|
||||
|
||||
do.
|
||||
lr_node_parent = rr_end_node.
|
||||
read table mt_json_tree reference into rr_end_node
|
||||
with key
|
||||
path = lv_cur_path
|
||||
name = lv_cur_name.
|
||||
if sy-subrc <> 0. " New node, assume it is always object as it has a named child, use touch_array to init array
|
||||
clear ls_new_node.
|
||||
if lr_node_parent is not initial. " if has parent
|
||||
lr_node_parent->children = lr_node_parent->children + 1.
|
||||
if lr_node_parent->type = z2ui5_if_ajson_types=>node_type-array.
|
||||
ls_new_node-index = lcl_utils=>validate_array_index(
|
||||
iv_path = lv_cur_path
|
||||
iv_index = lv_cur_name ).
|
||||
endif.
|
||||
endif.
|
||||
ls_new_node-path = lv_cur_path.
|
||||
ls_new_node-name = lv_cur_name.
|
||||
ls_new_node-type = z2ui5_if_ajson_types=>node_type-object.
|
||||
insert ls_new_node into table mt_json_tree reference into rr_end_node.
|
||||
endif.
|
||||
lv_cur_path = lv_cur_path && lv_cur_name && '/'.
|
||||
read table lt_path index sy-index into lv_cur_name.
|
||||
if sy-subrc <> 0.
|
||||
exit. " no more segments
|
||||
endif.
|
||||
enddo.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method read_only_watchdog.
|
||||
if ms_opts-read_only = abap_true.
|
||||
z2UI5_cx_ajson_error=>raise( 'This json instance is read only' ).
|
||||
endif.
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~array_to_string_table.
|
||||
|
||||
data lv_normalized_path type string.
|
||||
data lr_node type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
field-symbols <item> like line of mt_json_tree.
|
||||
|
||||
lv_normalized_path = lcl_utils=>normalize_path( iv_path ).
|
||||
lr_node = get_item( iv_path ).
|
||||
|
||||
if lr_node is initial.
|
||||
z2UI5_cx_ajson_error=>raise( |Path not found: { iv_path }| ).
|
||||
endif.
|
||||
if lr_node->type <> z2ui5_if_ajson_types=>node_type-array.
|
||||
z2UI5_cx_ajson_error=>raise( |Array expected at: { iv_path }| ).
|
||||
endif.
|
||||
|
||||
loop at mt_json_tree assigning <item> where path = lv_normalized_path.
|
||||
case <item>-type.
|
||||
when z2ui5_if_ajson_types=>node_type-number or z2ui5_if_ajson_types=>node_type-string.
|
||||
append <item>-value to rt_string_table.
|
||||
when z2ui5_if_ajson_types=>node_type-null.
|
||||
append '' to rt_string_table.
|
||||
when z2ui5_if_ajson_types=>node_type-boolean.
|
||||
data lv_tmp type string.
|
||||
if <item>-value = 'true'.
|
||||
lv_tmp = abap_true.
|
||||
else.
|
||||
clear lv_tmp.
|
||||
endif.
|
||||
append lv_tmp to rt_string_table.
|
||||
when others.
|
||||
z2UI5_cx_ajson_error=>raise( |Cannot convert [{ <item>-type
|
||||
}] to string at [{ <item>-path }{ <item>-name }]| ).
|
||||
endcase.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~clear.
|
||||
|
||||
read_only_watchdog( ).
|
||||
clear mt_json_tree.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~clone.
|
||||
ri_json = create_from( me ).
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~delete.
|
||||
|
||||
read_only_watchdog( ).
|
||||
|
||||
data ls_split_path type z2ui5_if_ajson_types=>ty_path_name.
|
||||
ls_split_path = lcl_utils=>split_path( iv_path ).
|
||||
|
||||
delete_subtree(
|
||||
iv_path = ls_split_path-path
|
||||
iv_name = ls_split_path-name ).
|
||||
|
||||
ri_json = me.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~exists.
|
||||
rv_exists = boolc( get_item( iv_path ) is not initial ).
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~filter.
|
||||
ri_json = create_from(
|
||||
ii_source_json = me
|
||||
ii_filter = ii_filter ).
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~format_datetime.
|
||||
ms_opts-format_datetime = iv_use_iso.
|
||||
ri_json = me.
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~freeze.
|
||||
ms_opts-read_only = abap_true.
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_item = get_item( iv_path ).
|
||||
if lr_item is not initial.
|
||||
rv_value = lr_item->value.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_boolean.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_item = get_item( iv_path ).
|
||||
if lr_item is initial or lr_item->type = z2ui5_if_ajson_types=>node_type-null.
|
||||
return.
|
||||
elseif lr_item->type = z2ui5_if_ajson_types=>node_type-boolean.
|
||||
rv_value = boolc( lr_item->value = 'true' ).
|
||||
elseif lr_item->value is not initial.
|
||||
rv_value = abap_true.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_date.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
data lv_y type c length 4.
|
||||
data lv_m type c length 2.
|
||||
data lv_d type c length 2.
|
||||
|
||||
lr_item = get_item( iv_path ).
|
||||
|
||||
if lr_item is not initial and lr_item->type = z2ui5_if_ajson_types=>node_type-string.
|
||||
find first occurrence of regex '^(\d{4})-(\d{2})-(\d{2})(T|$)' "#EC NOTEXT
|
||||
in lr_item->value
|
||||
submatches lv_y lv_m lv_d.
|
||||
concatenate lv_y lv_m lv_d into rv_value.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_integer.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_item = get_item( iv_path ).
|
||||
if lr_item is not initial and lr_item->type = z2ui5_if_ajson_types=>node_type-number.
|
||||
rv_value = lr_item->value.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_node_type.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_item = get_item( iv_path ).
|
||||
if lr_item is not initial.
|
||||
rv_node_type = lr_item->type.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_number.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_item = get_item( iv_path ).
|
||||
if lr_item is not initial and lr_item->type = z2ui5_if_ajson_types=>node_type-number.
|
||||
rv_value = lr_item->value.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_string.
|
||||
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_item = get_item( iv_path ).
|
||||
if lr_item is not initial and lr_item->type <> z2ui5_if_ajson_types=>node_type-null.
|
||||
rv_value = lr_item->value.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~get_timestamp.
|
||||
|
||||
data lo_to_abap type ref to lcl_json_to_abap.
|
||||
data lr_item type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
|
||||
lr_item = get_item( iv_path ).
|
||||
|
||||
if lr_item is initial.
|
||||
return.
|
||||
endif.
|
||||
|
||||
create object lo_to_abap.
|
||||
|
||||
try.
|
||||
rv_value = lo_to_abap->to_timestamp( lr_item->value ).
|
||||
catch z2UI5_cx_ajson_error.
|
||||
return.
|
||||
endtry.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~is_empty.
|
||||
rv_yes = boolc( lines( mt_json_tree ) = 0 ).
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~keep_item_order.
|
||||
ms_opts-keep_item_order = abap_true.
|
||||
ri_json = me.
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~map.
|
||||
ri_json = create_from(
|
||||
ii_source_json = me
|
||||
ii_mapper = ii_mapper ).
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~members.
|
||||
|
||||
data lv_normalized_path type string.
|
||||
field-symbols <item> like line of mt_json_tree.
|
||||
|
||||
lv_normalized_path = lcl_utils=>normalize_path( iv_path ).
|
||||
|
||||
loop at mt_json_tree assigning <item> where path = lv_normalized_path.
|
||||
append <item>-name to rt_members.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~opts.
|
||||
rs_opts = ms_opts.
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~push.
|
||||
|
||||
data lr_parent type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
data lr_new_node type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
|
||||
read_only_watchdog( ).
|
||||
|
||||
lr_parent = get_item( iv_path ).
|
||||
|
||||
if lr_parent is initial.
|
||||
z2UI5_cx_ajson_error=>raise( |Path [{ iv_path }] does not exist| ).
|
||||
endif.
|
||||
|
||||
if lr_parent->type <> z2ui5_if_ajson_types=>node_type-array.
|
||||
z2UI5_cx_ajson_error=>raise( |Path [{ iv_path }] is not array| ).
|
||||
endif.
|
||||
|
||||
data lt_new_nodes type z2ui5_if_ajson_types=>ty_nodes_tt.
|
||||
data ls_new_path type z2ui5_if_ajson_types=>ty_path_name.
|
||||
data lv_new_index type i.
|
||||
|
||||
lv_new_index = lr_parent->children + 1.
|
||||
ls_new_path-path = lcl_utils=>normalize_path( iv_path ).
|
||||
ls_new_path-name = |{ lv_new_index }|.
|
||||
|
||||
lt_new_nodes = lcl_abap_to_json=>convert(
|
||||
is_opts = ms_opts
|
||||
iv_data = iv_val
|
||||
is_prefix = ls_new_path ).
|
||||
read table lt_new_nodes index 1 reference into lr_new_node. " assume first record is the array item - not ideal !
|
||||
assert sy-subrc = 0.
|
||||
lr_new_node->index = lv_new_index.
|
||||
|
||||
" update data
|
||||
lr_parent->children = lv_new_index.
|
||||
insert lines of lt_new_nodes into table mt_json_tree.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set.
|
||||
|
||||
data ls_split_path type z2ui5_if_ajson_types=>ty_path_name.
|
||||
data lr_parent type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
data ls_deleted_node type z2ui5_if_ajson_types=>ty_node.
|
||||
data lv_item_order type z2ui5_if_ajson_types=>ty_node-order.
|
||||
|
||||
read_only_watchdog( ).
|
||||
|
||||
ri_json = me.
|
||||
|
||||
if iv_val is initial and iv_ignore_empty = abap_true and iv_node_type is initial.
|
||||
return. " nothing to assign
|
||||
endif.
|
||||
|
||||
if iv_node_type is not initial
|
||||
and iv_node_type <> z2ui5_if_ajson_types=>node_type-boolean and iv_node_type <> z2ui5_if_ajson_types=>node_type-null
|
||||
and iv_node_type <> z2ui5_if_ajson_types=>node_type-number and iv_node_type <> z2ui5_if_ajson_types=>node_type-string.
|
||||
z2UI5_cx_ajson_error=>raise( |Unexpected type { iv_node_type }| ).
|
||||
endif.
|
||||
|
||||
ls_split_path = lcl_utils=>split_path( iv_path ).
|
||||
if ls_split_path is initial. " Assign root, exceptional processing
|
||||
if iv_node_type is not initial.
|
||||
mt_json_tree = lcl_abap_to_json=>insert_with_type(
|
||||
is_opts = ms_opts
|
||||
iv_data = iv_val
|
||||
iv_type = iv_node_type
|
||||
is_prefix = ls_split_path
|
||||
ii_custom_mapping = mi_custom_mapping ).
|
||||
else.
|
||||
mt_json_tree = lcl_abap_to_json=>convert(
|
||||
is_opts = ms_opts
|
||||
iv_data = iv_val
|
||||
is_prefix = ls_split_path
|
||||
ii_custom_mapping = mi_custom_mapping ).
|
||||
endif.
|
||||
return.
|
||||
endif.
|
||||
|
||||
" Ensure whole path exists
|
||||
lr_parent = prove_path_exists( ls_split_path-path ).
|
||||
assert lr_parent is not initial.
|
||||
|
||||
" delete if exists with subtree
|
||||
ls_deleted_node = delete_subtree(
|
||||
ir_parent = lr_parent
|
||||
iv_path = ls_split_path-path
|
||||
iv_name = ls_split_path-name ).
|
||||
lv_item_order = ls_deleted_node-order.
|
||||
|
||||
" convert to json
|
||||
data lt_new_nodes type z2ui5_if_ajson_types=>ty_nodes_tt.
|
||||
data lv_array_index type i.
|
||||
|
||||
if lr_parent->type = z2ui5_if_ajson_types=>node_type-array.
|
||||
lv_array_index = lcl_utils=>validate_array_index(
|
||||
iv_path = ls_split_path-path
|
||||
iv_index = ls_split_path-name ).
|
||||
elseif lr_parent->type = z2ui5_if_ajson_types=>node_type-object
|
||||
and lv_item_order = 0 and ms_opts-keep_item_order = abap_true.
|
||||
lv_item_order = lr_parent->children + 1.
|
||||
endif.
|
||||
|
||||
if iv_node_type is not initial.
|
||||
lt_new_nodes = lcl_abap_to_json=>insert_with_type(
|
||||
is_opts = ms_opts
|
||||
iv_item_order = lv_item_order
|
||||
iv_data = iv_val
|
||||
iv_type = iv_node_type
|
||||
iv_array_index = lv_array_index
|
||||
is_prefix = ls_split_path
|
||||
ii_custom_mapping = mi_custom_mapping ).
|
||||
else.
|
||||
lt_new_nodes = lcl_abap_to_json=>convert(
|
||||
is_opts = ms_opts
|
||||
iv_item_order = lv_item_order
|
||||
iv_data = iv_val
|
||||
iv_array_index = lv_array_index
|
||||
is_prefix = ls_split_path
|
||||
ii_custom_mapping = mi_custom_mapping ).
|
||||
endif.
|
||||
|
||||
" update nodes
|
||||
if lines( lt_new_nodes ) > 0.
|
||||
lr_parent->children = lr_parent->children + 1.
|
||||
insert lines of lt_new_nodes into table mt_json_tree.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~setx.
|
||||
|
||||
data lv_path type string.
|
||||
data lv_val type string.
|
||||
data lv_int type i.
|
||||
data lv_dec type decfloat34.
|
||||
data lv_last type i.
|
||||
|
||||
if iv_param is initial.
|
||||
ri_json = me.
|
||||
return.
|
||||
endif.
|
||||
|
||||
split iv_param at ':' into lv_path lv_val.
|
||||
condense lv_path.
|
||||
condense lv_val.
|
||||
|
||||
if lv_val is initial.
|
||||
ri_json = me.
|
||||
return. " Hmm ? or empty string ? or null ?
|
||||
endif.
|
||||
|
||||
if go_float_regex is not bound.
|
||||
create object go_float_regex exporting pattern = '^([1-9][0-9]*|0)\.[0-9]+$'.
|
||||
" expects fractional, because ints are detected separately
|
||||
endif.
|
||||
|
||||
if lv_val = 'null'.
|
||||
z2ui5_if_ajson~set_null( lv_path ).
|
||||
elseif lv_val = 'true'.
|
||||
z2ui5_if_ajson~set_boolean(
|
||||
iv_path = lv_path
|
||||
iv_val = abap_true ).
|
||||
elseif lv_val = 'false'.
|
||||
z2ui5_if_ajson~set_boolean(
|
||||
iv_path = lv_path
|
||||
iv_val = abap_false ).
|
||||
elseif lv_val co '0123456789'.
|
||||
lv_int = lv_val.
|
||||
z2ui5_if_ajson~set_integer(
|
||||
iv_path = lv_path
|
||||
iv_val = lv_int ).
|
||||
elseif lv_val co '0123456789.' and go_float_regex->create_matcher( text = lv_val )->match( ) = abap_true.
|
||||
lv_dec = lv_val.
|
||||
z2ui5_if_ajson~set(
|
||||
iv_path = lv_path
|
||||
iv_val = lv_dec ).
|
||||
elseif lv_val+0(1) = '{' or lv_val+0(1) = '['.
|
||||
"Expect object/array, but no further checks, parser will catch errors
|
||||
z2ui5_if_ajson~set(
|
||||
iv_path = lv_path
|
||||
iv_val = parse(
|
||||
iv_json = lv_val
|
||||
iv_keep_item_order = ms_opts-keep_item_order ) ).
|
||||
else. " string
|
||||
lv_last = strlen( lv_val ) - 1.
|
||||
if lv_val+0(1) = '"' and lv_val+lv_last(1) = '"'.
|
||||
lv_val = substring(
|
||||
val = lv_val
|
||||
off = 1
|
||||
len = lv_last - 1 ).
|
||||
endif.
|
||||
z2ui5_if_ajson~set_string(
|
||||
iv_path = lv_path
|
||||
iv_val = lv_val ).
|
||||
endif.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set_boolean.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
data lv_bool type abap_bool.
|
||||
lv_bool = boolc( iv_val is not initial ).
|
||||
z2ui5_if_ajson~set(
|
||||
iv_ignore_empty = abap_false
|
||||
iv_path = iv_path
|
||||
iv_val = lv_bool ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set_date.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
data lv_val type string.
|
||||
lv_val = lcl_abap_to_json=>format_date( iv_val ).
|
||||
|
||||
z2ui5_if_ajson~set(
|
||||
iv_ignore_empty = abap_false
|
||||
iv_path = iv_path
|
||||
iv_val = lv_val ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set_integer.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
z2ui5_if_ajson~set(
|
||||
iv_ignore_empty = abap_false
|
||||
iv_path = iv_path
|
||||
iv_val = iv_val ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set_null.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
data lv_null_ref type ref to data.
|
||||
z2ui5_if_ajson~set(
|
||||
iv_ignore_empty = abap_false
|
||||
iv_path = iv_path
|
||||
iv_val = lv_null_ref ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set_string.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
data lv_val type string.
|
||||
lv_val = iv_val.
|
||||
z2ui5_if_ajson~set(
|
||||
iv_ignore_empty = abap_false
|
||||
iv_path = iv_path
|
||||
iv_val = lv_val ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~set_timestamp.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
data lv_timestamp_iso type string.
|
||||
lv_timestamp_iso = lcl_abap_to_json=>format_timestamp( iv_val ).
|
||||
|
||||
z2ui5_if_ajson~set(
|
||||
iv_ignore_empty = abap_false
|
||||
iv_path = iv_path
|
||||
iv_val = lv_timestamp_iso ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~slice.
|
||||
|
||||
data lo_section type ref to z2ui5_cl_ajson.
|
||||
data ls_item like line of mt_json_tree.
|
||||
data lv_normalized_path type string.
|
||||
data ls_path_parts type z2ui5_if_ajson_types=>ty_path_name.
|
||||
data lv_path_len type i.
|
||||
data lv_path_pattern type string.
|
||||
|
||||
create object lo_section.
|
||||
lv_normalized_path = lcl_utils=>normalize_path( iv_path ).
|
||||
lv_path_len = strlen( lv_normalized_path ).
|
||||
ls_path_parts = lcl_utils=>split_path( lv_normalized_path ).
|
||||
|
||||
read table mt_json_tree into ls_item
|
||||
with key path = ls_path_parts-path name = ls_path_parts-name.
|
||||
if sy-subrc <> 0.
|
||||
return.
|
||||
endif.
|
||||
|
||||
clear: ls_item-path, ls_item-name, ls_item-order. " this becomes a new root
|
||||
insert ls_item into table lo_section->mt_json_tree.
|
||||
|
||||
lv_path_pattern = lv_normalized_path && `*`.
|
||||
|
||||
loop at mt_json_tree into ls_item where path cp lv_path_pattern.
|
||||
|
||||
ls_item-path = substring( val = ls_item-path off = lv_path_len - 1 ). " less closing '/'
|
||||
insert ls_item into table lo_section->mt_json_tree.
|
||||
|
||||
endloop.
|
||||
|
||||
ri_json = lo_section.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~stringify.
|
||||
|
||||
rv_json = lcl_json_serializer=>stringify(
|
||||
it_json_tree = mt_json_tree
|
||||
iv_keep_item_order = ms_opts-keep_item_order
|
||||
iv_indent = iv_indent ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~touch_array.
|
||||
|
||||
data lr_node type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
data ls_deleted_node type z2ui5_if_ajson_types=>ty_node.
|
||||
data ls_new_node like line of mt_json_tree.
|
||||
data ls_split_path type z2ui5_if_ajson_types=>ty_path_name.
|
||||
|
||||
read_only_watchdog( ).
|
||||
|
||||
ls_split_path = lcl_utils=>split_path( iv_path ).
|
||||
if ls_split_path is initial. " Assign root, exceptional processing
|
||||
ls_new_node-path = ls_split_path-path.
|
||||
ls_new_node-name = ls_split_path-name.
|
||||
ls_new_node-type = z2ui5_if_ajson_types=>node_type-array.
|
||||
insert ls_new_node into table mt_json_tree.
|
||||
return.
|
||||
endif.
|
||||
|
||||
if iv_clear = abap_true.
|
||||
ls_deleted_node = delete_subtree(
|
||||
iv_path = ls_split_path-path
|
||||
iv_name = ls_split_path-name ).
|
||||
else.
|
||||
lr_node = get_item( iv_path ).
|
||||
endif.
|
||||
|
||||
if lr_node is initial. " Or node was cleared
|
||||
|
||||
data lr_parent type ref to z2ui5_if_ajson_types=>ty_node.
|
||||
lr_parent = prove_path_exists( ls_split_path-path ).
|
||||
assert lr_parent is not initial.
|
||||
|
||||
lr_parent->children = lr_parent->children + 1.
|
||||
|
||||
ls_new_node-path = ls_split_path-path.
|
||||
ls_new_node-name = ls_split_path-name.
|
||||
ls_new_node-type = z2ui5_if_ajson_types=>node_type-array.
|
||||
|
||||
if ms_opts-keep_item_order = abap_true and ls_deleted_node is not initial.
|
||||
ls_new_node-order = ls_deleted_node-order.
|
||||
endif.
|
||||
|
||||
insert ls_new_node into table mt_json_tree.
|
||||
|
||||
elseif lr_node->type <> z2ui5_if_ajson_types=>node_type-array.
|
||||
z2UI5_cx_ajson_error=>raise( |Path [{ iv_path }] already used and is not array| ).
|
||||
endif.
|
||||
|
||||
ri_json = me.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~to_abap.
|
||||
|
||||
data lo_to_abap type ref to lcl_json_to_abap.
|
||||
|
||||
clear ev_container.
|
||||
create object lo_to_abap
|
||||
exporting
|
||||
iv_corresponding = boolc( iv_corresponding = abap_true or ms_opts-to_abap_corresponding_only = abap_true )
|
||||
ii_custom_mapping = mi_custom_mapping.
|
||||
|
||||
lo_to_abap->to_abap(
|
||||
exporting
|
||||
it_nodes = z2ui5_if_ajson~mt_json_tree
|
||||
changing
|
||||
c_container = ev_container ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson~to_abap_corresponding_only.
|
||||
ms_opts-to_abap_corresponding_only = iv_enable.
|
||||
ri_json = me.
|
||||
endmethod.
|
||||
ENDCLASS.
|
2005
src/01/00/01/z2ui5_cl_ajson.clas.locals_imp.abap
Normal file
2005
src/01/00/01/z2ui5_cl_ajson.clas.locals_imp.abap
Normal file
File diff suppressed because it is too large
Load Diff
4773
src/01/00/01/z2ui5_cl_ajson.clas.testclasses.abap
Normal file
4773
src/01/00/01/z2ui5_cl_ajson.clas.testclasses.abap
Normal file
File diff suppressed because it is too large
Load Diff
17
src/01/00/01/z2ui5_cl_ajson.clas.xml
Normal file
17
src/01/00/01/z2ui5_cl_ajson.clas.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOCLASS>
|
||||
<CLSNAME>Z2UI5_CL_AJSON</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON</DESCRIPT>
|
||||
<STATE>1</STATE>
|
||||
<CLSCCINCL>X</CLSCCINCL>
|
||||
<FIXPT>X</FIXPT>
|
||||
<UNICODE>X</UNICODE>
|
||||
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
|
||||
</VSEOCLASS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
58
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.abap
Normal file
58
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.abap
Normal file
|
@ -0,0 +1,58 @@
|
|||
class Z2UI5_CL_AJSON_FILTER_LIB definition
|
||||
public
|
||||
final
|
||||
create public .
|
||||
|
||||
public section.
|
||||
|
||||
class-methods create_empty_filter
|
||||
returning
|
||||
value(ri_filter) type ref to z2ui5_if_ajson_filter
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
class-methods create_path_filter
|
||||
importing
|
||||
!it_skip_paths type string_table optional
|
||||
!iv_skip_paths type string optional
|
||||
!iv_pattern_search type abap_bool default abap_false
|
||||
returning
|
||||
value(ri_filter) type ref to z2ui5_if_ajson_filter
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
class-methods create_and_filter
|
||||
importing
|
||||
!it_filters type z2ui5_if_ajson_filter=>ty_filter_tab
|
||||
returning
|
||||
value(ri_filter) type ref to z2ui5_if_ajson_filter
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
|
||||
protected section.
|
||||
private section.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
|
||||
CLASS Z2UI5_CL_AJSON_FILTER_LIB IMPLEMENTATION.
|
||||
|
||||
|
||||
method create_and_filter.
|
||||
create object ri_filter type lcl_and_filter
|
||||
exporting
|
||||
it_filters = it_filters.
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_empty_filter.
|
||||
create object ri_filter type lcl_empty_filter.
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_path_filter.
|
||||
create object ri_filter type lcl_paths_filter
|
||||
exporting
|
||||
iv_pattern_search = iv_pattern_search
|
||||
it_skip_paths = it_skip_paths
|
||||
iv_skip_paths = iv_skip_paths.
|
||||
endmethod.
|
||||
ENDCLASS.
|
144
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.locals_imp.abap
Normal file
144
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.locals_imp.abap
Normal file
|
@ -0,0 +1,144 @@
|
|||
**********************************************************************
|
||||
* FILTER EMPTY VALUES
|
||||
**********************************************************************
|
||||
|
||||
class lcl_empty_filter definition final.
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_filter.
|
||||
endclass.
|
||||
|
||||
class lcl_empty_filter implementation.
|
||||
method z2ui5_if_ajson_filter~keep_node.
|
||||
|
||||
rv_keep = boolc(
|
||||
( iv_visit = z2ui5_if_ajson_filter=>visit_type-value and is_node-value is not initial ) or
|
||||
( iv_visit <> z2ui5_if_ajson_filter=>visit_type-value and is_node-children > 0 ) ).
|
||||
" children = 0 on open for initially empty nodes and on close for filtered ones
|
||||
|
||||
endmethod.
|
||||
endclass.
|
||||
|
||||
**********************************************************************
|
||||
* FILTER PREDEFINED PATHS
|
||||
**********************************************************************
|
||||
|
||||
class lcl_paths_filter definition final.
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_filter.
|
||||
methods constructor
|
||||
importing
|
||||
it_skip_paths type string_table optional
|
||||
iv_skip_paths type string optional
|
||||
iv_pattern_search type abap_bool
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
private section.
|
||||
data mt_skip_paths type hashed table of string with unique key table_line.
|
||||
data mv_pattern_search type abap_bool.
|
||||
endclass.
|
||||
|
||||
class lcl_paths_filter implementation.
|
||||
|
||||
method z2ui5_if_ajson_filter~keep_node.
|
||||
|
||||
data lv_full_path type string.
|
||||
field-symbols <p> like line of mt_skip_paths.
|
||||
|
||||
lv_full_path = is_node-path && is_node-name.
|
||||
|
||||
if mv_pattern_search = abap_true.
|
||||
rv_keep = abap_true.
|
||||
loop at mt_skip_paths assigning <p>.
|
||||
if lv_full_path cp <p>.
|
||||
rv_keep = abap_false.
|
||||
exit.
|
||||
endif.
|
||||
endloop.
|
||||
else.
|
||||
read table mt_skip_paths with key table_line = lv_full_path transporting no fields.
|
||||
rv_keep = boolc( sy-subrc <> 0 ).
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
method constructor.
|
||||
|
||||
data lv_s type string.
|
||||
data lt_tab type string_table.
|
||||
field-symbols <s> type string.
|
||||
|
||||
if boolc( iv_skip_paths is initial ) = boolc( it_skip_paths is initial ). " XOR
|
||||
z2UI5_cx_ajson_error=>raise( 'no filter path specified' ).
|
||||
endif.
|
||||
|
||||
loop at it_skip_paths into lv_s.
|
||||
lv_s = to_lower( lv_s ).
|
||||
append lv_s to lt_tab.
|
||||
endloop.
|
||||
|
||||
if iv_skip_paths is not initial.
|
||||
split iv_skip_paths at ',' into table lt_tab.
|
||||
loop at lt_tab assigning <s>.
|
||||
if <s> is initial.
|
||||
delete lt_tab index sy-tabix.
|
||||
continue.
|
||||
endif.
|
||||
<s> = condense( to_lower( <s> ) ).
|
||||
endloop.
|
||||
endif.
|
||||
|
||||
sort lt_tab by table_line.
|
||||
delete adjacent duplicates from lt_tab.
|
||||
|
||||
mt_skip_paths = lt_tab.
|
||||
mv_pattern_search = iv_pattern_search.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
**********************************************************************
|
||||
* MULTI FILTER
|
||||
**********************************************************************
|
||||
|
||||
class lcl_and_filter definition final.
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_filter.
|
||||
methods constructor
|
||||
importing
|
||||
it_filters type z2ui5_if_ajson_filter=>ty_filter_tab
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
private section.
|
||||
data mt_filters type z2ui5_if_ajson_filter=>ty_filter_tab.
|
||||
endclass.
|
||||
|
||||
class lcl_and_filter implementation.
|
||||
|
||||
method z2ui5_if_ajson_filter~keep_node.
|
||||
|
||||
data li_filter like line of mt_filters.
|
||||
|
||||
rv_keep = abap_true.
|
||||
loop at mt_filters into li_filter.
|
||||
rv_keep = li_filter->keep_node(
|
||||
is_node = is_node
|
||||
iv_visit = iv_visit ).
|
||||
if rv_keep = abap_false.
|
||||
return.
|
||||
endif.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
method constructor.
|
||||
|
||||
data li_filter like line of it_filters.
|
||||
|
||||
loop at it_filters into li_filter where table_line is bound.
|
||||
append li_filter to mt_filters.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
230
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.testclasses.abap
Normal file
230
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.testclasses.abap
Normal file
|
@ -0,0 +1,230 @@
|
|||
class ltcl_filters_test definition final
|
||||
for testing
|
||||
risk level harmless
|
||||
duration short.
|
||||
private section.
|
||||
methods empty_filter_simple for testing raising z2UI5_cx_ajson_error.
|
||||
methods empty_filter_deep for testing raising z2UI5_cx_ajson_error.
|
||||
methods path_filter for testing raising z2UI5_cx_ajson_error.
|
||||
methods path_filter_string for testing raising z2UI5_cx_ajson_error.
|
||||
methods path_filter_w_patterns for testing raising z2UI5_cx_ajson_error.
|
||||
methods path_filter_deep for testing raising z2UI5_cx_ajson_error.
|
||||
methods and_filter for testing raising z2UI5_cx_ajson_error.
|
||||
endclass.
|
||||
|
||||
|
||||
class ltcl_filters_test implementation.
|
||||
|
||||
method empty_filter_simple.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b'
|
||||
iv_val = '' ).
|
||||
li_json->set(
|
||||
iv_path = '/c'
|
||||
iv_val = '3' ).
|
||||
li_json->set(
|
||||
iv_path = '/d'
|
||||
iv_val = 0 ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_empty_filter( ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1","c":"3"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method empty_filter_deep.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/c'
|
||||
iv_val = '' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/d'
|
||||
iv_val = 0 ).
|
||||
li_json->set(
|
||||
iv_path = '/d/e'
|
||||
iv_val = 0 ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_empty_filter( ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method path_filter.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
data lt_paths type string_table.
|
||||
|
||||
append '/b/c' to lt_paths.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/c'
|
||||
iv_val = '2' ).
|
||||
li_json->set(
|
||||
iv_path = '/c/d'
|
||||
iv_val = '3' ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_path_filter( it_skip_paths = lt_paths ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1","b":{},"c":{"d":"3"}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method path_filter_string.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/c'
|
||||
iv_val = '2' ).
|
||||
li_json->set(
|
||||
iv_path = '/c/d'
|
||||
iv_val = '3' ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_path_filter( iv_skip_paths = '/b/c,/c/d' ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1","b":{},"c":{}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method path_filter_w_patterns.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/@meta'
|
||||
iv_val = 'meta' ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/c'
|
||||
iv_val = '2' ).
|
||||
li_json->set(
|
||||
iv_path = '/c/d'
|
||||
iv_val = '3' ).
|
||||
li_json->set(
|
||||
iv_path = '/c/@meta2'
|
||||
iv_val = 'meta2' ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_path_filter(
|
||||
iv_skip_paths = '/*/c,*/@*'
|
||||
iv_pattern_search = abap_true ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1","b":{},"c":{"d":"3"}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method path_filter_deep.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
data lt_paths type string_table.
|
||||
|
||||
append '/b' to lt_paths.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/c'
|
||||
iv_val = '2' ).
|
||||
li_json->set(
|
||||
iv_path = '/b/d'
|
||||
iv_val = 'x' ).
|
||||
li_json->set(
|
||||
iv_path = '/c/d'
|
||||
iv_val = '3' ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_path_filter( it_skip_paths = lt_paths ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1","c":{"d":"3"}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method and_filter.
|
||||
|
||||
data li_json type ref to z2ui5_if_ajson.
|
||||
data li_json_filtered type ref to z2ui5_if_ajson.
|
||||
data lt_filters type z2ui5_if_ajson_filter=>ty_filter_tab.
|
||||
|
||||
append z2ui5_cl_ajson_filter_lib=>create_empty_filter( ) to lt_filters.
|
||||
append z2ui5_cl_ajson_filter_lib=>create_path_filter( iv_skip_paths = '/c' ) to lt_filters.
|
||||
|
||||
li_json = z2ui5_cl_ajson=>create_empty( ).
|
||||
li_json->set(
|
||||
iv_path = '/a'
|
||||
iv_val = '1' ).
|
||||
li_json->set(
|
||||
iv_path = '/b'
|
||||
iv_val = '' ).
|
||||
li_json->set(
|
||||
iv_path = '/c'
|
||||
iv_val = '3' ).
|
||||
li_json->set(
|
||||
iv_path = '/d'
|
||||
iv_val = 0 ).
|
||||
|
||||
li_json_filtered = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = li_json
|
||||
ii_filter = z2ui5_cl_ajson_filter_lib=>create_and_filter( lt_filters ) ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = li_json_filtered->stringify( )
|
||||
exp = '{"a":"1"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
17
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.xml
Normal file
17
src/01/00/01/z2ui5_cl_ajson_filter_lib.clas.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOCLASS>
|
||||
<CLSNAME>Z2UI5_CL_AJSON_FILTER_LIB</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJson common typical filters</DESCRIPT>
|
||||
<STATE>1</STATE>
|
||||
<CLSCCINCL>X</CLSCCINCL>
|
||||
<FIXPT>X</FIXPT>
|
||||
<UNICODE>X</UNICODE>
|
||||
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
|
||||
</VSEOCLASS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
156
src/01/00/01/z2ui5_cl_ajson_mapping.clas.abap
Normal file
156
src/01/00/01/z2ui5_cl_ajson_mapping.clas.abap
Normal file
|
@ -0,0 +1,156 @@
|
|||
class z2ui5_cl_ajson_mapping definition
|
||||
public
|
||||
final
|
||||
create public.
|
||||
|
||||
public section.
|
||||
|
||||
constants:
|
||||
begin of rename_by,
|
||||
attr_name type i value 0,
|
||||
full_path type i value 1,
|
||||
pattern type i value 2,
|
||||
" regex type i value 3, " TODO add if needed in future
|
||||
end of rename_by.
|
||||
|
||||
class-methods create_camel_case " DEPRECATED
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping=>ty_mapping_fields optional
|
||||
iv_first_json_upper type abap_bool default abap_true
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_upper_case
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping=>ty_mapping_fields optional
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_lower_case
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping=>ty_mapping_fields optional
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_field_mapping " DEPRECATED
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping=>ty_mapping_fields
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_rename
|
||||
importing
|
||||
it_rename_map type z2ui5_if_ajson_mapping=>tty_rename_map
|
||||
iv_rename_by type i default rename_by-attr_name
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_compound_mapper
|
||||
importing
|
||||
ii_mapper1 type ref to z2ui5_if_ajson_mapping optional
|
||||
ii_mapper2 type ref to z2ui5_if_ajson_mapping optional
|
||||
ii_mapper3 type ref to z2ui5_if_ajson_mapping optional
|
||||
it_more type z2ui5_if_ajson_mapping=>ty_table_of optional
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_to_snake_case
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
class-methods create_to_camel_case
|
||||
importing
|
||||
iv_first_json_upper type abap_bool default abap_false
|
||||
returning
|
||||
value(ri_mapping) type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
|
||||
CLASS Z2UI5_CL_AJSON_MAPPING IMPLEMENTATION.
|
||||
|
||||
|
||||
method create_camel_case.
|
||||
|
||||
create object ri_mapping type lcl_mapping_camel
|
||||
exporting
|
||||
it_mapping_fields = it_mapping_fields
|
||||
iv_first_json_upper = iv_first_json_upper.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_compound_mapper.
|
||||
|
||||
data lt_queue type z2ui5_if_ajson_mapping=>ty_table_of.
|
||||
|
||||
append ii_mapper1 to lt_queue.
|
||||
append ii_mapper2 to lt_queue.
|
||||
append ii_mapper3 to lt_queue.
|
||||
append lines of it_more to lt_queue.
|
||||
delete lt_queue where table_line is initial.
|
||||
|
||||
create object ri_mapping type lcl_compound_mapper
|
||||
exporting
|
||||
it_queue = lt_queue.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_field_mapping.
|
||||
|
||||
create object ri_mapping type lcl_mapping_fields
|
||||
exporting
|
||||
it_mapping_fields = it_mapping_fields.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_lower_case.
|
||||
|
||||
create object ri_mapping type lcl_mapping_to_lower
|
||||
exporting
|
||||
it_mapping_fields = it_mapping_fields.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_rename.
|
||||
|
||||
create object ri_mapping type lcl_rename
|
||||
exporting
|
||||
it_rename_map = it_rename_map
|
||||
iv_rename_by = iv_rename_by.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_to_camel_case.
|
||||
|
||||
create object ri_mapping type lcl_to_camel
|
||||
exporting
|
||||
iv_first_json_upper = iv_first_json_upper.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_to_snake_case.
|
||||
|
||||
create object ri_mapping type lcl_to_snake.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method create_upper_case.
|
||||
|
||||
create object ri_mapping type lcl_mapping_to_upper
|
||||
exporting
|
||||
it_mapping_fields = it_mapping_fields.
|
||||
|
||||
endmethod.
|
||||
ENDCLASS.
|
116
src/01/00/01/z2ui5_cl_ajson_mapping.clas.locals_def.abap
Normal file
116
src/01/00/01/z2ui5_cl_ajson_mapping.clas.locals_def.abap
Normal file
|
@ -0,0 +1,116 @@
|
|||
class lcl_mapping_fields definition.
|
||||
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping~ty_mapping_fields optional.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
data mt_mapping_fields type z2ui5_if_ajson_mapping~ty_mapping_fields.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_rename definition.
|
||||
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
it_rename_map type z2ui5_if_ajson_mapping~tty_rename_map
|
||||
iv_rename_by type i.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
data mt_rename_map type z2ui5_if_ajson_mapping~tty_rename_map.
|
||||
data mv_rename_by type i.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_mapping_to_upper definition.
|
||||
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping~ty_mapping_fields optional.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
data mi_mapping_fields type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
class lcl_mapping_to_lower definition.
|
||||
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping~ty_mapping_fields optional.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
data mi_mapping_fields type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
class lcl_mapping_camel definition.
|
||||
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
it_mapping_fields type z2ui5_if_ajson_mapping~ty_mapping_fields optional
|
||||
iv_first_json_upper type abap_bool default abap_true.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
data mv_first_json_upper type abap_bool.
|
||||
data mi_mapping_fields type ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_compound_mapper definition.
|
||||
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
|
||||
methods constructor
|
||||
importing
|
||||
it_queue type z2ui5_if_ajson_mapping=>ty_table_of.
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
data mt_queue type z2ui5_if_ajson_mapping=>ty_table_of.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_to_snake definition.
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
endclass.
|
||||
|
||||
class lcl_to_camel definition.
|
||||
public section.
|
||||
interfaces z2ui5_if_ajson_mapping.
|
||||
methods constructor
|
||||
importing
|
||||
iv_first_json_upper type abap_bool.
|
||||
private section.
|
||||
data mv_first_json_upper type abap_bool.
|
||||
endclass.
|
335
src/01/00/01/z2ui5_cl_ajson_mapping.clas.locals_imp.abap
Normal file
335
src/01/00/01/z2ui5_cl_ajson_mapping.clas.locals_imp.abap
Normal file
|
@ -0,0 +1,335 @@
|
|||
class lcl_mapping_fields implementation. "DEPRECATED
|
||||
|
||||
|
||||
method constructor.
|
||||
|
||||
data ls_mapping_field like line of mt_mapping_fields.
|
||||
|
||||
loop at it_mapping_fields into ls_mapping_field.
|
||||
ls_mapping_field-abap = to_upper( ls_mapping_field-abap ).
|
||||
insert ls_mapping_field into table mt_mapping_fields.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
data ls_mapping_field like line of mt_mapping_fields.
|
||||
|
||||
read table mt_mapping_fields into ls_mapping_field
|
||||
with key json components json = iv_name.
|
||||
if sy-subrc = 0.
|
||||
rv_result = ls_mapping_field-abap.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
data lv_field type string.
|
||||
data ls_mapping_field like line of mt_mapping_fields.
|
||||
|
||||
lv_field = to_upper( iv_name ).
|
||||
|
||||
read table mt_mapping_fields into ls_mapping_field
|
||||
with key abap components abap = lv_field.
|
||||
if sy-subrc = 0.
|
||||
rv_result = ls_mapping_field-json.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_rename implementation.
|
||||
|
||||
method constructor.
|
||||
mt_rename_map = it_rename_map.
|
||||
mv_rename_by = iv_rename_by.
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
data lv_full_path type string.
|
||||
data lv_pair_found type abap_bool.
|
||||
field-symbols <r> like line of mt_rename_map.
|
||||
|
||||
case mv_rename_by.
|
||||
when z2ui5_cl_ajson_mapping=>rename_by-attr_name.
|
||||
read table mt_rename_map assigning <r> with table key by_name components from = cv_name.
|
||||
lv_pair_found = boolc( sy-subrc = 0 ).
|
||||
when z2ui5_cl_ajson_mapping=>rename_by-full_path.
|
||||
lv_full_path = is_node-path && cv_name.
|
||||
read table mt_rename_map assigning <r> with table key by_name components from = lv_full_path.
|
||||
lv_pair_found = boolc( sy-subrc = 0 ).
|
||||
when z2ui5_cl_ajson_mapping=>rename_by-pattern.
|
||||
lv_full_path = is_node-path && cv_name.
|
||||
loop at mt_rename_map assigning <r>.
|
||||
if lv_full_path cp <r>-from.
|
||||
lv_pair_found = abap_true.
|
||||
exit.
|
||||
endif.
|
||||
endloop.
|
||||
when others.
|
||||
lv_pair_found = abap_false. " No rename
|
||||
endcase.
|
||||
|
||||
if lv_pair_found = abap_true.
|
||||
cv_name = <r>-to.
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_mapping_to_upper implementation.
|
||||
|
||||
|
||||
method constructor.
|
||||
|
||||
mi_mapping_fields = z2ui5_cl_ajson_mapping=>create_field_mapping( it_mapping_fields ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
rv_result = mi_mapping_fields->to_abap( iv_path = iv_path iv_name = iv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
rv_result = mi_mapping_fields->to_json( iv_path = iv_path iv_name = iv_name ).
|
||||
|
||||
if rv_result is not initial. " Mapping found
|
||||
return.
|
||||
endif.
|
||||
|
||||
rv_result = to_upper( iv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
cv_name = to_upper( cv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
class lcl_mapping_to_lower implementation.
|
||||
|
||||
|
||||
method constructor.
|
||||
|
||||
mi_mapping_fields = z2ui5_cl_ajson_mapping=>create_field_mapping( it_mapping_fields ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
rv_result = mi_mapping_fields->to_abap( iv_path = iv_path iv_name = iv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
rv_result = mi_mapping_fields->to_json( iv_path = iv_path iv_name = iv_name ).
|
||||
|
||||
if rv_result is not initial. " Mapping found
|
||||
return.
|
||||
endif.
|
||||
|
||||
rv_result = to_lower( iv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
cv_name = to_lower( cv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
class lcl_mapping_camel implementation. "DEPRECATED
|
||||
|
||||
|
||||
method constructor.
|
||||
|
||||
mi_mapping_fields = z2ui5_cl_ajson_mapping=>create_field_mapping( it_mapping_fields ).
|
||||
mv_first_json_upper = iv_first_json_upper.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
rv_result = mi_mapping_fields->to_abap( iv_path = iv_path iv_name = iv_name ).
|
||||
|
||||
if rv_result is not initial. " Mapping found
|
||||
return.
|
||||
endif.
|
||||
|
||||
rv_result = iv_name.
|
||||
|
||||
replace all occurrences of regex `([a-z])([A-Z])` in rv_result with `$1_$2`. "#EC NOTEXT
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
types ty_token type c length 255.
|
||||
data lt_tokens type standard table of ty_token.
|
||||
data lv_from type i.
|
||||
field-symbols <token> like line of lt_tokens.
|
||||
|
||||
rv_result = mi_mapping_fields->to_json( iv_path = iv_path iv_name = iv_name ).
|
||||
|
||||
if rv_result is not initial. " Mapping found
|
||||
return.
|
||||
endif.
|
||||
|
||||
rv_result = iv_name.
|
||||
|
||||
replace all occurrences of `__` in rv_result with `*`.
|
||||
|
||||
translate rv_result to lower case.
|
||||
translate rv_result using `/_:_~_`.
|
||||
|
||||
if mv_first_json_upper = abap_true.
|
||||
lv_from = 1.
|
||||
else.
|
||||
lv_from = 2.
|
||||
endif.
|
||||
|
||||
split rv_result at `_` into table lt_tokens.
|
||||
loop at lt_tokens assigning <token> from lv_from.
|
||||
translate <token>(1) to upper case.
|
||||
endloop.
|
||||
|
||||
concatenate lines of lt_tokens into rv_result.
|
||||
replace all occurrences of `*` in rv_result with `_`.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_compound_mapper implementation.
|
||||
|
||||
method constructor.
|
||||
mt_queue = it_queue.
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
data ls_node like is_node.
|
||||
data li_mapper like line of mt_queue.
|
||||
|
||||
ls_node = is_node.
|
||||
|
||||
loop at mt_queue into li_mapper.
|
||||
li_mapper->rename_node(
|
||||
exporting
|
||||
is_node = ls_node
|
||||
changing
|
||||
cv_name = cv_name ).
|
||||
ls_node-name = cv_name.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_to_snake implementation.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
replace all occurrences of regex `([a-z])([A-Z])` in cv_name with `$1_$2`. "#EC NOTEXT
|
||||
cv_name = to_lower( cv_name ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_to_camel implementation.
|
||||
|
||||
method constructor.
|
||||
mv_first_json_upper = iv_first_json_upper.
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~rename_node.
|
||||
|
||||
types lty_token type c length 255.
|
||||
constants lc_forced_underscore_marker type c length 1 value cl_abap_char_utilities=>horizontal_tab.
|
||||
|
||||
data lt_tokens type standard table of lty_token.
|
||||
data lv_from type i.
|
||||
field-symbols <token> like line of lt_tokens.
|
||||
|
||||
if mv_first_json_upper = abap_true.
|
||||
lv_from = 1.
|
||||
else.
|
||||
lv_from = 2.
|
||||
endif.
|
||||
replace all occurrences of `__` in cv_name with lc_forced_underscore_marker. " Force underscore
|
||||
|
||||
split cv_name at `_` into table lt_tokens.
|
||||
delete lt_tokens where table_line is initial.
|
||||
loop at lt_tokens assigning <token> from lv_from.
|
||||
translate <token>+0(1) to upper case.
|
||||
endloop.
|
||||
|
||||
concatenate lines of lt_tokens into cv_name.
|
||||
replace all occurrences of lc_forced_underscore_marker in cv_name with `_`.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_abap.
|
||||
|
||||
endmethod.
|
||||
|
||||
method z2ui5_if_ajson_mapping~to_json.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
535
src/01/00/01/z2ui5_cl_ajson_mapping.clas.testclasses.abap
Normal file
535
src/01/00/01/z2ui5_cl_ajson_mapping.clas.testclasses.abap
Normal file
|
@ -0,0 +1,535 @@
|
|||
class ltcl_test_mappers definition final for testing
|
||||
duration short
|
||||
risk level harmless.
|
||||
|
||||
private section.
|
||||
methods:
|
||||
from_json_to_json for testing raising z2UI5_cx_ajson_error,
|
||||
to_abap for testing raising z2UI5_cx_ajson_error,
|
||||
to_json for testing raising z2UI5_cx_ajson_error,
|
||||
to_json_nested_struc for testing raising z2UI5_cx_ajson_error,
|
||||
to_json_nested_table for testing raising z2UI5_cx_ajson_error,
|
||||
to_json_first_lower for testing raising z2UI5_cx_ajson_error.
|
||||
|
||||
methods:
|
||||
to_snake for testing raising z2UI5_cx_ajson_error,
|
||||
to_camel for testing raising z2UI5_cx_ajson_error,
|
||||
to_camel_1st_upper for testing raising z2UI5_cx_ajson_error,
|
||||
rename_by_attr for testing raising z2UI5_cx_ajson_error,
|
||||
rename_by_path for testing raising z2UI5_cx_ajson_error,
|
||||
rename_by_pattern for testing raising z2UI5_cx_ajson_error,
|
||||
compound_mapper for testing raising z2UI5_cx_ajson_error,
|
||||
test_to_upper for testing raising z2UI5_cx_ajson_error,
|
||||
test_to_lower for testing raising z2UI5_cx_ajson_error.
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
class ltcl_test_mappers implementation.
|
||||
|
||||
|
||||
method from_json_to_json.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson.
|
||||
|
||||
lo_ajson =
|
||||
z2ui5_cl_ajson=>parse(
|
||||
iv_json = `{"fieldData":"field_value"}`
|
||||
ii_custom_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ) ).
|
||||
|
||||
lo_ajson->set_string( iv_path = `/fieldData` iv_val = 'E' ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"fieldData":"E"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_abap.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( ).
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>parse( iv_json = '{"FieldData":"field_value"}' ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->to_abap( importing ev_container = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = ls_result-field_data
|
||||
exp = 'field_value' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ).
|
||||
|
||||
ls_result-field_data = 'field_value'.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = '/' iv_val = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"fieldData":"field_value"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json_nested_struc.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
begin of struc_data,
|
||||
field_more type string,
|
||||
end of struc_data,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ).
|
||||
|
||||
ls_result-field_data = 'field_value'.
|
||||
ls_result-struc_data-field_more = 'field_more'.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = '/' iv_val = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"fieldData":"field_value","strucData":{"fieldMore":"field_more"}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json_nested_table.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
lv_value type string,
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
begin of struc_data,
|
||||
field_more type string_table,
|
||||
end of struc_data,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ).
|
||||
|
||||
ls_result-field_data = 'field_value'.
|
||||
lv_value = 'field_more'.
|
||||
insert lv_value into table ls_result-struc_data-field_more.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = '/'
|
||||
iv_val = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"fieldData":"field_value","strucData":{"fieldMore":["field_more"]}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json_first_lower.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_camel_case( ).
|
||||
|
||||
ls_result-field_data = 'field_value'.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = '/' iv_val = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"FieldData":"field_value"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method test_to_upper.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"a":1,"b":{"c":2}}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_upper_case( ) )->stringify( )
|
||||
exp = '{"A":1,"B":{"C":2}}' ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>parse( '{"a":1,"b":{"c":2}}'
|
||||
)->map( z2ui5_cl_ajson_mapping=>create_upper_case( )
|
||||
)->stringify( )
|
||||
exp = '{"A":1,"B":{"C":2}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method test_to_lower.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"A":1,"B":{"C":2}}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_lower_case( ) )->stringify( )
|
||||
exp = '{"a":1,"b":{"c":2}}' ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>parse( '{"A":1,"B":{"C":2}}'
|
||||
)->map( z2ui5_cl_ajson_mapping=>create_lower_case( )
|
||||
)->stringify( )
|
||||
exp = '{"a":1,"b":{"c":2}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method rename_by_attr.
|
||||
|
||||
data lt_map type z2ui5_if_ajson_mapping=>tty_rename_map.
|
||||
field-symbols <i> like line of lt_map.
|
||||
|
||||
append initial line to lt_map assigning <i>.
|
||||
<i>-from = 'a'.
|
||||
<i>-to = 'x'.
|
||||
append initial line to lt_map assigning <i>.
|
||||
<i>-from = 'c'.
|
||||
<i>-to = 'y'.
|
||||
append initial line to lt_map assigning <i>.
|
||||
<i>-from = 'd'.
|
||||
<i>-to = 'z'.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"a":1,"b":{"c":2},"d":{"e":3}}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_rename( lt_map
|
||||
) )->stringify( )
|
||||
exp = '{"b":{"y":2},"x":1,"z":{"e":3}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method rename_by_path.
|
||||
|
||||
data lt_map type z2ui5_if_ajson_mapping=>tty_rename_map.
|
||||
field-symbols <i> like line of lt_map.
|
||||
|
||||
append initial line to lt_map assigning <i>.
|
||||
<i>-from = '/b/a'.
|
||||
<i>-to = 'x'.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"a":1,"b":{"a":2},"c":{"a":3}}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_rename(
|
||||
it_rename_map = lt_map
|
||||
iv_rename_by = z2ui5_cl_ajson_mapping=>rename_by-full_path
|
||||
) )->stringify( )
|
||||
exp = '{"a":1,"b":{"x":2},"c":{"a":3}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method rename_by_pattern.
|
||||
|
||||
data lt_map type z2ui5_if_ajson_mapping=>tty_rename_map.
|
||||
field-symbols <i> like line of lt_map.
|
||||
|
||||
append initial line to lt_map assigning <i>.
|
||||
<i>-from = '/*/this*'.
|
||||
<i>-to = 'x'.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"andthisnot":1,"b":{"thisone":2},"c":{"a":3}}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_rename(
|
||||
it_rename_map = lt_map
|
||||
iv_rename_by = z2ui5_cl_ajson_mapping=>rename_by-pattern
|
||||
) )->stringify( )
|
||||
exp = '{"andthisnot":1,"b":{"x":2},"c":{"a":3}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method compound_mapper.
|
||||
|
||||
data lt_map type z2ui5_if_ajson_mapping=>tty_rename_map.
|
||||
field-symbols <i> like line of lt_map.
|
||||
|
||||
append initial line to lt_map assigning <i>.
|
||||
<i>-from = '/b/a'.
|
||||
<i>-to = 'x'.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"a":1,"b":{"a":2},"c":{"a":3}}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_compound_mapper(
|
||||
ii_mapper1 = z2ui5_cl_ajson_mapping=>create_rename(
|
||||
it_rename_map = lt_map
|
||||
iv_rename_by = z2ui5_cl_ajson_mapping=>rename_by-full_path )
|
||||
ii_mapper2 = z2ui5_cl_ajson_mapping=>create_upper_case( ) )
|
||||
)->stringify( )
|
||||
exp = '{"A":1,"B":{"X":2},"C":{"A":3}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method to_snake.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"aB":1,"BbC":2,"cD":{"xY":3},"ZZ":4}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_to_snake_case( )
|
||||
)->stringify( )
|
||||
exp = '{"a_b":1,"bb_c":2,"c_d":{"x_y":3},"zz":4}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method to_camel.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"a_b":1,"bb_c":2,"c_d":{"x_y":3},"zz":4}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_to_camel_case( )
|
||||
)->stringify( )
|
||||
exp = '{"aB":1,"bbC":2,"cD":{"xY":3},"zz":4}' ).
|
||||
|
||||
" Forced underscore
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"a__b":1}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_to_camel_case( )
|
||||
)->stringify( )
|
||||
exp = '{"a_b":1}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method to_camel_1st_upper.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson=>create_from(
|
||||
ii_source_json = z2ui5_cl_ajson=>parse( '{"aj_bc":1,"bb_c":2,"c_d":{"xq_yq":3},"zz":4}' )
|
||||
ii_mapper = z2ui5_cl_ajson_mapping=>create_to_camel_case( iv_first_json_upper = abap_true )
|
||||
)->stringify( )
|
||||
exp = '{"AjBc":1,"BbC":2,"CD":{"XqYq":3},"Zz":4}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
|
||||
class ltcl_fields definition final for testing
|
||||
duration short
|
||||
risk level harmless.
|
||||
|
||||
private section.
|
||||
methods:
|
||||
to_json_without_path for testing raising z2UI5_cx_ajson_error,
|
||||
to_json_with_path for testing raising z2UI5_cx_ajson_error,
|
||||
to_abap for testing raising z2UI5_cx_ajson_error,
|
||||
to_json importing iv_path type string returning value(rv_result) type string raising z2UI5_cx_ajson_error.
|
||||
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
class ltcl_fields implementation.
|
||||
|
||||
|
||||
method to_abap.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping,
|
||||
lt_mapping_fields type z2ui5_if_ajson_mapping=>ty_mapping_fields,
|
||||
ls_mapping_field like line of lt_mapping_fields.
|
||||
data:
|
||||
begin of ls_result,
|
||||
abap_field type string,
|
||||
field type string,
|
||||
end of ls_result.
|
||||
|
||||
clear ls_mapping_field.
|
||||
ls_mapping_field-abap = 'ABAP_FIELD'.
|
||||
ls_mapping_field-json = 'json.field'.
|
||||
insert ls_mapping_field into table lt_mapping_fields.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_field_mapping( lt_mapping_fields ).
|
||||
|
||||
lo_ajson =
|
||||
z2ui5_cl_ajson=>parse( iv_json = '{"field":"value","json.field":"field_value"}' ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->to_abap( importing ev_container = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = ls_result-abap_field
|
||||
exp = 'field_value' ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = ls_result-field
|
||||
exp = 'value' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json_without_path.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = to_json( `/` )
|
||||
exp = '{"field":"value","json.field":"field_value"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json_with_path.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = to_json( '/samplePath' )
|
||||
exp = '{"samplePath":{"field":"value","json.field":"field_value"}}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method to_json.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping,
|
||||
lt_mapping_fields type z2ui5_if_ajson_mapping=>ty_mapping_fields,
|
||||
ls_mapping_field like line of lt_mapping_fields.
|
||||
data:
|
||||
begin of ls_result,
|
||||
abap_field type string,
|
||||
field type string,
|
||||
end of ls_result.
|
||||
|
||||
clear ls_mapping_field.
|
||||
ls_mapping_field-abap = 'ABAP_FIELD'.
|
||||
ls_mapping_field-json = 'json.field'.
|
||||
insert ls_mapping_field into table lt_mapping_fields.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_field_mapping( lt_mapping_fields ).
|
||||
|
||||
ls_result-abap_field = 'field_value'.
|
||||
ls_result-field = 'value'.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = iv_path iv_val = ls_result ).
|
||||
|
||||
rv_result = lo_ajson->stringify( ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
|
||||
class ltcl_to_lower definition final for testing
|
||||
duration short
|
||||
risk level harmless.
|
||||
|
||||
private section.
|
||||
methods:
|
||||
to_json for testing raising z2UI5_cx_ajson_error.
|
||||
endclass.
|
||||
|
||||
|
||||
class ltcl_to_lower implementation.
|
||||
|
||||
|
||||
method to_json.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_lower_case( ).
|
||||
|
||||
ls_result-field_data = 'field_value'.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = '/' iv_val = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"field_data":"field_value"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
endclass.
|
||||
|
||||
|
||||
|
||||
class ltcl_to_upper definition final for testing
|
||||
duration short
|
||||
risk level harmless.
|
||||
|
||||
private section.
|
||||
methods:
|
||||
to_json for testing raising z2UI5_cx_ajson_error.
|
||||
endclass.
|
||||
|
||||
|
||||
class ltcl_to_upper implementation.
|
||||
|
||||
|
||||
method to_json.
|
||||
|
||||
data:
|
||||
lo_ajson type ref to z2ui5_cl_ajson,
|
||||
li_mapping type ref to z2ui5_if_ajson_mapping.
|
||||
data:
|
||||
begin of ls_result,
|
||||
field_data type string,
|
||||
end of ls_result.
|
||||
|
||||
li_mapping = z2ui5_cl_ajson_mapping=>create_upper_case( ).
|
||||
|
||||
ls_result-field_data = 'field_value'.
|
||||
|
||||
lo_ajson = z2ui5_cl_ajson=>create_empty( ii_custom_mapping = li_mapping ).
|
||||
|
||||
lo_ajson->set( iv_path = '/' iv_val = ls_result ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_ajson->stringify( )
|
||||
exp = '{"FIELD_DATA":"field_value"}' ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
endclass.
|
17
src/01/00/01/z2ui5_cl_ajson_mapping.clas.xml
Normal file
17
src/01/00/01/z2ui5_cl_ajson_mapping.clas.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOCLASS>
|
||||
<CLSNAME>Z2UI5_CL_AJSON_MAPPING</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON Mapping</DESCRIPT>
|
||||
<STATE>1</STATE>
|
||||
<CLSCCINCL>X</CLSCCINCL>
|
||||
<FIXPT>X</FIXPT>
|
||||
<UNICODE>X</UNICODE>
|
||||
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
|
||||
</VSEOCLASS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
378
src/01/00/01/z2ui5_cl_ajson_utilities.clas.abap
Normal file
378
src/01/00/01/z2ui5_cl_ajson_utilities.clas.abap
Normal file
|
@ -0,0 +1,378 @@
|
|||
class z2ui5_cl_ajson_utilities definition
|
||||
public
|
||||
create public .
|
||||
|
||||
public section.
|
||||
|
||||
class-methods new
|
||||
returning
|
||||
value(ro_instance) type ref to z2ui5_cl_ajson_utilities.
|
||||
methods diff
|
||||
importing
|
||||
!iv_json_a type string optional
|
||||
!iv_json_b type string optional
|
||||
!io_json_a type ref to z2ui5_if_ajson optional
|
||||
!io_json_b type ref to z2ui5_if_ajson optional
|
||||
!iv_keep_empty_arrays type abap_bool default abap_false
|
||||
exporting
|
||||
!eo_insert type ref to z2ui5_if_ajson
|
||||
!eo_delete type ref to z2ui5_if_ajson
|
||||
!eo_change type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
methods merge
|
||||
importing
|
||||
!iv_json_a type string optional
|
||||
!iv_json_b type string optional
|
||||
!io_json_a type ref to z2ui5_if_ajson optional
|
||||
!io_json_b type ref to z2ui5_if_ajson optional
|
||||
!iv_keep_empty_arrays type abap_bool default abap_false
|
||||
returning
|
||||
value(ro_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
methods sort
|
||||
importing
|
||||
!iv_json type string optional
|
||||
!io_json type ref to z2ui5_if_ajson optional
|
||||
returning
|
||||
value(rv_sorted) type string
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
methods is_equal
|
||||
importing
|
||||
!iv_json_a type string optional
|
||||
!iv_json_b type string optional
|
||||
!ii_json_a type ref to z2ui5_if_ajson optional
|
||||
!ii_json_b type ref to z2ui5_if_ajson optional
|
||||
returning
|
||||
value(rv_yes) type abap_bool
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
|
||||
protected section.
|
||||
|
||||
private section.
|
||||
|
||||
data mo_json_a type ref to z2ui5_if_ajson .
|
||||
data mo_json_b type ref to z2ui5_if_ajson .
|
||||
data mo_insert type ref to z2ui5_if_ajson .
|
||||
data mo_delete type ref to z2ui5_if_ajson .
|
||||
data mo_change type ref to z2ui5_if_ajson .
|
||||
|
||||
methods normalize_input
|
||||
importing
|
||||
!iv_json type string optional
|
||||
!io_json type ref to z2ui5_if_ajson optional
|
||||
returning
|
||||
value(ro_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
methods diff_a_b
|
||||
importing
|
||||
!iv_path type string
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
methods diff_b_a
|
||||
importing
|
||||
!iv_path type string
|
||||
!iv_array type abap_bool default abap_false
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
methods delete_empty_nodes
|
||||
importing
|
||||
!io_json type ref to z2ui5_if_ajson
|
||||
!iv_keep_empty_arrays type abap_bool
|
||||
raising
|
||||
z2UI5_cx_ajson_error .
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
|
||||
CLASS Z2UI5_CL_AJSON_UTILITIES IMPLEMENTATION.
|
||||
|
||||
|
||||
method delete_empty_nodes.
|
||||
|
||||
data ls_json_tree like line of io_json->mt_json_tree.
|
||||
data lv_done type abap_bool.
|
||||
|
||||
do.
|
||||
lv_done = abap_true.
|
||||
|
||||
if iv_keep_empty_arrays = abap_false.
|
||||
loop at io_json->mt_json_tree into ls_json_tree
|
||||
where type = z2ui5_if_ajson_types=>node_type-array and children = 0.
|
||||
|
||||
io_json->delete( ls_json_tree-path && ls_json_tree-name ).
|
||||
|
||||
endloop.
|
||||
if sy-subrc = 0.
|
||||
lv_done = abap_false.
|
||||
endif.
|
||||
endif.
|
||||
|
||||
loop at io_json->mt_json_tree into ls_json_tree
|
||||
where type = z2ui5_if_ajson_types=>node_type-object and children = 0.
|
||||
|
||||
io_json->delete( ls_json_tree-path && ls_json_tree-name ).
|
||||
|
||||
endloop.
|
||||
if sy-subrc = 0.
|
||||
lv_done = abap_false.
|
||||
endif.
|
||||
|
||||
if lv_done = abap_true.
|
||||
exit. " nothing else to delete
|
||||
endif.
|
||||
enddo.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method diff.
|
||||
|
||||
mo_json_a = normalize_input(
|
||||
iv_json = iv_json_a
|
||||
io_json = io_json_a ).
|
||||
|
||||
mo_json_b = normalize_input(
|
||||
iv_json = iv_json_b
|
||||
io_json = io_json_b ).
|
||||
|
||||
mo_insert = z2ui5_cl_ajson=>create_empty( ).
|
||||
mo_delete = z2ui5_cl_ajson=>create_empty( ).
|
||||
mo_change = z2ui5_cl_ajson=>create_empty( ).
|
||||
|
||||
diff_a_b( '/' ).
|
||||
diff_b_a( '/' ).
|
||||
|
||||
eo_insert ?= mo_insert.
|
||||
eo_delete ?= mo_delete.
|
||||
eo_change ?= mo_change.
|
||||
|
||||
delete_empty_nodes(
|
||||
io_json = eo_insert
|
||||
iv_keep_empty_arrays = iv_keep_empty_arrays ).
|
||||
delete_empty_nodes(
|
||||
io_json = eo_delete
|
||||
iv_keep_empty_arrays = iv_keep_empty_arrays ).
|
||||
delete_empty_nodes(
|
||||
io_json = eo_change
|
||||
iv_keep_empty_arrays = iv_keep_empty_arrays ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method diff_a_b.
|
||||
|
||||
data:
|
||||
lv_path_a type string,
|
||||
lv_path_b type string.
|
||||
|
||||
field-symbols:
|
||||
<node_a> like line of mo_json_a->mt_json_tree,
|
||||
<node_b> like line of mo_json_a->mt_json_tree.
|
||||
|
||||
loop at mo_json_a->mt_json_tree assigning <node_a> where path = iv_path.
|
||||
lv_path_a = <node_a>-path && <node_a>-name && '/'.
|
||||
|
||||
read table mo_json_b->mt_json_tree assigning <node_b>
|
||||
with table key path = <node_a>-path name = <node_a>-name.
|
||||
if sy-subrc = 0.
|
||||
lv_path_b = <node_b>-path && <node_b>-name && '/'.
|
||||
|
||||
if <node_a>-type = <node_b>-type.
|
||||
case <node_a>-type.
|
||||
when z2ui5_if_ajson_types=>node_type-array.
|
||||
mo_insert->touch_array( lv_path_a ).
|
||||
mo_change->touch_array( lv_path_a ).
|
||||
mo_delete->touch_array( lv_path_a ).
|
||||
diff_a_b( lv_path_a ).
|
||||
when z2ui5_if_ajson_types=>node_type-object.
|
||||
diff_a_b( lv_path_a ).
|
||||
when others.
|
||||
if <node_a>-value <> <node_b>-value.
|
||||
" save as changed value
|
||||
mo_change->set(
|
||||
iv_path = lv_path_b
|
||||
iv_val = <node_b>-value
|
||||
iv_node_type = <node_b>-type ).
|
||||
endif.
|
||||
endcase.
|
||||
else.
|
||||
" save changed type as delete + insert
|
||||
case <node_a>-type.
|
||||
when z2ui5_if_ajson_types=>node_type-array.
|
||||
mo_delete->touch_array( lv_path_a ).
|
||||
diff_a_b( lv_path_a ).
|
||||
when z2ui5_if_ajson_types=>node_type-object.
|
||||
diff_a_b( lv_path_a ).
|
||||
when others.
|
||||
mo_delete->set(
|
||||
iv_path = lv_path_a
|
||||
iv_val = <node_a>-value
|
||||
iv_node_type = <node_a>-type ).
|
||||
endcase.
|
||||
case <node_b>-type.
|
||||
when z2ui5_if_ajson_types=>node_type-array.
|
||||
mo_insert->touch_array( lv_path_b ).
|
||||
diff_b_a( lv_path_b ).
|
||||
when z2ui5_if_ajson_types=>node_type-object.
|
||||
diff_b_a( lv_path_b ).
|
||||
when others.
|
||||
mo_insert->set(
|
||||
iv_path = lv_path_b
|
||||
iv_val = <node_b>-value
|
||||
iv_node_type = <node_b>-type ).
|
||||
endcase.
|
||||
endif.
|
||||
else.
|
||||
" save as delete
|
||||
case <node_a>-type.
|
||||
when z2ui5_if_ajson_types=>node_type-array.
|
||||
mo_delete->touch_array( lv_path_a ).
|
||||
diff_a_b( lv_path_a ).
|
||||
when z2ui5_if_ajson_types=>node_type-object.
|
||||
diff_a_b( lv_path_a ).
|
||||
when others.
|
||||
mo_delete->set(
|
||||
iv_path = lv_path_a
|
||||
iv_val = <node_a>-value
|
||||
iv_node_type = <node_a>-type ).
|
||||
endcase.
|
||||
endif.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method diff_b_a.
|
||||
|
||||
data lv_path type string.
|
||||
|
||||
field-symbols <node_b> like line of mo_json_b->mt_json_tree.
|
||||
|
||||
loop at mo_json_b->mt_json_tree assigning <node_b> where path = iv_path.
|
||||
lv_path = <node_b>-path && <node_b>-name && '/'.
|
||||
|
||||
case <node_b>-type.
|
||||
when z2ui5_if_ajson_types=>node_type-array.
|
||||
mo_insert->touch_array( lv_path ).
|
||||
diff_b_a(
|
||||
iv_path = lv_path
|
||||
iv_array = abap_true ).
|
||||
when z2ui5_if_ajson_types=>node_type-object.
|
||||
diff_b_a( lv_path ).
|
||||
when others.
|
||||
if iv_array = abap_false.
|
||||
read table mo_json_a->mt_json_tree transporting no fields
|
||||
with table key path = <node_b>-path name = <node_b>-name.
|
||||
if sy-subrc <> 0.
|
||||
" save as insert
|
||||
mo_insert->set(
|
||||
iv_path = lv_path
|
||||
iv_val = <node_b>-value
|
||||
iv_node_type = <node_b>-type ).
|
||||
endif.
|
||||
else.
|
||||
read table mo_insert->mt_json_tree transporting no fields
|
||||
with key path = <node_b>-path value = <node_b>-value.
|
||||
if sy-subrc <> 0.
|
||||
" save as new array value
|
||||
mo_insert->push(
|
||||
iv_path = iv_path
|
||||
iv_val = <node_b>-value ).
|
||||
endif.
|
||||
endif.
|
||||
endcase.
|
||||
endloop.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method is_equal.
|
||||
|
||||
data li_ins type ref to z2ui5_if_ajson.
|
||||
data li_del type ref to z2ui5_if_ajson.
|
||||
data li_mod type ref to z2ui5_if_ajson.
|
||||
|
||||
diff(
|
||||
exporting
|
||||
iv_json_a = iv_json_a
|
||||
iv_json_b = iv_json_b
|
||||
io_json_a = ii_json_a
|
||||
io_json_b = ii_json_b
|
||||
importing
|
||||
eo_insert = li_ins
|
||||
eo_delete = li_del
|
||||
eo_change = li_mod ).
|
||||
|
||||
rv_yes = boolc(
|
||||
li_ins->is_empty( ) = abap_true and
|
||||
li_del->is_empty( ) = abap_true and
|
||||
li_mod->is_empty( ) = abap_true ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method merge.
|
||||
|
||||
mo_json_a = normalize_input(
|
||||
iv_json = iv_json_a
|
||||
io_json = io_json_a ).
|
||||
|
||||
mo_json_b = normalize_input(
|
||||
iv_json = iv_json_b
|
||||
io_json = io_json_b ).
|
||||
|
||||
" Start with first JSON...
|
||||
mo_insert = mo_json_a.
|
||||
|
||||
" ...and add all nodes from second JSON
|
||||
diff_b_a( '/' ).
|
||||
|
||||
ro_json ?= mo_insert.
|
||||
|
||||
delete_empty_nodes(
|
||||
io_json = ro_json
|
||||
iv_keep_empty_arrays = iv_keep_empty_arrays ).
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method new.
|
||||
create object ro_instance.
|
||||
endmethod.
|
||||
|
||||
|
||||
method normalize_input.
|
||||
|
||||
if boolc( iv_json is initial ) = boolc( io_json is initial ).
|
||||
z2UI5_cx_ajson_error=>raise( 'Either supply JSON string or instance, but not both' ).
|
||||
endif.
|
||||
|
||||
if iv_json is not initial.
|
||||
ro_json = z2ui5_cl_ajson=>parse( iv_json ).
|
||||
elseif io_json is not initial.
|
||||
ro_json = io_json.
|
||||
else.
|
||||
z2UI5_cx_ajson_error=>raise( 'Supply either JSON string or instance' ).
|
||||
endif.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method sort.
|
||||
|
||||
data lo_json type ref to z2ui5_if_ajson.
|
||||
|
||||
lo_json = normalize_input(
|
||||
iv_json = iv_json
|
||||
io_json = io_json ).
|
||||
|
||||
" Nodes are parsed into a sorted table, so no explicit sorting required
|
||||
rv_sorted = lo_json->stringify( 2 ).
|
||||
|
||||
endmethod.
|
||||
ENDCLASS.
|
548
src/01/00/01/z2ui5_cl_ajson_utilities.clas.testclasses.abap
Normal file
548
src/01/00/01/z2ui5_cl_ajson_utilities.clas.testclasses.abap
Normal file
|
@ -0,0 +1,548 @@
|
|||
**********************************************************************
|
||||
* UTIL
|
||||
**********************************************************************
|
||||
|
||||
class lcl_nodes_helper definition final.
|
||||
public section.
|
||||
|
||||
data mt_nodes type z2ui5_if_ajson_types=>ty_nodes_tt read-only.
|
||||
|
||||
methods add
|
||||
importing
|
||||
iv_str type string.
|
||||
methods sorted
|
||||
returning
|
||||
value(rt_nodes) type z2ui5_if_ajson_types=>ty_nodes_ts.
|
||||
|
||||
endclass.
|
||||
|
||||
class lcl_nodes_helper implementation.
|
||||
method add.
|
||||
|
||||
field-symbols <n> like line of mt_nodes.
|
||||
data lv_children type string.
|
||||
data lv_index type string.
|
||||
|
||||
append initial line to mt_nodes assigning <n>.
|
||||
|
||||
split iv_str at '|' into
|
||||
<n>-path
|
||||
<n>-name
|
||||
<n>-type
|
||||
<n>-value
|
||||
lv_index
|
||||
lv_children.
|
||||
condense <n>-path.
|
||||
condense <n>-name.
|
||||
condense <n>-type.
|
||||
condense <n>-value.
|
||||
<n>-index = lv_index.
|
||||
<n>-children = lv_children.
|
||||
|
||||
endmethod.
|
||||
|
||||
method sorted.
|
||||
rt_nodes = mt_nodes.
|
||||
endmethod.
|
||||
endclass.
|
||||
|
||||
**********************************************************************
|
||||
* PARSER
|
||||
**********************************************************************
|
||||
|
||||
class ltcl_parser_test definition final
|
||||
for testing
|
||||
risk level harmless
|
||||
duration short.
|
||||
|
||||
public section.
|
||||
|
||||
class-methods sample_json
|
||||
importing
|
||||
iv_separator type string optional
|
||||
returning
|
||||
value(rv_json) type string.
|
||||
|
||||
endclass.
|
||||
|
||||
class ltcl_parser_test implementation.
|
||||
|
||||
method sample_json.
|
||||
|
||||
rv_json =
|
||||
'{\n' &&
|
||||
' "string": "abc",\n' &&
|
||||
' "number": 123,\n' &&
|
||||
' "float": 123.45,\n' &&
|
||||
' "boolean": true,\n' &&
|
||||
' "false": false,\n' &&
|
||||
' "null": null,\n' &&
|
||||
' "date": "2020-03-15",\n' &&
|
||||
' "issues": [\n' &&
|
||||
' {\n' &&
|
||||
' "message": "Indentation problem ...",\n' &&
|
||||
' "key": "indentation",\n' &&
|
||||
' "start": {\n' &&
|
||||
' "row": 4,\n' &&
|
||||
' "col": 3\n' &&
|
||||
' },\n' &&
|
||||
' "end": {\n' &&
|
||||
' "row": 4,\n' &&
|
||||
' "col": 26\n' &&
|
||||
' },\n' &&
|
||||
' "filename": "./zxxx.prog.abap"\n' &&
|
||||
' },\n' &&
|
||||
' {\n' &&
|
||||
' "message": "Remove space before XXX",\n' &&
|
||||
' "key": "space_before_dot",\n' &&
|
||||
' "start": {\n' &&
|
||||
' "row": 3,\n' &&
|
||||
' "col": 21\n' &&
|
||||
' },\n' &&
|
||||
' "end": {\n' &&
|
||||
' "row": 3,\n' &&
|
||||
' "col": 22\n' &&
|
||||
' },\n' &&
|
||||
' "filename": "./zxxx.prog.abap"\n' &&
|
||||
' }\n' &&
|
||||
' ]\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in rv_json with iv_separator.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
||||
|
||||
**********************************************************************
|
||||
* JSON UTILITIES
|
||||
**********************************************************************
|
||||
|
||||
class ltcl_json_utils definition
|
||||
for testing
|
||||
risk level harmless
|
||||
duration short
|
||||
final.
|
||||
|
||||
private section.
|
||||
|
||||
methods json_diff for testing raising z2UI5_cx_ajson_error.
|
||||
methods json_diff_types for testing raising z2UI5_cx_ajson_error.
|
||||
methods json_diff_arrays for testing raising z2UI5_cx_ajson_error.
|
||||
methods json_merge for testing raising z2UI5_cx_ajson_error.
|
||||
methods json_sort for testing raising z2UI5_cx_ajson_error.
|
||||
methods is_equal for testing raising z2UI5_cx_ajson_error.
|
||||
|
||||
endclass.
|
||||
|
||||
class ltcl_json_utils implementation.
|
||||
|
||||
method json_diff.
|
||||
|
||||
data:
|
||||
lv_json type string,
|
||||
lo_util type ref to z2ui5_cl_ajson_utilities,
|
||||
lo_insert type ref to z2ui5_if_ajson,
|
||||
lo_delete type ref to z2ui5_if_ajson,
|
||||
lo_change type ref to z2ui5_if_ajson,
|
||||
lo_insert_exp type ref to lcl_nodes_helper,
|
||||
lo_delete_exp type ref to lcl_nodes_helper,
|
||||
lo_change_exp type ref to lcl_nodes_helper.
|
||||
|
||||
lv_json =
|
||||
'{\n' &&
|
||||
' "string": "abc",\n' && " no changes
|
||||
' "number": 789,\n' && " changed value
|
||||
' "float": 123.45,\n' &&
|
||||
' "boolean": "true",\n' && " changed type
|
||||
' "true": true,\n' && " insert
|
||||
* ' "false": false,\n' && " delete
|
||||
' "null": null,\n' &&
|
||||
' "date": "2020-03-15",\n' &&
|
||||
' "issues": [\n' &&
|
||||
' {\n' &&
|
||||
' "message": "Indentation problem ...",\n' &&
|
||||
' "key": "indentation",\n' &&
|
||||
' "start": {\n' &&
|
||||
' "row": 5,\n' && " array change
|
||||
' "col": 3\n' &&
|
||||
' },\n' &&
|
||||
' "end": {\n' &&
|
||||
' "new": 1,\n' && " array insert
|
||||
* ' "row": 4,\n' && " array delete
|
||||
' "col": 26\n' &&
|
||||
' },\n' &&
|
||||
' "filename": "./zxxx.prog.abap"\n' &&
|
||||
' },\n' &&
|
||||
' {\n' &&
|
||||
' "message": "Remove space before XXX",\n' &&
|
||||
' "key": "space_before_dot",\n' &&
|
||||
' "start": {\n' &&
|
||||
' "row": 3,\n' &&
|
||||
' "col": 21\n' &&
|
||||
' },\n' &&
|
||||
' "end": {\n' &&
|
||||
' "row": 3,\n' &&
|
||||
' "col": 22\n' &&
|
||||
' },\n' &&
|
||||
' "filename": "./zxxx.prog.abap"\n' &&
|
||||
' }\n' &&
|
||||
' ]\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in lv_json with cl_abap_char_utilities=>newline.
|
||||
|
||||
create object lo_insert_exp.
|
||||
lo_insert_exp->add( ' | |object | |0|3' ).
|
||||
lo_insert_exp->add( '/ |boolean |str |true |0|0' ). " changed type (insert new)
|
||||
lo_insert_exp->add( '/ |issues |array | |0|1' ).
|
||||
lo_insert_exp->add( '/ |true |bool |true |0|0' ). " insert
|
||||
lo_insert_exp->add( '/issues/ |1 |object | |1|1' ).
|
||||
lo_insert_exp->add( '/issues/1/ |end |object | |0|1' ).
|
||||
lo_insert_exp->add( '/issues/1/end/ |new |num |1 |0|0' ). " array insert
|
||||
|
||||
create object lo_delete_exp.
|
||||
lo_delete_exp->add( ' | |object | |0|3' ).
|
||||
lo_delete_exp->add( '/ |boolean |bool |true |0|0' ). " changed type (delete old)
|
||||
lo_delete_exp->add( '/ |false |bool |false |0|0' ). " delete
|
||||
lo_delete_exp->add( '/ |issues |array | |0|1' ).
|
||||
lo_delete_exp->add( '/issues/ |1 |object | |1|1' ).
|
||||
lo_delete_exp->add( '/issues/1/ |end |object | |0|1' ).
|
||||
lo_delete_exp->add( '/issues/1/end/ |row |num |4 |0|0' ). " array delete
|
||||
|
||||
create object lo_change_exp.
|
||||
lo_change_exp->add( ' | |object | |0|2' ).
|
||||
lo_change_exp->add( '/ |issues |array | |0|1' ).
|
||||
lo_change_exp->add( '/ |number |num |789 |0|0' ). " changed value
|
||||
lo_change_exp->add( '/issues/ |1 |object | |1|1' ).
|
||||
lo_change_exp->add( '/issues/1/ |start |object | |0|1' ).
|
||||
lo_change_exp->add( '/issues/1/start/|row |num |5 |0|0' ). " array change
|
||||
|
||||
create object lo_util.
|
||||
|
||||
lo_util->diff(
|
||||
exporting
|
||||
iv_json_a = ltcl_parser_test=>sample_json( )
|
||||
iv_json_b = lv_json
|
||||
importing
|
||||
eo_insert = lo_insert
|
||||
eo_delete = lo_delete
|
||||
eo_change = lo_change ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_insert->mt_json_tree
|
||||
exp = lo_insert_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_delete->mt_json_tree
|
||||
exp = lo_delete_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_change->mt_json_tree
|
||||
exp = lo_change_exp->mt_nodes ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method json_diff_types.
|
||||
|
||||
data:
|
||||
lv_json_a type string,
|
||||
lv_json_b type string,
|
||||
lo_util type ref to z2ui5_cl_ajson_utilities,
|
||||
lo_insert type ref to z2ui5_if_ajson,
|
||||
lo_delete type ref to z2ui5_if_ajson,
|
||||
lo_change type ref to z2ui5_if_ajson,
|
||||
lo_insert_exp type ref to lcl_nodes_helper,
|
||||
lo_delete_exp type ref to lcl_nodes_helper.
|
||||
|
||||
" Change single value to array
|
||||
lv_json_a =
|
||||
'{\n' &&
|
||||
' "string": "abc",\n' &&
|
||||
' "number": 123\n' &&
|
||||
'}'.
|
||||
|
||||
lv_json_b =
|
||||
'{\n' &&
|
||||
' "string": [\n' &&
|
||||
' "a",\n' &&
|
||||
' "b",\n' &&
|
||||
' "c"\n' &&
|
||||
' ],\n' &&
|
||||
' "number": 123\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in lv_json_a with cl_abap_char_utilities=>newline.
|
||||
replace all occurrences of '\n' in lv_json_b with cl_abap_char_utilities=>newline.
|
||||
|
||||
create object lo_insert_exp.
|
||||
lo_insert_exp->add( ' | |object | |0|1' ).
|
||||
lo_insert_exp->add( '/ |string |array | |0|3' ).
|
||||
lo_insert_exp->add( '/string/ |1 |str |a |1|0' ).
|
||||
lo_insert_exp->add( '/string/ |2 |str |b |2|0' ).
|
||||
lo_insert_exp->add( '/string/ |3 |str |c |3|0' ).
|
||||
|
||||
create object lo_delete_exp.
|
||||
lo_delete_exp->add( ' | |object | |0|1' ).
|
||||
lo_delete_exp->add( '/ |string |str |abc |0|0' ).
|
||||
|
||||
create object lo_util.
|
||||
|
||||
lo_util->diff(
|
||||
exporting
|
||||
iv_json_a = lv_json_a
|
||||
iv_json_b = lv_json_b
|
||||
importing
|
||||
eo_insert = lo_insert
|
||||
eo_delete = lo_delete
|
||||
eo_change = lo_change ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_insert->mt_json_tree
|
||||
exp = lo_insert_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_delete->mt_json_tree
|
||||
exp = lo_delete_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_change->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
" Change array to single value
|
||||
lo_util->diff(
|
||||
exporting
|
||||
iv_json_a = lv_json_b
|
||||
iv_json_b = lv_json_a
|
||||
importing
|
||||
eo_insert = lo_insert
|
||||
eo_delete = lo_delete
|
||||
eo_change = lo_change ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_insert->mt_json_tree
|
||||
exp = lo_delete_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_delete->mt_json_tree
|
||||
exp = lo_insert_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_change->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method json_diff_arrays.
|
||||
|
||||
data:
|
||||
lv_json_a type string,
|
||||
lv_json_b type string,
|
||||
lo_util type ref to z2ui5_cl_ajson_utilities,
|
||||
lo_insert type ref to z2ui5_if_ajson,
|
||||
lo_delete type ref to z2ui5_if_ajson,
|
||||
lo_change type ref to z2ui5_if_ajson,
|
||||
lo_insert_exp type ref to lcl_nodes_helper.
|
||||
|
||||
" Add empty array
|
||||
lv_json_a =
|
||||
'{\n' &&
|
||||
' "number": 123\n' &&
|
||||
'}'.
|
||||
|
||||
lv_json_b =
|
||||
'{\n' &&
|
||||
' "names": [],\n' &&
|
||||
' "number": 123\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in lv_json_a with cl_abap_char_utilities=>newline.
|
||||
replace all occurrences of '\n' in lv_json_b with cl_abap_char_utilities=>newline.
|
||||
|
||||
create object lo_util.
|
||||
|
||||
" Empty arrays are ignored by default
|
||||
lo_util->diff(
|
||||
exporting
|
||||
iv_json_a = lv_json_a
|
||||
iv_json_b = lv_json_b
|
||||
importing
|
||||
eo_insert = lo_insert
|
||||
eo_delete = lo_delete
|
||||
eo_change = lo_change ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_insert->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_delete->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_change->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
" Keep empty arrays
|
||||
lo_util->diff(
|
||||
exporting
|
||||
iv_json_a = lv_json_a
|
||||
iv_json_b = lv_json_b
|
||||
iv_keep_empty_arrays = abap_true
|
||||
importing
|
||||
eo_insert = lo_insert
|
||||
eo_delete = lo_delete
|
||||
eo_change = lo_change ).
|
||||
|
||||
create object lo_insert_exp.
|
||||
lo_insert_exp->add( ' | |object | |0|1' ).
|
||||
lo_insert_exp->add( '/ |names |array | |0|0' ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_insert->mt_json_tree
|
||||
exp = lo_insert_exp->mt_nodes ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_delete->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lines( lo_change->mt_json_tree )
|
||||
exp = 0 ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method json_merge.
|
||||
|
||||
data:
|
||||
lv_json_a type string,
|
||||
lv_json_b type string,
|
||||
lo_util type ref to z2ui5_cl_ajson_utilities,
|
||||
lo_merge type ref to z2ui5_if_ajson,
|
||||
lo_merge_exp type ref to lcl_nodes_helper.
|
||||
|
||||
" Merge new value of b into a
|
||||
lv_json_a =
|
||||
'{\n' &&
|
||||
' "string": [\n' &&
|
||||
' "a",\n' &&
|
||||
' "c"\n' &&
|
||||
' ],\n' &&
|
||||
' "number": 123\n' &&
|
||||
'}'.
|
||||
|
||||
lv_json_b =
|
||||
'{\n' &&
|
||||
' "string": [\n' &&
|
||||
' "a",\n' &&
|
||||
' "b"\n' && " new array value
|
||||
' ],\n' &&
|
||||
' "number": 456,\n' && " existing values are not overwritten
|
||||
' "float": 123.45\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in lv_json_a with cl_abap_char_utilities=>newline.
|
||||
replace all occurrences of '\n' in lv_json_b with cl_abap_char_utilities=>newline.
|
||||
|
||||
create object lo_merge_exp.
|
||||
lo_merge_exp->add( ' | |object | |0|3' ).
|
||||
lo_merge_exp->add( '/ |float |num |123.45 |0|0' ).
|
||||
lo_merge_exp->add( '/ |number |num |123 |0|0' ).
|
||||
lo_merge_exp->add( '/ |string |array | |0|3' ).
|
||||
lo_merge_exp->add( '/string/ |1 |str |a |1|0' ).
|
||||
lo_merge_exp->add( '/string/ |2 |str |c |2|0' ).
|
||||
lo_merge_exp->add( '/string/ |3 |str |b |3|0' ).
|
||||
|
||||
create object lo_util.
|
||||
|
||||
lo_merge = lo_util->merge(
|
||||
iv_json_a = lv_json_a
|
||||
iv_json_b = lv_json_b ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lo_merge->mt_json_tree
|
||||
exp = lo_merge_exp->mt_nodes ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method json_sort.
|
||||
|
||||
data:
|
||||
lv_json type string,
|
||||
lo_util type ref to z2ui5_cl_ajson_utilities,
|
||||
lv_sorted type string,
|
||||
lv_sorted_exp type string.
|
||||
|
||||
lv_json =
|
||||
'{\n' &&
|
||||
' "string": "abc",\n' &&
|
||||
' "number": 789,\n' &&
|
||||
' "float": 123.45,\n' &&
|
||||
' "boolean": "true",\n' &&
|
||||
' "true": true,\n' &&
|
||||
' "false": false,\n' &&
|
||||
' "null": null,\n' &&
|
||||
' "date": "2020-03-15"\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in lv_json with cl_abap_char_utilities=>newline.
|
||||
|
||||
lv_sorted_exp =
|
||||
'{\n' &&
|
||||
' "boolean": "true",\n' &&
|
||||
' "date": "2020-03-15",\n' &&
|
||||
' "false": false,\n' &&
|
||||
' "float": 123.45,\n' &&
|
||||
' "null": null,\n' &&
|
||||
' "number": 789,\n' &&
|
||||
' "string": "abc",\n' &&
|
||||
' "true": true\n' &&
|
||||
'}'.
|
||||
|
||||
replace all occurrences of '\n' in lv_sorted_exp with cl_abap_char_utilities=>newline.
|
||||
|
||||
create object lo_util.
|
||||
|
||||
lv_sorted = lo_util->sort( iv_json = lv_json ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = lv_sorted
|
||||
exp = lv_sorted_exp ).
|
||||
|
||||
endmethod.
|
||||
|
||||
method is_equal.
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson_utilities=>new( )->is_equal(
|
||||
ii_json_a = z2ui5_cl_ajson=>parse( '{"a":1,"b":2}' )
|
||||
ii_json_b = z2ui5_cl_ajson=>parse( '{"a":1,"b":2}' ) )
|
||||
exp = abap_true ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson_utilities=>new( )->is_equal(
|
||||
iv_json_a = '{"a":1,"b":2}'
|
||||
iv_json_b = '{"a":1,"b":2}' )
|
||||
exp = abap_true ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson_utilities=>new( )->is_equal(
|
||||
iv_json_a = '{"a":1,"b":2}'
|
||||
iv_json_b = '{"a":1,"b":3}' )
|
||||
exp = abap_false ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson_utilities=>new( )->is_equal(
|
||||
iv_json_a = '{"a":1,"b":2}'
|
||||
iv_json_b = '{"a":1,"b":2,"c":3}' )
|
||||
exp = abap_false ).
|
||||
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
act = z2ui5_cl_ajson_utilities=>new( )->is_equal(
|
||||
iv_json_a = '{"a":1,"b":2,"c":3}'
|
||||
iv_json_b = '{"a":1,"b":2}' )
|
||||
exp = abap_false ).
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
17
src/01/00/01/z2ui5_cl_ajson_utilities.clas.xml
Normal file
17
src/01/00/01/z2ui5_cl_ajson_utilities.clas.xml
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOCLASS>
|
||||
<CLSNAME>Z2UI5_CL_AJSON_UTILITIES</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON Utilities</DESCRIPT>
|
||||
<STATE>1</STATE>
|
||||
<CLSCCINCL>X</CLSCCINCL>
|
||||
<FIXPT>X</FIXPT>
|
||||
<UNICODE>X</UNICODE>
|
||||
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
|
||||
</VSEOCLASS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
137
src/01/00/01/z2ui5_cx_ajson_error.clas.abap
Normal file
137
src/01/00/01/z2ui5_cx_ajson_error.clas.abap
Normal file
|
@ -0,0 +1,137 @@
|
|||
class Z2UI5_CX_AJSON_ERROR definition
|
||||
public
|
||||
inheriting from CX_STATIC_CHECK
|
||||
final
|
||||
create public .
|
||||
|
||||
public section.
|
||||
|
||||
interfaces IF_T100_MESSAGE .
|
||||
|
||||
types:
|
||||
ty_rc type c length 4 .
|
||||
|
||||
constants:
|
||||
begin of ZCX_AJSON_ERROR,
|
||||
msgid type symsgid value '00',
|
||||
msgno type symsgno value '001',
|
||||
attr1 type scx_attrname value 'A1',
|
||||
attr2 type scx_attrname value 'A2',
|
||||
attr3 type scx_attrname value 'A3',
|
||||
attr4 type scx_attrname value 'A4',
|
||||
end of ZCX_AJSON_ERROR .
|
||||
data RC type TY_RC read-only .
|
||||
data MESSAGE type STRING read-only .
|
||||
data LOCATION type STRING read-only .
|
||||
data A1 type SYMSGV read-only .
|
||||
data A2 type SYMSGV read-only .
|
||||
data A3 type SYMSGV read-only .
|
||||
data A4 type SYMSGV read-only .
|
||||
|
||||
methods CONSTRUCTOR
|
||||
importing
|
||||
!TEXTID like IF_T100_MESSAGE=>T100KEY optional
|
||||
!PREVIOUS like PREVIOUS optional
|
||||
!RC type TY_RC optional
|
||||
!MESSAGE type STRING optional
|
||||
!LOCATION type STRING optional
|
||||
!A1 type SYMSGV optional
|
||||
!A2 type SYMSGV optional
|
||||
!A3 type SYMSGV optional
|
||||
!A4 type SYMSGV optional .
|
||||
class-methods RAISE
|
||||
importing
|
||||
!IV_MSG type STRING
|
||||
!IV_LOCATION type STRING optional
|
||||
!IS_NODE type ANY optional
|
||||
raising
|
||||
Z2UI5_CX_AJSON_ERROR .
|
||||
methods SET_LOCATION
|
||||
importing
|
||||
!IV_LOCATION type STRING optional
|
||||
!IS_NODE type ANY optional
|
||||
preferred parameter IV_LOCATION .
|
||||
protected section.
|
||||
private section.
|
||||
types:
|
||||
begin of ty_message_parts,
|
||||
a1 like a1,
|
||||
a2 like a1,
|
||||
a3 like a1,
|
||||
a4 like a1,
|
||||
end of ty_message_parts.
|
||||
ENDCLASS.
|
||||
|
||||
|
||||
|
||||
CLASS Z2UI5_CX_AJSON_ERROR IMPLEMENTATION.
|
||||
|
||||
|
||||
method CONSTRUCTOR ##ADT_SUPPRESS_GENERATION.
|
||||
CALL METHOD SUPER->CONSTRUCTOR
|
||||
EXPORTING
|
||||
PREVIOUS = PREVIOUS
|
||||
.
|
||||
me->RC = RC .
|
||||
me->MESSAGE = MESSAGE .
|
||||
me->LOCATION = LOCATION .
|
||||
me->A1 = A1 .
|
||||
me->A2 = A2 .
|
||||
me->A3 = A3 .
|
||||
me->A4 = A4 .
|
||||
clear me->textid.
|
||||
if textid is initial.
|
||||
IF_T100_MESSAGE~T100KEY = ZCX_AJSON_ERROR .
|
||||
else.
|
||||
IF_T100_MESSAGE~T100KEY = TEXTID.
|
||||
endif.
|
||||
endmethod.
|
||||
|
||||
|
||||
method raise.
|
||||
|
||||
data lx type ref to z2ui5_cx_ajson_error.
|
||||
|
||||
create object lx exporting message = iv_msg.
|
||||
lx->set_location(
|
||||
iv_location = iv_location
|
||||
is_node = is_node ).
|
||||
raise exception lx.
|
||||
|
||||
endmethod.
|
||||
|
||||
|
||||
method set_location.
|
||||
|
||||
data ls_msg type ty_message_parts.
|
||||
data lv_location type string.
|
||||
data lv_tmp type string.
|
||||
field-symbols <path> type string.
|
||||
field-symbols <name> type string.
|
||||
|
||||
if iv_location is not initial.
|
||||
lv_location = iv_location.
|
||||
elseif is_node is not initial.
|
||||
assign component 'PATH' of structure is_node to <path>.
|
||||
assign component 'NAME' of structure is_node to <name>.
|
||||
if <path> is assigned and <name> is assigned.
|
||||
lv_location = <path> && <name>.
|
||||
endif.
|
||||
endif.
|
||||
|
||||
if lv_location is not initial.
|
||||
lv_tmp = message && | @{ lv_location }|.
|
||||
else.
|
||||
lv_tmp = message.
|
||||
endif.
|
||||
|
||||
ls_msg = lv_tmp.
|
||||
|
||||
location = lv_location.
|
||||
a1 = ls_msg-a1.
|
||||
a2 = ls_msg-a2.
|
||||
a3 = ls_msg-a3.
|
||||
a4 = ls_msg-a4.
|
||||
|
||||
endmethod.
|
||||
ENDCLASS.
|
108
src/01/00/01/z2ui5_cx_ajson_error.clas.testclasses.abap
Normal file
108
src/01/00/01/z2ui5_cx_ajson_error.clas.testclasses.abap
Normal file
|
@ -0,0 +1,108 @@
|
|||
class ltcl_error definition
|
||||
for testing
|
||||
risk level harmless
|
||||
duration short
|
||||
final.
|
||||
|
||||
private section.
|
||||
|
||||
methods raise for testing.
|
||||
methods raise_w_location for testing.
|
||||
methods raise_w_node for testing.
|
||||
methods set_location for testing.
|
||||
|
||||
endclass.
|
||||
|
||||
class ltcl_error implementation.
|
||||
|
||||
method raise.
|
||||
|
||||
data lx type ref to z2ui5_cx_ajson_error.
|
||||
data lv_msg type string.
|
||||
|
||||
lv_msg = repeat( val = 'a' occ = 50 ) && repeat( val = 'b' occ = 50 ) && '123'.
|
||||
|
||||
try.
|
||||
z2ui5_cx_ajson_error=>raise( lv_msg ).
|
||||
cl_abap_unit_assert=>fail( ).
|
||||
catch z2ui5_cx_ajson_error into lx.
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = lv_msg
|
||||
act = lx->get_text( ) ).
|
||||
endtry.
|
||||
|
||||
endmethod.
|
||||
|
||||
method raise_w_location.
|
||||
|
||||
data lx type ref to z2ui5_cx_ajson_error.
|
||||
|
||||
try.
|
||||
z2ui5_cx_ajson_error=>raise( iv_msg = 'a' iv_location = 'b' ).
|
||||
cl_abap_unit_assert=>fail( ).
|
||||
catch z2ui5_cx_ajson_error into lx.
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = 'a @b'
|
||||
act = lx->get_text( ) ).
|
||||
endtry.
|
||||
|
||||
endmethod.
|
||||
|
||||
method raise_w_node.
|
||||
|
||||
data lx type ref to z2ui5_cx_ajson_error.
|
||||
data ls_node type z2ui5_if_ajson_types=>ty_node.
|
||||
|
||||
ls_node-path = '/x/'.
|
||||
ls_node-name = 'y'.
|
||||
|
||||
try.
|
||||
z2ui5_cx_ajson_error=>raise( iv_msg = 'a' is_node = ls_node ).
|
||||
cl_abap_unit_assert=>fail( ).
|
||||
catch z2ui5_cx_ajson_error into lx.
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = 'a @/x/y'
|
||||
act = lx->get_text( ) ).
|
||||
endtry.
|
||||
|
||||
endmethod.
|
||||
|
||||
method set_location.
|
||||
|
||||
data lx type ref to z2ui5_cx_ajson_error.
|
||||
|
||||
try.
|
||||
z2ui5_cx_ajson_error=>raise( iv_msg = 'a' iv_location = 'b' ).
|
||||
cl_abap_unit_assert=>fail( ).
|
||||
catch z2ui5_cx_ajson_error into lx.
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = lx->location
|
||||
act = 'b' ).
|
||||
lx->set_location( 'c' ).
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = lx->location
|
||||
act = 'c' ).
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = 'a @c'
|
||||
act = lx->get_text( ) ).
|
||||
endtry.
|
||||
|
||||
try.
|
||||
z2ui5_cx_ajson_error=>raise( iv_msg = 'a' ).
|
||||
cl_abap_unit_assert=>fail( ).
|
||||
catch z2ui5_cx_ajson_error into lx.
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = lx->location
|
||||
act = '' ).
|
||||
lx->set_location( 'c' ).
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = lx->location
|
||||
act = 'c' ).
|
||||
cl_abap_unit_assert=>assert_equals(
|
||||
exp = 'a @c'
|
||||
act = lx->get_text( ) ).
|
||||
endtry.
|
||||
|
||||
endmethod.
|
||||
|
||||
endclass.
|
18
src/01/00/01/z2ui5_cx_ajson_error.clas.xml
Normal file
18
src/01/00/01/z2ui5_cx_ajson_error.clas.xml
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_CLAS" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOCLASS>
|
||||
<CLSNAME>Z2UI5_CX_AJSON_ERROR</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON exception</DESCRIPT>
|
||||
<CATEGORY>40</CATEGORY>
|
||||
<STATE>1</STATE>
|
||||
<CLSCCINCL>X</CLSCCINCL>
|
||||
<FIXPT>X</FIXPT>
|
||||
<UNICODE>X</UNICODE>
|
||||
<WITH_UNIT_TESTS>X</WITH_UNIT_TESTS>
|
||||
</VSEOCLASS>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
262
src/01/00/01/z2ui5_if_ajson.intf.abap
Normal file
262
src/01/00/01/z2ui5_if_ajson.intf.abap
Normal file
|
@ -0,0 +1,262 @@
|
|||
interface z2ui5_if_ajson
|
||||
public.
|
||||
|
||||
constants version type string value 'v1.1.9'. "#EC NOTEXT
|
||||
constants origin type string value 'https://github.com/sbcgua/ajson'. "#EC NOTEXT
|
||||
constants license type string value 'MIT'. "#EC NOTEXT
|
||||
|
||||
types:
|
||||
begin of ty_opts,
|
||||
read_only type abap_bool,
|
||||
keep_item_order type abap_bool,
|
||||
format_datetime type abap_bool,
|
||||
to_abap_corresponding_only type abap_bool,
|
||||
end of ty_opts.
|
||||
|
||||
" DATA
|
||||
|
||||
data mt_json_tree type z2ui5_if_ajson_types=>ty_nodes_ts read-only.
|
||||
|
||||
" CLONING
|
||||
|
||||
methods clone
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
methods filter
|
||||
importing
|
||||
ii_filter type ref to z2ui5_if_ajson_filter
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
methods map
|
||||
importing
|
||||
ii_mapper type ref to z2ui5_if_ajson_mapping
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
" METHODS
|
||||
|
||||
methods freeze.
|
||||
methods keep_item_order
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson.
|
||||
methods format_datetime
|
||||
importing
|
||||
iv_use_iso type abap_bool default abap_true
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson.
|
||||
methods to_abap_corresponding_only
|
||||
importing
|
||||
iv_enable type abap_bool default abap_true
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson.
|
||||
methods opts
|
||||
returning
|
||||
value(rs_opts) type ty_opts.
|
||||
|
||||
" METHODS ex.reader
|
||||
|
||||
methods is_empty
|
||||
returning
|
||||
value(rv_yes) type abap_bool.
|
||||
|
||||
methods exists
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_exists) type abap_bool.
|
||||
|
||||
methods members
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rt_members) type string_table.
|
||||
|
||||
methods get
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type string.
|
||||
|
||||
methods get_node_type
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_node_type) type z2ui5_if_ajson_types=>ty_node_type.
|
||||
|
||||
methods get_boolean
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type abap_bool.
|
||||
|
||||
methods get_integer
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type i.
|
||||
|
||||
methods get_number
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type f.
|
||||
|
||||
methods get_date
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type d.
|
||||
|
||||
methods get_timestamp
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type timestamp.
|
||||
|
||||
methods get_string
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rv_value) type string.
|
||||
|
||||
methods slice
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson.
|
||||
|
||||
methods to_abap
|
||||
importing
|
||||
iv_corresponding type abap_bool default abap_false
|
||||
exporting
|
||||
ev_container type any
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods array_to_string_table
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(rt_string_table) type string_table
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
" METHODS ex.writer
|
||||
|
||||
methods clear
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type any
|
||||
iv_ignore_empty type abap_bool default abap_true
|
||||
iv_node_type type z2ui5_if_ajson_types=>ty_node_type optional
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods setx
|
||||
importing
|
||||
iv_param type string
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set_boolean
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type any
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set_string
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type clike
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set_integer
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type i
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set_date
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type d
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set_timestamp
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type timestamp
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods set_null
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods delete
|
||||
importing
|
||||
iv_path type string
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods touch_array
|
||||
importing
|
||||
iv_path type string
|
||||
iv_clear type abap_bool default abap_false
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods push
|
||||
importing
|
||||
iv_path type string
|
||||
iv_val type any
|
||||
returning
|
||||
value(ri_json) type ref to z2ui5_if_ajson
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
methods stringify
|
||||
importing
|
||||
iv_indent type i default 0
|
||||
returning
|
||||
value(rv_json) type string
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
endinterface.
|
15
src/01/00/01/z2ui5_if_ajson.intf.xml
Normal file
15
src/01/00/01/z2ui5_if_ajson.intf.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOINTERF>
|
||||
<CLSNAME>Z2UI5_IF_AJSON</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON interface and types</DESCRIPT>
|
||||
<EXPOSURE>2</EXPOSURE>
|
||||
<STATE>1</STATE>
|
||||
<UNICODE>X</UNICODE>
|
||||
</VSEOINTERF>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
23
src/01/00/01/z2ui5_if_ajson_filter.intf.abap
Normal file
23
src/01/00/01/z2ui5_if_ajson_filter.intf.abap
Normal file
|
@ -0,0 +1,23 @@
|
|||
interface z2ui5_if_ajson_filter
|
||||
public.
|
||||
|
||||
types ty_filter_tab type standard table of ref to z2ui5_if_ajson_filter with key table_line.
|
||||
types ty_visit_type type i.
|
||||
|
||||
constants:
|
||||
begin of visit_type,
|
||||
value type ty_visit_type value 0,
|
||||
open type ty_visit_type value 1,
|
||||
close type ty_visit_type value 2,
|
||||
end of visit_type.
|
||||
|
||||
methods keep_node
|
||||
importing
|
||||
is_node type z2ui5_if_ajson_types=>ty_node
|
||||
iv_visit type ty_visit_type default visit_type-value
|
||||
returning
|
||||
value(rv_keep) type abap_bool
|
||||
raising
|
||||
z2UI5_cx_ajson_error.
|
||||
|
||||
endinterface.
|
15
src/01/00/01/z2ui5_if_ajson_filter.intf.xml
Normal file
15
src/01/00/01/z2ui5_if_ajson_filter.intf.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOINTERF>
|
||||
<CLSNAME>Z2UI5_IF_AJSON_FILTER</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON filter interface</DESCRIPT>
|
||||
<EXPOSURE>2</EXPOSURE>
|
||||
<STATE>1</STATE>
|
||||
<UNICODE>X</UNICODE>
|
||||
</VSEOINTERF>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
44
src/01/00/01/z2ui5_if_ajson_mapping.intf.abap
Normal file
44
src/01/00/01/z2ui5_if_ajson_mapping.intf.abap
Normal file
|
@ -0,0 +1,44 @@
|
|||
interface z2ui5_if_ajson_mapping
|
||||
public.
|
||||
|
||||
types:
|
||||
begin of ty_mapping_field, " deprecated, will be removed
|
||||
abap type string,
|
||||
json type string,
|
||||
end of ty_mapping_field,
|
||||
ty_mapping_fields type standard table of ty_mapping_field
|
||||
with unique sorted key abap components abap
|
||||
with unique sorted key json components json.
|
||||
|
||||
types:
|
||||
begin of ty_rename,
|
||||
from type string,
|
||||
to type string,
|
||||
end of ty_rename,
|
||||
tty_rename_map type standard table of ty_rename
|
||||
with unique sorted key by_name components from.
|
||||
|
||||
types:
|
||||
ty_table_of type standard table of ref to z2ui5_if_ajson_mapping.
|
||||
|
||||
methods to_abap " deprecated, will be removed
|
||||
importing
|
||||
!iv_path type string
|
||||
!iv_name type string
|
||||
returning
|
||||
value(rv_result) type string.
|
||||
|
||||
methods to_json " deprecated, will be removed
|
||||
importing
|
||||
!iv_path type string
|
||||
!iv_name type string
|
||||
returning
|
||||
value(rv_result) type string.
|
||||
|
||||
methods rename_node
|
||||
importing
|
||||
!is_node type z2ui5_if_ajson_types=>ty_node
|
||||
changing
|
||||
!cv_name type z2ui5_if_ajson_types=>ty_node-name.
|
||||
|
||||
endinterface.
|
15
src/01/00/01/z2ui5_if_ajson_mapping.intf.xml
Normal file
15
src/01/00/01/z2ui5_if_ajson_mapping.intf.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOINTERF>
|
||||
<CLSNAME>Z2UI5_IF_AJSON_MAPPING</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON Mapping</DESCRIPT>
|
||||
<EXPOSURE>2</EXPOSURE>
|
||||
<STATE>1</STATE>
|
||||
<UNICODE>X</UNICODE>
|
||||
</VSEOINTERF>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
41
src/01/00/01/z2ui5_if_ajson_types.intf.abap
Normal file
41
src/01/00/01/z2ui5_if_ajson_types.intf.abap
Normal file
|
@ -0,0 +1,41 @@
|
|||
interface z2ui5_if_ajson_types
|
||||
public.
|
||||
|
||||
types:
|
||||
ty_node_type type string.
|
||||
|
||||
constants:
|
||||
begin of node_type,
|
||||
boolean type ty_node_type value 'bool',
|
||||
string type ty_node_type value 'str',
|
||||
number type ty_node_type value 'num',
|
||||
null type ty_node_type value 'null',
|
||||
array type ty_node_type value 'array',
|
||||
object type ty_node_type value 'object',
|
||||
end of node_type.
|
||||
|
||||
types:
|
||||
begin of ty_node,
|
||||
path type string,
|
||||
name type string,
|
||||
type type ty_node_type,
|
||||
value type string,
|
||||
index type i,
|
||||
order type i,
|
||||
children type i,
|
||||
end of ty_node.
|
||||
types:
|
||||
ty_nodes_tt type standard table of ty_node with key path name.
|
||||
types:
|
||||
ty_nodes_ts type sorted table of ty_node
|
||||
with unique key path name
|
||||
with non-unique sorted key array_index components path index
|
||||
with non-unique sorted key item_order components path order.
|
||||
|
||||
types:
|
||||
begin of ty_path_name,
|
||||
path type string,
|
||||
name type string,
|
||||
end of ty_path_name.
|
||||
|
||||
endinterface.
|
15
src/01/00/01/z2ui5_if_ajson_types.intf.xml
Normal file
15
src/01/00/01/z2ui5_if_ajson_types.intf.xml
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
|
||||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<VSEOINTERF>
|
||||
<CLSNAME>Z2UI5_IF_AJSON_TYPES</CLSNAME>
|
||||
<LANGU>E</LANGU>
|
||||
<DESCRIPT>AJSON common types</DESCRIPT>
|
||||
<EXPOSURE>2</EXPOSURE>
|
||||
<STATE>1</STATE>
|
||||
<UNICODE>X</UNICODE>
|
||||
</VSEOINTERF>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
</abapGit>
|
|
@ -3,7 +3,7 @@
|
|||
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||
<asx:values>
|
||||
<DEVC>
|
||||
<CTEXT>external libraries</CTEXT>
|
||||
<CTEXT>abap2UI5 - ext libraries</CTEXT>
|
||||
</DEVC>
|
||||
</asx:values>
|
||||
</asx:abap>
|
||||
|
|
|
@ -44,7 +44,9 @@ CLASS z2ui5_cl_fw_model IMPLEMENTATION.
|
|||
ENDMETHOD.
|
||||
|
||||
|
||||
|
||||
METHOD main_set_backend.
|
||||
|
||||
FIELD-SYMBOLS <backend> TYPE any.
|
||||
FIELD-SYMBOLS <frontend> TYPE any.
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user