ajson, Automatic Update (#5966)

This commit is contained in:
github-actions[bot] 2023-01-03 14:47:44 +01:00 committed by GitHub
parent 0ea950c938
commit 95389c532b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 1460 additions and 109 deletions

View File

@ -164,7 +164,9 @@
"cyclic_oo": false, "cyclic_oo": false,
"fully_type_constants": true, "fully_type_constants": true,
"keep_single_parameter_on_one_line": true, "keep_single_parameter_on_one_line": true,
"prefer_returning_to_exporting": true, "prefer_returning_to_exporting": {
"exclude": ["/json/"]
},
"selection_screen_naming": true, "selection_screen_naming": true,
"sicf_consistency": true, "sicf_consistency": true,
"sql_escape_host_variables": true, "sql_escape_host_variables": true,
@ -291,7 +293,7 @@
}, },
"line_length": { "line_length": {
"length": 120, "length": 120,
"exclude": ["zcl_abapgit_object_pdts.clas.testclasses.abap"] "exclude": ["zcl_abapgit_object_pdts.clas.testclasses.abap", "/json/"]
}, },
"line_only_punc": { "line_only_punc": {
"ignoreExceptions": true "ignoreExceptions": true

View File

@ -26,12 +26,12 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"@abaplint/cli": "^2.94.10", "@abaplint/cli": "^2.94.13",
"@abaplint/database-sqlite": "^2.3.93", "@abaplint/database-sqlite": "^2.3.93",
"@abaplint/runtime": "^2.3.93", "@abaplint/runtime": "^2.3.94",
"@abaplint/transpiler-cli": "^2.3.93", "@abaplint/transpiler-cli": "^2.3.94",
"abapmerge": "^0.14.8", "abapmerge": "^0.14.8",
"c8": "^7.12.0", "c8": "^7.12.0",
"eslint": "^8.30.0" "eslint": "^8.31.0"
} }
} }

View File

@ -1,6 +1,6 @@
CLASS zcl_abapgit_ajson DEFINITION CLASS zcl_abapgit_ajson DEFINITION
PUBLIC PUBLIC
CREATE PRIVATE . CREATE PUBLIC .
PUBLIC SECTION. PUBLIC SECTION.
@ -24,6 +24,7 @@ CLASS zcl_abapgit_ajson DEFINITION
ALIASES: ALIASES:
clear FOR zif_abapgit_ajson~clear, clear FOR zif_abapgit_ajson~clear,
set FOR zif_abapgit_ajson~set, set FOR zif_abapgit_ajson~set,
setx FOR zif_abapgit_ajson~setx,
set_boolean FOR zif_abapgit_ajson~set_boolean, set_boolean FOR zif_abapgit_ajson~set_boolean,
set_string FOR zif_abapgit_ajson~set_string, set_string FOR zif_abapgit_ajson~set_string,
set_integer FOR zif_abapgit_ajson~set_integer, set_integer FOR zif_abapgit_ajson~set_integer,
@ -35,6 +36,11 @@ CLASS zcl_abapgit_ajson DEFINITION
push FOR zif_abapgit_ajson~push, push FOR zif_abapgit_ajson~push,
stringify FOR zif_abapgit_ajson~stringify. stringify FOR zif_abapgit_ajson~stringify.
ALIASES:
clone FOR zif_abapgit_ajson~clone,
filter FOR zif_abapgit_ajson~filter,
map FOR zif_abapgit_ajson~map.
ALIASES: ALIASES:
mt_json_tree FOR zif_abapgit_ajson~mt_json_tree, mt_json_tree FOR zif_abapgit_ajson~mt_json_tree,
keep_item_order FOR zif_abapgit_ajson~keep_item_order, keep_item_order FOR zif_abapgit_ajson~keep_item_order,
@ -51,33 +57,44 @@ CLASS zcl_abapgit_ajson DEFINITION
RAISING RAISING
zcx_abapgit_ajson_error . zcx_abapgit_ajson_error .
CLASS-METHODS create_empty CLASS-METHODS create_empty " Might be deprecated, prefer using new( ) or create object
IMPORTING IMPORTING
!ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL !ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
iv_keep_item_order TYPE abap_bool DEFAULT abap_false
iv_format_datetime TYPE abap_bool DEFAULT abap_true
RETURNING RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson. VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson.
" Experimental ! May change " Experimental ! May change
CLASS-METHODS create_from CLASS-METHODS create_from " TODO, rename to 'from' ?
IMPORTING IMPORTING
!ii_source_json TYPE REF TO zif_abapgit_ajson !ii_source_json TYPE REF TO zif_abapgit_ajson
!ii_filter TYPE REF TO zif_abapgit_ajson_filter OPTIONAL !ii_filter TYPE REF TO zif_abapgit_ajson_filter OPTIONAL " Might be deprecated, use filter() instead
!ii_mapper TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL " Might be deprecated, use map() instead
RETURNING RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson
RAISING RAISING
zcx_abapgit_ajson_error . zcx_abapgit_ajson_error .
METHODS constructor. METHODS constructor
IMPORTING
iv_keep_item_order TYPE abap_bool DEFAULT abap_false
iv_format_datetime TYPE abap_bool DEFAULT abap_true.
CLASS-METHODS new
IMPORTING
iv_keep_item_order TYPE abap_bool DEFAULT abap_false
iv_format_datetime TYPE abap_bool DEFAULT abap_true
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_ajson.
PROTECTED SECTION. PROTECTED SECTION.
PRIVATE SECTION. PRIVATE SECTION.
DATA mv_read_only TYPE abap_bool. CLASS-DATA go_float_regex TYPE REF TO cl_abap_regex.
DATA mi_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping.
DATA mv_keep_item_order TYPE abap_bool. DATA ms_opts TYPE zif_abapgit_ajson=>ty_opts.
DATA mv_format_datetime TYPE abap_bool. DATA mi_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping. " DEPRECATED, will be removed
" TODO restructure into zif_ajson=>ty_opts
METHODS get_item METHODS get_item
IMPORTING IMPORTING
@ -107,44 +124,51 @@ ENDCLASS.
CLASS zcl_abapgit_ajson IMPLEMENTATION. CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~opts.
rs_opts-read_only = mv_read_only.
rs_opts-format_datetime = mv_format_datetime.
rs_opts-keep_item_order = mv_keep_item_order.
ENDMETHOD.
METHOD constructor. METHOD constructor.
format_datetime( abap_true ). ms_opts-keep_item_order = iv_keep_item_order.
format_datetime( iv_format_datetime ).
ENDMETHOD. ENDMETHOD.
METHOD create_empty. METHOD create_empty.
CREATE OBJECT ro_instance. CREATE OBJECT ro_instance
EXPORTING
iv_format_datetime = iv_format_datetime
iv_keep_item_order = iv_keep_item_order.
ro_instance->mi_custom_mapping = ii_custom_mapping. ro_instance->mi_custom_mapping = ii_custom_mapping.
ENDMETHOD. ENDMETHOD.
METHOD create_from. METHOD create_from.
DATA lo_filter_runner TYPE REF TO lcl_filter_runner. DATA lo_mutator_queue TYPE REF TO lcl_mutator_queue.
IF ii_source_json IS NOT BOUND. IF ii_source_json IS NOT BOUND.
zcx_abapgit_ajson_error=>raise( 'Source not bound' ). zcx_abapgit_ajson_error=>raise( 'Source not bound' ).
ENDIF. ENDIF.
CREATE OBJECT ro_instance. CREATE OBJECT ro_instance
EXPORTING
iv_format_datetime = ii_source_json->opts( )-format_datetime
iv_keep_item_order = ii_source_json->opts( )-keep_item_order.
IF ii_filter IS BOUND. IF ii_filter IS NOT BOUND AND ii_mapper IS NOT BOUND.
CREATE OBJECT lo_filter_runner.
lo_filter_runner->run(
EXPORTING
ii_filter = ii_filter
it_source_tree = ii_source_json->mt_json_tree
CHANGING
ct_dest_tree = ro_instance->mt_json_tree ).
ELSE.
ro_instance->mt_json_tree = ii_source_json->mt_json_tree. ro_instance->mt_json_tree = ii_source_json->mt_json_tree.
" Copy keep order and custom mapping ??? 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. ENDIF.
ENDMETHOD. ENDMETHOD.
@ -201,6 +225,14 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD new.
CREATE OBJECT ro_instance
EXPORTING
iv_format_datetime = iv_format_datetime
iv_keep_item_order = iv_keep_item_order.
ENDMETHOD.
METHOD parse. METHOD parse.
DATA lo_parser TYPE REF TO lcl_json_parser. DATA lo_parser TYPE REF TO lcl_json_parser.
@ -260,7 +292,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD read_only_watchdog. METHOD read_only_watchdog.
IF mv_read_only = abap_true. IF ms_opts-read_only = abap_true.
zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ). zcx_abapgit_ajson_error=>raise( 'This json instance is read only' ).
ENDIF. ENDIF.
ENDMETHOD. ENDMETHOD.
@ -313,6 +345,11 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson~clone.
ri_json = create_from( me ).
ENDMETHOD.
METHOD zif_abapgit_ajson~delete. METHOD zif_abapgit_ajson~delete.
read_only_watchdog( ). read_only_watchdog( ).
@ -334,14 +371,21 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson~filter.
ri_json = create_from(
ii_source_json = me
ii_filter = ii_filter ).
ENDMETHOD.
METHOD zif_abapgit_ajson~format_datetime. METHOD zif_abapgit_ajson~format_datetime.
mv_format_datetime = iv_use_iso. ms_opts-format_datetime = iv_use_iso.
ri_json = me. ri_json = me.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson~freeze. METHOD zif_abapgit_ajson~freeze.
mv_read_only = abap_true. ms_opts-read_only = abap_true.
ENDMETHOD. ENDMETHOD.
@ -462,11 +506,18 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
METHOD zif_abapgit_ajson~keep_item_order. METHOD zif_abapgit_ajson~keep_item_order.
mv_keep_item_order = abap_true. ms_opts-keep_item_order = abap_true.
ri_json = me. ri_json = me.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson~map.
ri_json = create_from(
ii_source_json = me
ii_mapper = ii_mapper ).
ENDMETHOD.
METHOD zif_abapgit_ajson~members. METHOD zif_abapgit_ajson~members.
DATA lv_normalized_path TYPE string. DATA lv_normalized_path TYPE string.
@ -481,6 +532,11 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson~opts.
rs_opts = ms_opts.
ENDMETHOD.
METHOD zif_abapgit_ajson~push. METHOD zif_abapgit_ajson~push.
DATA lr_parent TYPE REF TO zif_abapgit_ajson=>ty_node. DATA lr_parent TYPE REF TO zif_abapgit_ajson=>ty_node.
@ -507,7 +563,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ls_new_path-name = |{ lv_new_index }|. ls_new_path-name = |{ lv_new_index }|.
lt_new_nodes = lcl_abap_to_json=>convert( lt_new_nodes = lcl_abap_to_json=>convert(
iv_keep_item_order = mv_keep_item_order is_opts = ms_opts
iv_data = iv_val iv_data = iv_val
is_prefix = ls_new_path ). 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 ! READ TABLE lt_new_nodes INDEX 1 REFERENCE INTO lr_new_node. " assume first record is the array item - not ideal !
@ -547,16 +603,14 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
IF ls_split_path IS INITIAL. " Assign root, exceptional processing IF ls_split_path IS INITIAL. " Assign root, exceptional processing
IF iv_node_type IS NOT INITIAL. IF iv_node_type IS NOT INITIAL.
mt_json_tree = lcl_abap_to_json=>insert_with_type( mt_json_tree = lcl_abap_to_json=>insert_with_type(
iv_format_datetime = mv_format_datetime is_opts = ms_opts
iv_keep_item_order = mv_keep_item_order
iv_data = iv_val iv_data = iv_val
iv_type = iv_node_type iv_type = iv_node_type
is_prefix = ls_split_path is_prefix = ls_split_path
ii_custom_mapping = mi_custom_mapping ). ii_custom_mapping = mi_custom_mapping ).
ELSE. ELSE.
mt_json_tree = lcl_abap_to_json=>convert( mt_json_tree = lcl_abap_to_json=>convert(
iv_format_datetime = mv_format_datetime is_opts = ms_opts
iv_keep_item_order = mv_keep_item_order
iv_data = iv_val iv_data = iv_val
is_prefix = ls_split_path is_prefix = ls_split_path
ii_custom_mapping = mi_custom_mapping ). ii_custom_mapping = mi_custom_mapping ).
@ -586,8 +640,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
IF iv_node_type IS NOT INITIAL. IF iv_node_type IS NOT INITIAL.
lt_new_nodes = lcl_abap_to_json=>insert_with_type( lt_new_nodes = lcl_abap_to_json=>insert_with_type(
iv_format_datetime = mv_format_datetime is_opts = ms_opts
iv_keep_item_order = mv_keep_item_order
iv_item_order = ls_deleted_node-order iv_item_order = ls_deleted_node-order
iv_data = iv_val iv_data = iv_val
iv_type = iv_node_type iv_type = iv_node_type
@ -596,8 +649,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ii_custom_mapping = mi_custom_mapping ). ii_custom_mapping = mi_custom_mapping ).
ELSE. ELSE.
lt_new_nodes = lcl_abap_to_json=>convert( lt_new_nodes = lcl_abap_to_json=>convert(
iv_format_datetime = mv_format_datetime is_opts = ms_opts
iv_keep_item_order = mv_keep_item_order
iv_item_order = ls_deleted_node-order iv_item_order = ls_deleted_node-order
iv_data = iv_val iv_data = iv_val
iv_array_index = lv_array_index iv_array_index = lv_array_index
@ -614,6 +666,74 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_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.
RETURN.
ENDIF.
SPLIT iv_param AT ':' INTO lv_path lv_val.
CONDENSE lv_path.
CONDENSE lv_val.
IF lv_val IS INITIAL.
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'.
zif_abapgit_ajson~set_null( lv_path ).
ELSEIF lv_val = 'true'.
zif_abapgit_ajson~set_boolean(
iv_path = lv_path
iv_val = abap_true ).
ELSEIF lv_val = 'false'.
zif_abapgit_ajson~set_boolean(
iv_path = lv_path
iv_val = abap_false ).
ELSEIF lv_val CO '0123456789'.
lv_int = lv_val.
zif_abapgit_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.
zif_abapgit_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
zif_abapgit_ajson~set(
iv_path = lv_path
iv_val = parse( lv_val ) ).
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.
zif_abapgit_ajson~set_string(
iv_path = lv_path
iv_val = lv_val ).
ENDIF.
ri_json = me.
ENDMETHOD.
METHOD zif_abapgit_ajson~set_boolean. METHOD zif_abapgit_ajson~set_boolean.
ri_json = me. ri_json = me.
@ -733,7 +853,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
rv_json = lcl_json_serializer=>stringify( rv_json = lcl_json_serializer=>stringify(
it_json_tree = mt_json_tree it_json_tree = mt_json_tree
iv_keep_item_order = mv_keep_item_order iv_keep_item_order = ms_opts-keep_item_order
iv_indent = iv_indent ). iv_indent = iv_indent ).
ENDMETHOD. ENDMETHOD.
@ -777,7 +897,7 @@ CLASS zcl_abapgit_ajson IMPLEMENTATION.
ls_new_node-name = ls_split_path-name. ls_new_node-name = ls_split_path-name.
ls_new_node-type = zif_abapgit_ajson=>node_type-array. ls_new_node-type = zif_abapgit_ajson=>node_type-array.
IF mv_keep_item_order = abap_true AND ls_deleted_node IS NOT INITIAL. IF ms_opts-keep_item_order = abap_true AND ls_deleted_node IS NOT INITIAL.
ls_new_node-order = ls_deleted_node-order. ls_new_node-order = ls_deleted_node-order.
ENDIF. ENDIF.

View File

@ -1073,8 +1073,7 @@ CLASS lcl_abap_to_json DEFINITION FINAL.
is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL
iv_array_index TYPE i DEFAULT 0 iv_array_index TYPE i DEFAULT 0
ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
iv_keep_item_order TYPE abap_bool DEFAULT abap_false is_opts TYPE zif_abapgit_ajson=>ty_opts OPTIONAL
iv_format_datetime TYPE abap_bool DEFAULT abap_false
iv_item_order TYPE i DEFAULT 0 iv_item_order TYPE i DEFAULT 0
RETURNING RETURNING
VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt
@ -1088,8 +1087,7 @@ CLASS lcl_abap_to_json DEFINITION FINAL.
is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL is_prefix TYPE zif_abapgit_ajson=>ty_path_name OPTIONAL
iv_array_index TYPE i DEFAULT 0 iv_array_index TYPE i DEFAULT 0
ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL ii_custom_mapping TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
iv_keep_item_order TYPE abap_bool DEFAULT abap_false is_opts TYPE zif_abapgit_ajson=>ty_opts OPTIONAL
iv_format_datetime TYPE abap_bool DEFAULT abap_false
iv_item_order TYPE i DEFAULT 0 iv_item_order TYPE i DEFAULT 0
RETURNING RETURNING
VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_tt
@ -1226,8 +1224,8 @@ CLASS lcl_abap_to_json IMPLEMENTATION.
CREATE OBJECT lo_converter. CREATE OBJECT lo_converter.
lo_converter->mi_custom_mapping = ii_custom_mapping. lo_converter->mi_custom_mapping = ii_custom_mapping.
lo_converter->mv_keep_item_order = iv_keep_item_order. lo_converter->mv_keep_item_order = is_opts-keep_item_order.
lo_converter->mv_format_datetime = iv_format_datetime. lo_converter->mv_format_datetime = is_opts-format_datetime.
lo_converter->convert_any( lo_converter->convert_any(
EXPORTING EXPORTING
@ -1623,8 +1621,8 @@ CLASS lcl_abap_to_json IMPLEMENTATION.
CREATE OBJECT lo_converter. CREATE OBJECT lo_converter.
lo_converter->mi_custom_mapping = ii_custom_mapping. lo_converter->mi_custom_mapping = ii_custom_mapping.
lo_converter->mv_keep_item_order = iv_keep_item_order. lo_converter->mv_keep_item_order = is_opts-keep_item_order.
lo_converter->mv_format_datetime = iv_format_datetime. lo_converter->mv_format_datetime = is_opts-format_datetime.
lo_converter->insert_value_with_type( lo_converter->insert_value_with_type(
EXPORTING EXPORTING
@ -1689,20 +1687,35 @@ CLASS lcl_abap_to_json IMPLEMENTATION.
ENDCLASS. ENDCLASS.
**********************************************************************
* MUTATOR INTERFACE
**********************************************************************
INTERFACE lif_mutator_runner.
METHODS run
IMPORTING
it_source_tree TYPE zif_abapgit_ajson=>ty_nodes_ts
EXPORTING
et_dest_tree TYPE zif_abapgit_ajson=>ty_nodes_ts
RAISING
zcx_abapgit_ajson_error.
ENDINTERFACE.
********************************************************************** **********************************************************************
* FILTER RUNNER * FILTER RUNNER
********************************************************************** **********************************************************************
CLASS lcl_filter_runner DEFINITION FINAL. CLASS lcl_filter_runner DEFINITION FINAL.
PUBLIC SECTION. PUBLIC SECTION.
METHODS run INTERFACES lif_mutator_runner.
CLASS-METHODS new
IMPORTING IMPORTING
ii_filter TYPE REF TO zif_abapgit_ajson_filter ii_filter TYPE REF TO zif_abapgit_ajson_filter
it_source_tree TYPE zif_abapgit_ajson=>ty_nodes_ts RETURNING
CHANGING VALUE(ro_instance) TYPE REF TO lcl_filter_runner.
ct_dest_tree TYPE zif_abapgit_ajson=>ty_nodes_ts METHODS constructor
RAISING IMPORTING
zcx_abapgit_ajson_error. ii_filter TYPE REF TO zif_abapgit_ajson_filter.
PRIVATE SECTION. PRIVATE SECTION.
DATA mi_filter TYPE REF TO zif_abapgit_ajson_filter. DATA mi_filter TYPE REF TO zif_abapgit_ajson_filter.
@ -1721,14 +1734,20 @@ ENDCLASS.
CLASS lcl_filter_runner IMPLEMENTATION. CLASS lcl_filter_runner IMPLEMENTATION.
METHOD run. METHOD new.
CREATE OBJECT ro_instance EXPORTING ii_filter = ii_filter.
ENDMETHOD.
METHOD constructor.
ASSERT ii_filter IS BOUND. ASSERT ii_filter IS BOUND.
mi_filter = ii_filter. mi_filter = ii_filter.
CLEAR ct_dest_tree. ENDMETHOD.
METHOD lif_mutator_runner~run.
CLEAR et_dest_tree.
GET REFERENCE OF it_source_tree INTO mr_source_tree. GET REFERENCE OF it_source_tree INTO mr_source_tree.
GET REFERENCE OF ct_dest_tree INTO mr_dest_tree. GET REFERENCE OF et_dest_tree INTO mr_dest_tree.
walk( iv_path = '' ). walk( iv_path = '' ).
@ -1788,3 +1807,187 @@ CLASS lcl_filter_runner IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
ENDCLASS. ENDCLASS.
**********************************************************************
* MAPPER RUNNER
**********************************************************************
CLASS lcl_mapper_runner DEFINITION FINAL.
PUBLIC SECTION.
INTERFACES lif_mutator_runner.
CLASS-METHODS new
IMPORTING
ii_mapper TYPE REF TO zif_abapgit_ajson_mapping
RETURNING
VALUE(ro_instance) TYPE REF TO lcl_mapper_runner.
METHODS constructor
IMPORTING
ii_mapper TYPE REF TO zif_abapgit_ajson_mapping.
PRIVATE SECTION.
DATA mi_mapper TYPE REF TO zif_abapgit_ajson_mapping.
DATA mr_source_tree TYPE REF TO zif_abapgit_ajson=>ty_nodes_ts.
DATA mr_dest_tree TYPE REF TO zif_abapgit_ajson=>ty_nodes_ts.
METHODS process_deep_node
IMPORTING
iv_path TYPE string
iv_renamed_path TYPE string
iv_node_type TYPE zif_abapgit_ajson=>ty_node-type
RAISING
zcx_abapgit_ajson_error.
ENDCLASS.
CLASS lcl_mapper_runner IMPLEMENTATION.
METHOD new.
CREATE OBJECT ro_instance EXPORTING ii_mapper = ii_mapper.
ENDMETHOD.
METHOD constructor.
ASSERT ii_mapper IS BOUND.
mi_mapper = ii_mapper.
ENDMETHOD.
METHOD lif_mutator_runner~run.
FIELD-SYMBOLS <root> LIKE LINE OF it_source_tree.
READ TABLE it_source_tree WITH KEY path = `` name = `` ASSIGNING <root>.
IF sy-subrc <> 0 OR NOT ( <root>-type = zif_abapgit_ajson=>node_type-array OR <root>-type = zif_abapgit_ajson=>node_type-object ).
" empty or one-value-only tree
et_dest_tree = it_source_tree.
RETURN.
ENDIF.
CLEAR et_dest_tree.
GET REFERENCE OF it_source_tree INTO mr_source_tree.
GET REFERENCE OF et_dest_tree INTO mr_dest_tree.
INSERT <root> INTO TABLE et_dest_tree.
process_deep_node(
iv_path = `/`
iv_renamed_path = `/`
iv_node_type = <root>-type ).
ENDMETHOD.
METHOD process_deep_node.
FIELD-SYMBOLS <item> LIKE LINE OF mr_source_tree->*.
DATA ls_renamed_node LIKE <item>.
LOOP AT mr_source_tree->* ASSIGNING <item> WHERE path = iv_path.
ls_renamed_node = <item>.
IF iv_node_type <> zif_abapgit_ajson=>node_type-array.
" don't rename array item names -> they are numeric index
mi_mapper->rename_node(
EXPORTING
is_node = <item>
CHANGING
cv_name = ls_renamed_node-name ).
IF ls_renamed_node-name IS INITIAL.
zcx_abapgit_ajson_error=>raise(
iv_msg = 'Renamed node name cannot be empty'
is_node = <item> ).
ENDIF.
ENDIF.
ls_renamed_node-path = iv_renamed_path.
INSERT ls_renamed_node INTO TABLE mr_dest_tree->*.
IF sy-subrc <> 0. " = 4 ?
zcx_abapgit_ajson_error=>raise(
iv_msg = 'Renamed node has a duplicate'
is_node = ls_renamed_node ).
ENDIF.
" maybe also catch CX_SY_ITAB_DUPLICATE_KEY but secondary keys are not changed here, so not for now
IF <item>-type = zif_abapgit_ajson=>node_type-array OR <item>-type = zif_abapgit_ajson=>node_type-object.
process_deep_node(
iv_path = iv_path && <item>-name && `/`
iv_renamed_path = iv_renamed_path && ls_renamed_node-name && `/`
iv_node_type = <item>-type ).
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
**********************************************************************
* MUTATOR QUEUE
**********************************************************************
CLASS lcl_mutator_queue DEFINITION FINAL.
PUBLIC SECTION.
INTERFACES lif_mutator_runner.
CLASS-METHODS new
RETURNING
VALUE(ro_instance) TYPE REF TO lcl_mutator_queue.
METHODS add
IMPORTING
ii_mutator TYPE REF TO lif_mutator_runner
RETURNING
VALUE(ro_self) TYPE REF TO lcl_mutator_queue.
PRIVATE SECTION.
DATA mt_queue TYPE STANDARD TABLE OF REF TO lif_mutator_runner.
ENDCLASS.
CLASS lcl_mutator_queue IMPLEMENTATION.
METHOD add.
IF ii_mutator IS BOUND.
APPEND ii_mutator TO mt_queue.
ENDIF.
ro_self = me.
ENDMETHOD.
METHOD new.
CREATE OBJECT ro_instance.
ENDMETHOD.
METHOD lif_mutator_runner~run.
DATA li_mutator TYPE REF TO lif_mutator_runner.
DATA lv_qsize TYPE i.
FIELD-SYMBOLS <from> LIKE it_source_tree.
FIELD-SYMBOLS <to> LIKE it_source_tree.
DATA lr_buf TYPE REF TO zif_abapgit_ajson=>ty_nodes_ts.
lv_qsize = lines( mt_queue ).
IF lv_qsize = 0.
et_dest_tree = it_source_tree.
RETURN.
ENDIF.
LOOP AT mt_queue INTO li_mutator.
IF sy-tabix = 1.
ASSIGN it_source_tree TO <from>.
ELSE.
ASSIGN lr_buf->* TO <from>.
ENDIF.
IF sy-tabix = lv_qsize.
ASSIGN et_dest_tree TO <to>.
ELSE.
CREATE DATA lr_buf.
ASSIGN lr_buf->* TO <to>.
ENDIF.
li_mutator->run(
EXPORTING
it_source_tree = <from>
IMPORTING
et_dest_tree = <to> ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.

View File

@ -1976,6 +1976,9 @@ CLASS ltcl_writer_test DEFINITION FINAL
METHODS set_with_type FOR TESTING RAISING zcx_abapgit_ajson_error. METHODS set_with_type FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS overwrite_w_keep_order_touch FOR TESTING RAISING zcx_abapgit_ajson_error. METHODS overwrite_w_keep_order_touch FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS overwrite_w_keep_order_set FOR TESTING RAISING zcx_abapgit_ajson_error. METHODS overwrite_w_keep_order_set FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS setx FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS setx_float FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS setx_complex FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS set_with_type_slice METHODS set_with_type_slice
IMPORTING IMPORTING
@ -3083,6 +3086,112 @@ CLASS ltcl_writer_test IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD setx.
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:1' )->stringify( )
exp = '{"a":1}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a : 1' )->stringify( )
exp = '{"a":1}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:"1"' )->stringify( )
exp = '{"a":"1"}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:abc' )->stringify( )
exp = '{"a":"abc"}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:null' )->stringify( )
exp = '{"a":null}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:true' )->stringify( )
exp = '{"a":true}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:"true"' )->stringify( )
exp = '{"a":"true"}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:false' )->stringify( )
exp = '{"a":false}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a/b:1' )->stringify( )
exp = '{"a":{"b":1}}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/:1' )->stringify( )
exp = '1' ). " Hmmm ?
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( ':1' )->stringify( )
exp = '1' ). " Hmmm ?
" TODO some negative tests like "/a:", ""
ENDMETHOD.
METHOD setx_float.
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:1.123' )->stringify( )
exp = '{"a":1.123}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:00.123' )->stringify( )
exp = '{"a":"00.123"}' ). " hmmm
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:.123' )->stringify( )
exp = '{"a":".123"}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:123.' )->stringify( )
exp = '{"a":"123."}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:1..123' )->stringify( )
exp = '{"a":"1..123"}' ).
ENDMETHOD.
METHOD setx_complex.
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:{"b" : 1}' )->stringify( )
exp = '{"a":{"b":1}}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:{}' )->stringify( )
exp = '{"a":{}}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:[1, 2]' )->stringify( )
exp = '{"a":[1,2]}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>new( )->setx( '/a:[]' )->stringify( )
exp = '{"a":[]}' ).
TRY.
zcl_abapgit_ajson=>new( )->setx( '/a:{"b" : 1' ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_ajson_error.
ENDTRY.
TRY.
zcl_abapgit_ajson=>new( )->setx( '/a:[1, 2' ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_ajson_error.
ENDTRY.
ENDMETHOD.
ENDCLASS. ENDCLASS.
@ -3999,3 +4108,400 @@ CLASS ltcl_filter_test IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
ENDCLASS. ENDCLASS.
**********************************************************************
* MAPPER TEST
**********************************************************************
CLASS ltcl_mapper_test DEFINITION FINAL
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping.
PRIVATE SECTION.
METHODS simple_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS array_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS duplication_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS empty_name_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS trivial FOR TESTING RAISING zcx_abapgit_ajson_error.
ENDCLASS.
CLASS ltcl_mapper_test IMPLEMENTATION.
METHOD zif_abapgit_ajson_mapping~rename_node.
IF cv_name+0(1) = 'a'.
cv_name = to_upper( cv_name ).
ENDIF.
IF cv_name = 'set_this_empty'.
CLEAR cv_name.
ENDIF.
" watch dog for array
IF is_node-index <> 0.
cl_abap_unit_assert=>fail( 'rename must not be called for direct array items' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_abap.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_json.
ENDMETHOD.
METHOD simple_test.
DATA lo_json TYPE REF TO zcl_abapgit_ajson.
DATA lo_json_filtered TYPE REF TO zcl_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
lo_json = zcl_abapgit_ajson=>create_empty( ).
lo_json->set(
iv_path = '/ab'
iv_val = 1 ).
lo_json->set(
iv_path = '/bc'
iv_val = 2 ).
lo_json->set(
iv_path = '/c/ax'
iv_val = 3 ).
lo_json->set(
iv_path = '/c/by'
iv_val = 4 ).
lo_json->set(
iv_path = '/a/ax'
iv_val = 5 ).
lo_json->set(
iv_path = '/a/by'
iv_val = 6 ).
lo_json_filtered = zcl_abapgit_ajson=>create_from(
ii_source_json = lo_json
ii_mapper = me ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |object | | |4' ).
lo_nodes_exp->add( '/ |AB |num |1 | |0' ).
lo_nodes_exp->add( '/ |bc |num |2 | |0' ).
lo_nodes_exp->add( '/ |c |object | | |2' ).
lo_nodes_exp->add( '/c/ |AX |num |3 | |0' ).
lo_nodes_exp->add( '/c/ |by |num |4 | |0' ).
lo_nodes_exp->add( '/ |A |object | | |2' ).
lo_nodes_exp->add( '/A/ |AX |num |5 | |0' ).
lo_nodes_exp->add( '/A/ |by |num |6 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = lo_json_filtered->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD array_test.
DATA lo_json TYPE REF TO zcl_abapgit_ajson.
DATA lo_json_filtered TYPE REF TO zcl_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
lo_json = zcl_abapgit_ajson=>create_empty( ).
lo_json->touch_array( iv_path = '/' ).
lo_json->set(
iv_path = '/1/ab'
iv_val = 1 ).
lo_json->set(
iv_path = '/1/bc'
iv_val = 2 ).
lo_json->set(
iv_path = '/2/ax'
iv_val = 3 ).
lo_json->set(
iv_path = '/2/by'
iv_val = 4 ).
lo_json_filtered = zcl_abapgit_ajson=>create_from(
ii_source_json = lo_json
ii_mapper = me ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |array | | |2' ).
lo_nodes_exp->add( '/ |1 |object | |1|2' ).
lo_nodes_exp->add( '/ |2 |object | |2|2' ).
lo_nodes_exp->add( '/1/ |AB |num |1 | |0' ).
lo_nodes_exp->add( '/1/ |bc |num |2 | |0' ).
lo_nodes_exp->add( '/2/ |AX |num |3 | |0' ).
lo_nodes_exp->add( '/2/ |by |num |4 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = lo_json_filtered->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD duplication_test.
DATA lo_json TYPE REF TO zcl_abapgit_ajson.
DATA lx_err TYPE REF TO zcx_abapgit_ajson_error.
lo_json = zcl_abapgit_ajson=>create_empty( ).
lo_json->set(
iv_path = '/ab'
iv_val = 1 ).
lo_json->set(
iv_path = '/AB'
iv_val = 2 ).
TRY.
zcl_abapgit_ajson=>create_from(
ii_source_json = lo_json
ii_mapper = me ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_ajson_error INTO lx_err.
cl_abap_unit_assert=>assert_char_cp(
act = lx_err->get_text( )
exp = 'Renamed node has a duplicate @/AB' ).
ENDTRY.
ENDMETHOD.
METHOD trivial.
DATA lo_json TYPE REF TO zcl_abapgit_ajson.
DATA lo_json_filtered TYPE REF TO zcl_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
lo_json = zcl_abapgit_ajson=>create_empty( ).
lo_json_filtered = zcl_abapgit_ajson=>create_from(
ii_source_json = lo_json
ii_mapper = me ).
cl_abap_unit_assert=>assert_initial( lo_json_filtered->mt_json_tree ).
lo_json->set(
iv_path = '/'
iv_val = 1 ).
lo_json_filtered = zcl_abapgit_ajson=>create_from(
ii_source_json = lo_json
ii_mapper = me ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |num |1 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = lo_json_filtered->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD empty_name_test.
DATA lo_json TYPE REF TO zcl_abapgit_ajson.
DATA lx_err TYPE REF TO zcx_abapgit_ajson_error.
lo_json = zcl_abapgit_ajson=>create_empty( ).
lo_json->set(
iv_path = '/set_this_empty'
iv_val = 1 ).
TRY.
zcl_abapgit_ajson=>create_from(
ii_source_json = lo_json
ii_mapper = me ).
cl_abap_unit_assert=>fail( ).
CATCH zcx_abapgit_ajson_error INTO lx_err.
cl_abap_unit_assert=>assert_char_cp(
act = lx_err->get_text( )
exp = 'Renamed node name cannot be empty @/set_this_empty' ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
**********************************************************************
* CLONING TEST
**********************************************************************
CLASS ltcl_cloning_test DEFINITION FINAL
FOR TESTING
DURATION SHORT
RISK LEVEL HARMLESS.
PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping.
INTERFACES zif_abapgit_ajson_filter.
PRIVATE SECTION.
METHODS clone_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS filter_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS mapper_test FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS mapper_and_filter FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS opts_copying FOR TESTING RAISING zcx_abapgit_ajson_error.
ENDCLASS.
CLASS ltcl_cloning_test IMPLEMENTATION.
METHOD clone_test.
DATA li_json TYPE REF TO zif_abapgit_ajson.
DATA li_json_new TYPE REF TO zif_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
li_json = zcl_abapgit_ajson=>create_empty( ).
li_json->set(
iv_path = '/ab'
iv_val = 1 ).
li_json->set(
iv_path = '/xy'
iv_val = 2 ).
li_json_new = li_json->clone( ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |object | | |2' ).
lo_nodes_exp->add( '/ |ab |num |1 | |0' ).
lo_nodes_exp->add( '/ |xy |num |2 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = li_json->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
cl_abap_unit_assert=>assert_equals(
act = li_json_new->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
" ensure disconnection
li_json->set(
iv_path = '/ab'
iv_val = 5 ).
cl_abap_unit_assert=>assert_equals(
act = li_json->get_integer( '/ab' )
exp = 5 ).
cl_abap_unit_assert=>assert_equals(
act = li_json_new->get_integer( '/ab' )
exp = 1 ).
ENDMETHOD.
METHOD filter_test.
DATA li_json TYPE REF TO zif_abapgit_ajson.
DATA li_json_new TYPE REF TO zif_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
li_json = zcl_abapgit_ajson=>create_empty( ).
li_json->set(
iv_path = '/ab'
iv_val = 1 ).
li_json->set(
iv_path = '/xy'
iv_val = 2 ).
li_json_new = li_json->filter( me ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |object | | |1' ).
lo_nodes_exp->add( '/ |ab |num |1 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = li_json_new->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD mapper_test.
DATA li_json TYPE REF TO zif_abapgit_ajson.
DATA li_json_new TYPE REF TO zif_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
li_json = zcl_abapgit_ajson=>create_empty( ).
li_json->set(
iv_path = '/ab'
iv_val = 1 ).
li_json->set(
iv_path = '/xy'
iv_val = 2 ).
li_json_new = li_json->map( me ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |object | | |2' ).
lo_nodes_exp->add( '/ |AB |num |1 | |0' ).
lo_nodes_exp->add( '/ |xy |num |2 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = li_json_new->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~rename_node.
IF cv_name+0(1) = 'a'.
cv_name = to_upper( cv_name ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_abap.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_json.
ENDMETHOD.
METHOD zif_abapgit_ajson_filter~keep_node.
rv_keep = boolc( is_node-name IS INITIAL OR is_node-name+0(1) <> 'x' ).
ENDMETHOD.
METHOD mapper_and_filter.
DATA li_json TYPE REF TO zif_abapgit_ajson.
DATA li_json_new TYPE REF TO zif_abapgit_ajson.
DATA lo_nodes_exp TYPE REF TO lcl_nodes_helper.
li_json = zcl_abapgit_ajson=>new( ).
li_json->set(
iv_path = '/ab'
iv_val = 1 ).
li_json->set(
iv_path = '/bc'
iv_val = 2 ).
li_json->set(
iv_path = '/xy'
iv_val = 3 ).
li_json_new = zcl_abapgit_ajson=>create_from(
ii_source_json = li_json
ii_filter = me
ii_mapper = me ).
CREATE OBJECT lo_nodes_exp.
lo_nodes_exp->add( ' | |object | | |2' ).
lo_nodes_exp->add( '/ |AB |num |1 | |0' ).
lo_nodes_exp->add( '/ |bc |num |2 | |0' ).
cl_abap_unit_assert=>assert_equals(
act = li_json_new->mt_json_tree
exp = lo_nodes_exp->sorted( ) ).
ENDMETHOD.
METHOD opts_copying.
DATA li_json TYPE REF TO zif_abapgit_ajson.
DATA li_json_new TYPE REF TO zif_abapgit_ajson.
li_json = zcl_abapgit_ajson=>new( )->keep_item_order( ).
li_json->set(
iv_path = '/ab'
iv_val = 1 ).
li_json_new = li_json->clone( ).
cl_abap_unit_assert=>assert_equals(
act = li_json_new->opts( )-keep_item_order
exp = abap_true ).
ENDMETHOD.
ENDCLASS.

View File

@ -4,7 +4,16 @@ CLASS zcl_abapgit_ajson_mapping DEFINITION
CREATE PUBLIC. CREATE PUBLIC.
PUBLIC SECTION. PUBLIC SECTION.
CLASS-METHODS create_camel_case
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 IMPORTING
it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields OPTIONAL it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields OPTIONAL
iv_first_json_upper TYPE abap_bool DEFAULT abap_true iv_first_json_upper TYPE abap_bool DEFAULT abap_true
@ -23,12 +32,38 @@ CLASS zcl_abapgit_ajson_mapping DEFINITION
RETURNING RETURNING
VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping. VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping.
CLASS-METHODS create_field_mapping CLASS-METHODS create_field_mapping " DEPRECATED
IMPORTING IMPORTING
it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields it_mapping_fields TYPE zif_abapgit_ajson_mapping=>ty_mapping_fields
RETURNING RETURNING
VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping. VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping.
CLASS-METHODS create_rename
IMPORTING
it_rename_map TYPE zif_abapgit_ajson_mapping=>tty_rename_map
iv_rename_by TYPE i DEFAULT rename_by-attr_name
RETURNING
VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping.
CLASS-METHODS create_compound_mapper
IMPORTING
ii_mapper1 TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
ii_mapper2 TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
ii_mapper3 TYPE REF TO zif_abapgit_ajson_mapping OPTIONAL
it_more TYPE zif_abapgit_ajson_mapping=>ty_table_of OPTIONAL
RETURNING
VALUE(ri_mapping) TYPE REF TO zif_abapgit_ajson_mapping.
CLASS-METHODS create_to_snake_case
RETURNING
VALUE(ri_mapping) TYPE REF TO zif_abapgit_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 zif_abapgit_ajson_mapping.
PROTECTED SECTION. PROTECTED SECTION.
PRIVATE SECTION. PRIVATE SECTION.
@ -67,6 +102,21 @@ CLASS zcl_abapgit_ajson_mapping IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD create_compound_mapper.
DATA lt_queue TYPE zif_abapgit_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_upper_case. METHOD create_upper_case.
@ -75,4 +125,28 @@ CLASS zcl_abapgit_ajson_mapping IMPLEMENTATION.
it_mapping_fields = it_mapping_fields. it_mapping_fields = it_mapping_fields.
ENDMETHOD. 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_snake_case.
CREATE OBJECT ri_mapping TYPE lcl_to_snake.
ENDMETHOD.
METHOD create_to_camel_case.
CREATE OBJECT ri_mapping TYPE lcl_to_camel
EXPORTING
iv_first_json_upper = iv_first_json_upper.
ENDMETHOD.
ENDCLASS. ENDCLASS.

View File

@ -3,9 +3,6 @@ CLASS lcl_mapping_fields DEFINITION.
PUBLIC SECTION. PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping. INTERFACES zif_abapgit_ajson_mapping.
ALIASES to_abap FOR zif_abapgit_ajson_mapping~to_abap.
ALIASES to_json FOR zif_abapgit_ajson_mapping~to_json.
METHODS constructor METHODS constructor
IMPORTING IMPORTING
it_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields OPTIONAL. it_mapping_fields TYPE zif_abapgit_ajson_mapping~ty_mapping_fields OPTIONAL.
@ -17,6 +14,23 @@ CLASS lcl_mapping_fields DEFINITION.
ENDCLASS. ENDCLASS.
CLASS lcl_rename DEFINITION.
PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping.
METHODS constructor
IMPORTING
it_rename_map TYPE zif_abapgit_ajson_mapping~tty_rename_map
iv_rename_by TYPE i.
PROTECTED SECTION.
PRIVATE SECTION.
DATA mt_rename_map TYPE zif_abapgit_ajson_mapping~tty_rename_map.
DATA mv_rename_by TYPE i.
ENDCLASS.
CLASS lcl_mapping_to_upper DEFINITION. CLASS lcl_mapping_to_upper DEFINITION.
@ -69,3 +83,34 @@ CLASS lcl_mapping_camel DEFINITION.
DATA mi_mapping_fields TYPE REF TO zif_abapgit_ajson_mapping. DATA mi_mapping_fields TYPE REF TO zif_abapgit_ajson_mapping.
ENDCLASS. ENDCLASS.
CLASS lcl_compound_mapper DEFINITION.
PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping.
METHODS constructor
IMPORTING
it_queue TYPE zif_abapgit_ajson_mapping=>ty_table_of.
PROTECTED SECTION.
PRIVATE SECTION.
DATA mt_queue TYPE zif_abapgit_ajson_mapping=>ty_table_of.
ENDCLASS.
CLASS lcl_to_snake DEFINITION.
PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping.
ENDCLASS.
CLASS lcl_to_camel DEFINITION.
PUBLIC SECTION.
INTERFACES zif_abapgit_ajson_mapping.
METHODS constructor
IMPORTING
iv_first_json_upper TYPE abap_bool.
PRIVATE SECTION.
DATA mv_first_json_upper TYPE abap_bool.
ENDCLASS.

View File

@ -1,4 +1,4 @@
CLASS lcl_mapping_fields IMPLEMENTATION. CLASS lcl_mapping_fields IMPLEMENTATION. "DEPRECATED
METHOD constructor. METHOD constructor.
@ -41,9 +41,58 @@ CLASS lcl_mapping_fields IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~rename_node.
ENDMETHOD.
ENDCLASS. ENDCLASS.
CLASS lcl_rename IMPLEMENTATION.
METHOD constructor.
mt_rename_map = it_rename_map.
mv_rename_by = iv_rename_by.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_abap.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_json.
ENDMETHOD.
METHOD zif_abapgit_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 zcl_abapgit_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 zcl_abapgit_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 zcl_abapgit_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. CLASS lcl_mapping_to_upper IMPLEMENTATION.
@ -76,6 +125,11 @@ CLASS lcl_mapping_to_upper IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~rename_node.
cv_name = to_upper( cv_name ).
ENDMETHOD.
ENDCLASS. ENDCLASS.
@ -111,11 +165,16 @@ CLASS lcl_mapping_to_lower IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~rename_node.
cv_name = to_lower( cv_name ).
ENDMETHOD.
ENDCLASS. ENDCLASS.
CLASS lcl_mapping_camel IMPLEMENTATION. CLASS lcl_mapping_camel IMPLEMENTATION. "DEPRECATED
METHOD constructor. METHOD constructor.
@ -179,5 +238,104 @@ CLASS lcl_mapping_camel IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~rename_node.
ENDMETHOD.
ENDCLASS.
CLASS lcl_compound_mapper IMPLEMENTATION.
METHOD constructor.
mt_queue = it_queue.
ENDMETHOD.
METHOD zif_abapgit_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 zif_abapgit_ajson_mapping~to_abap.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_json.
ENDMETHOD.
ENDCLASS.
CLASS lcl_to_snake IMPLEMENTATION.
METHOD zif_abapgit_ajson_mapping~rename_node.
REPLACE ALL OCCURRENCES OF REGEX `([a-z])([A-Z])` IN cv_name WITH `$1_$2`.
cv_name = to_lower( cv_name ).
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_abap.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_json.
ENDMETHOD.
ENDCLASS.
CLASS lcl_to_camel IMPLEMENTATION.
METHOD constructor.
mv_first_json_upper = iv_first_json_upper.
ENDMETHOD.
METHOD zif_abapgit_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 zif_abapgit_ajson_mapping~to_abap.
ENDMETHOD.
METHOD zif_abapgit_ajson_mapping~to_json.
ENDMETHOD.
ENDCLASS. ENDCLASS.

View File

@ -1,4 +1,4 @@
CLASS ltcl_camel_case DEFINITION FINAL FOR TESTING CLASS ltcl_test_mappers DEFINITION FINAL FOR TESTING
DURATION SHORT DURATION SHORT
RISK LEVEL HARMLESS. RISK LEVEL HARMLESS.
@ -11,10 +11,21 @@ CLASS ltcl_camel_case DEFINITION FINAL FOR TESTING
to_json_nested_table FOR TESTING RAISING zcx_abapgit_ajson_error, to_json_nested_table FOR TESTING RAISING zcx_abapgit_ajson_error,
to_json_first_lower FOR TESTING RAISING zcx_abapgit_ajson_error. to_json_first_lower FOR TESTING RAISING zcx_abapgit_ajson_error.
METHODS:
to_snake FOR TESTING RAISING zcx_abapgit_ajson_error,
to_camel FOR TESTING RAISING zcx_abapgit_ajson_error,
to_camel_1st_upper FOR TESTING RAISING zcx_abapgit_ajson_error,
rename_by_attr FOR TESTING RAISING zcx_abapgit_ajson_error,
rename_by_path FOR TESTING RAISING zcx_abapgit_ajson_error,
rename_by_pattern FOR TESTING RAISING zcx_abapgit_ajson_error,
compound_mapper FOR TESTING RAISING zcx_abapgit_ajson_error,
test_to_upper FOR TESTING RAISING zcx_abapgit_ajson_error,
test_to_lower FOR TESTING RAISING zcx_abapgit_ajson_error.
ENDCLASS. ENDCLASS.
CLASS ltcl_camel_case IMPLEMENTATION. CLASS ltcl_test_mappers IMPLEMENTATION.
METHOD from_json_to_json. METHOD from_json_to_json.
@ -175,6 +186,165 @@ CLASS ltcl_camel_case IMPLEMENTATION.
ENDMETHOD. ENDMETHOD.
METHOD test_to_upper.
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"a":1,"b":{"c":2}}' )
ii_mapper = zcl_abapgit_ajson_mapping=>create_upper_case( ) )->stringify( )
exp = '{"A":1,"B":{"C":2}}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>parse( '{"a":1,"b":{"c":2}}'
)->map( zcl_abapgit_ajson_mapping=>create_upper_case( )
)->stringify( )
exp = '{"A":1,"B":{"C":2}}' ).
ENDMETHOD.
METHOD test_to_lower.
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"A":1,"B":{"C":2}}' )
ii_mapper = zcl_abapgit_ajson_mapping=>create_lower_case( ) )->stringify( )
exp = '{"a":1,"b":{"c":2}}' ).
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>parse( '{"A":1,"B":{"C":2}}'
)->map( zcl_abapgit_ajson_mapping=>create_lower_case( )
)->stringify( )
exp = '{"a":1,"b":{"c":2}}' ).
ENDMETHOD.
METHOD rename_by_attr.
DATA lt_map TYPE zif_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"a":1,"b":{"c":2},"d":{"e":3}}' )
ii_mapper = zcl_abapgit_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 zif_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"a":1,"b":{"a":2},"c":{"a":3}}' )
ii_mapper = zcl_abapgit_ajson_mapping=>create_rename(
it_rename_map = lt_map
iv_rename_by = zcl_abapgit_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 zif_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"andthisnot":1,"b":{"thisone":2},"c":{"a":3}}' )
ii_mapper = zcl_abapgit_ajson_mapping=>create_rename(
it_rename_map = lt_map
iv_rename_by = zcl_abapgit_ajson_mapping=>rename_by-pattern
) )->stringify( )
exp = '{"andthisnot":1,"b":{"x":2},"c":{"a":3}}' ).
ENDMETHOD.
METHOD compound_mapper.
DATA lt_map TYPE zif_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"a":1,"b":{"a":2},"c":{"a":3}}' )
ii_mapper = zcl_abapgit_ajson_mapping=>create_compound_mapper(
ii_mapper1 = zcl_abapgit_ajson_mapping=>create_rename(
it_rename_map = lt_map
iv_rename_by = zcl_abapgit_ajson_mapping=>rename_by-full_path )
ii_mapper2 = zcl_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"aB":1,"BbC":2,"cD":{"xY":3},"ZZ":4}' )
ii_mapper = zcl_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"a_b":1,"bb_c":2,"c_d":{"x_y":3},"zz":4}' )
ii_mapper = zcl_abapgit_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 = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"a__b":1}' )
ii_mapper = zcl_abapgit_ajson_mapping=>create_to_camel_case( )
)->stringify( )
exp = '{"a_b":1}' ).
ENDMETHOD.
METHOD to_camel_1st_upper.
cl_abap_unit_assert=>assert_equals(
act = zcl_abapgit_ajson=>create_from(
ii_source_json = zcl_abapgit_ajson=>parse( '{"aj_bc":1,"bb_c":2,"c_d":{"xq_yq":3},"zz":4}' )
ii_mapper = zcl_abapgit_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. ENDCLASS.

View File

@ -43,11 +43,14 @@ public section.
importing importing
!IV_MSG type STRING !IV_MSG type STRING
!IV_LOCATION type STRING optional !IV_LOCATION type STRING optional
!IS_NODE type ANY optional
raising raising
zcx_abapgit_ajson_error . zcx_abapgit_ajson_error .
methods set_location methods SET_LOCATION
importing importing
iv_location type string. !IV_LOCATION type STRING optional
!IS_NODE type ANY optional
preferred parameter IV_LOCATION .
protected section. protected section.
private section. private section.
types: types:
@ -64,7 +67,7 @@ ENDCLASS.
CLASS zcx_abapgit_ajson_error IMPLEMENTATION. CLASS zcx_abapgit_ajson_error IMPLEMENTATION.
method CONSTRUCTOR. method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR CALL METHOD SUPER->CONSTRUCTOR
EXPORTING EXPORTING
PREVIOUS = PREVIOUS PREVIOUS = PREVIOUS
@ -82,51 +85,53 @@ if textid is initial.
else. else.
IF_T100_MESSAGE~T100KEY = TEXTID. IF_T100_MESSAGE~T100KEY = TEXTID.
endif. endif.
endmethod. endmethod.
method raise. method raise.
data ls_msg type ty_message_parts. data lx type ref to zcx_abapgit_ajson_error.
data lv_tmp type string.
if iv_location is initial. create object lx exporting message = iv_msg.
lv_tmp = iv_msg. lx->set_location(
else. iv_location = iv_location
lv_tmp = iv_msg && | @{ iv_location }|. is_node = is_node ).
endif. raise exception lx.
ls_msg = lv_tmp.
raise exception type zcx_abapgit_ajson_error
exporting
textid = zcx_ajson_error
message = iv_msg
location = iv_location
a1 = ls_msg-a1
a2 = ls_msg-a2
a3 = ls_msg-a3
a4 = ls_msg-a4.
endmethod. endmethod.
method set_location. method set_location.
data ls_msg type ty_message_parts. data ls_msg type ty_message_parts.
data lv_location type string.
data lv_tmp type string. data lv_tmp type string.
field-symbols <path> type string.
field-symbols <name> type string.
if iv_location is initial. if iv_location is not initial.
lv_tmp = message. lv_location = iv_location.
else. elseif is_node is not initial.
lv_tmp = message && | @{ iv_location }|. 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. endif.
if lv_location is not initial.
lv_tmp = message && | @{ lv_location }|.
else.
lv_tmp = message.
endif.
ls_msg = lv_tmp. ls_msg = lv_tmp.
location = iv_location. location = lv_location.
a1 = ls_msg-a1. a1 = ls_msg-a1.
a2 = ls_msg-a2. a2 = ls_msg-a2.
a3 = ls_msg-a3. a3 = ls_msg-a3.
a4 = ls_msg-a4. a4 = ls_msg-a4.
endmethod. endmethod.
ENDCLASS. ENDCLASS.

View File

@ -8,6 +8,7 @@ class ltcl_error definition
methods raise for testing. methods raise for testing.
methods raise_w_location for testing. methods raise_w_location for testing.
methods raise_w_node for testing.
methods set_location for testing. methods set_location for testing.
endclass. endclass.
@ -50,6 +51,26 @@ class ltcl_error implementation.
endmethod. endmethod.
method raise_w_node.
data lx type ref to zcx_abapgit_ajson_error.
data ls_node type zif_abapgit_ajson=>ty_node.
ls_node-path = '/x/'.
ls_node-name = 'y'.
try.
zcx_abapgit_ajson_error=>raise( iv_msg = 'a'
is_node = ls_node ).
cl_abap_unit_assert=>fail( ).
catch zcx_abapgit_ajson_error into lx.
cl_abap_unit_assert=>assert_equals(
exp = 'a @/x/y'
act = lx->get_text( ) ).
endtry.
endmethod.
method set_location. method set_location.
data lx type ref to zcx_abapgit_ajson_error. data lx type ref to zcx_abapgit_ajson_error.

View File

@ -48,6 +48,27 @@ INTERFACE zif_abapgit_ajson
DATA mt_json_tree TYPE ty_nodes_ts READ-ONLY. DATA mt_json_tree TYPE ty_nodes_ts READ-ONLY.
" CLONING
METHODS clone
RETURNING
VALUE(ri_json) TYPE REF TO zif_abapgit_ajson
RAISING
zcx_abapgit_ajson_error.
METHODS filter
IMPORTING
ii_filter TYPE REF TO zif_abapgit_ajson_filter
RETURNING
VALUE(ri_json) TYPE REF TO zif_abapgit_ajson
RAISING
zcx_abapgit_ajson_error.
METHODS map
IMPORTING
ii_mapper TYPE REF TO zif_abapgit_ajson_mapping
RETURNING
VALUE(ri_json) TYPE REF TO zif_abapgit_ajson
RAISING
zcx_abapgit_ajson_error.
" METHODS " METHODS
METHODS freeze. METHODS freeze.
@ -166,6 +187,14 @@ INTERFACE zif_abapgit_ajson
RAISING RAISING
zcx_abapgit_ajson_error. zcx_abapgit_ajson_error.
METHODS setx
IMPORTING
iv_param TYPE string
RETURNING
VALUE(ri_json) TYPE REF TO zif_abapgit_ajson
RAISING
zcx_abapgit_ajson_error.
METHODS set_boolean METHODS set_boolean
IMPORTING IMPORTING
iv_path TYPE string iv_path TYPE string

View File

@ -2,7 +2,7 @@ INTERFACE zif_abapgit_ajson_mapping
PUBLIC. PUBLIC.
TYPES: TYPES:
BEGIN OF ty_mapping_field, BEGIN OF ty_mapping_field, " deprecated, will be removed
abap TYPE string, abap TYPE string,
json TYPE string, json TYPE string,
END OF ty_mapping_field, END OF ty_mapping_field,
@ -10,18 +10,35 @@ INTERFACE zif_abapgit_ajson_mapping
WITH UNIQUE SORTED KEY abap COMPONENTS abap WITH UNIQUE SORTED KEY abap COMPONENTS abap
WITH UNIQUE SORTED KEY json COMPONENTS json. WITH UNIQUE SORTED KEY json COMPONENTS json.
METHODS to_abap 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 zif_abapgit_ajson_mapping.
METHODS to_abap " deprecated, will be removed
IMPORTING IMPORTING
!iv_path TYPE string !iv_path TYPE string
!iv_name TYPE string !iv_name TYPE string
RETURNING RETURNING
VALUE(rv_result) TYPE string. VALUE(rv_result) TYPE string.
METHODS to_json METHODS to_json " deprecated, will be removed
IMPORTING IMPORTING
!iv_path TYPE string !iv_path TYPE string
!iv_name TYPE string !iv_name TYPE string
RETURNING RETURNING
VALUE(rv_result) TYPE string. VALUE(rv_result) TYPE string.
METHODS rename_node
IMPORTING
!is_node TYPE zif_abapgit_ajson=>ty_node
CHANGING
!cv_name TYPE zif_abapgit_ajson=>ty_node-name.
ENDINTERFACE. ENDINTERFACE.

View File

@ -88,7 +88,7 @@ ENDCLASS.
CLASS ZCL_ABAPGIT_JSON_HANDLER IMPLEMENTATION. CLASS zcl_abapgit_json_handler IMPLEMENTATION.
METHOD deserialize. METHOD deserialize.
@ -248,7 +248,7 @@ CLASS ZCL_ABAPGIT_JSON_HANDLER IMPLEMENTATION.
lo_mapping = zcl_abapgit_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ). lo_mapping = zcl_abapgit_ajson_mapping=>create_camel_case( iv_first_json_upper = abap_false ).
lo_ajson = zcl_abapgit_ajson=>create_empty( lo_mapping ). lo_ajson = zcl_abapgit_ajson=>create_empty( ii_custom_mapping = lo_mapping ).
lo_ajson->keep_item_order( ). lo_ajson->keep_item_order( ).
lo_ajson->set( lo_ajson->set(

View File

@ -108,6 +108,7 @@
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_json_to_abap", "method": "to_abap_array_of_arrays", "note": "Expected table to contain 2 rows, got 4"}, {"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_json_to_abap", "method": "to_abap_array_of_arrays", "note": "Expected table to contain 2 rows, got 4"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "set_tab_hashed", "note": "Expected table to contain 4 rows, got 3"}, {"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "set_tab_hashed", "note": "Expected table to contain 4 rows, got 3"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_integrated", "method": "reader", "note": "Path not found @/false, keywords?"}, {"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_integrated", "method": "reader", "note": "Path not found @/false, keywords?"},
{"object": "ZCL_ABAPGIT_AJSON", "class": "ltcl_writer_test", "method": "setx_float", "note": "DecFloat34"},
{"object": "ZCL_ABAPGIT_REQUIREMENT_HELPER", "class": "ltcl_lower_release", "method": "empty_patch", "note": "Void type: CVERS_SDU"}, {"object": "ZCL_ABAPGIT_REQUIREMENT_HELPER", "class": "ltcl_lower_release", "method": "empty_patch", "note": "Void type: CVERS_SDU"},
{"object": "ZCL_ABAPGIT_REQUIREMENT_HELPER", "class": "ltcl_lower_release", "method": "lower_patch", "note": "Void type: CVERS_SDU"}, {"object": "ZCL_ABAPGIT_REQUIREMENT_HELPER", "class": "ltcl_lower_release", "method": "lower_patch", "note": "Void type: CVERS_SDU"},