Skip to content

Commit feb450b

Browse files
authored
Array iterator (sbcgua#210)
* iterate array * Move to utils
1 parent ee86d0b commit feb450b

File tree

6 files changed

+361
-24
lines changed

6 files changed

+361
-24
lines changed

src/core/zcl_ajson.clas.abap

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
class zcl_ajson definition
22
public
3-
create public .
3+
create public.
44

55
public section.
66

7-
interfaces zif_ajson .
7+
interfaces zif_ajson.
88

99
aliases:
1010
is_empty for zif_ajson~is_empty,
@@ -57,7 +57,7 @@ class zcl_ajson definition
5757
returning
5858
value(ro_instance) type ref to zcl_ajson
5959
raising
60-
zcx_ajson_error .
60+
zcx_ajson_error.
6161

6262
class-methods create_empty " Might be deprecated, prefer using new( ) or create object
6363
importing
@@ -77,13 +77,14 @@ class zcl_ajson definition
7777
returning
7878
value(ro_instance) type ref to zcl_ajson
7979
raising
80-
zcx_ajson_error .
80+
zcx_ajson_error.
8181

8282
methods constructor
8383
importing
8484
iv_keep_item_order type abap_bool default abap_false
8585
iv_format_datetime type abap_bool default abap_true
8686
iv_to_abap_corresponding_only type abap_bool default abap_false.
87+
8788
class-methods new
8889
importing
8990
iv_keep_item_order type abap_bool default abap_false
@@ -92,6 +93,12 @@ class zcl_ajson definition
9293
returning
9394
value(ro_instance) type ref to zcl_ajson.
9495

96+
class-methods normalize_path
97+
importing
98+
iv_path type string
99+
returning
100+
value(rv_path) type string.
101+
95102
protected section.
96103

97104
private section.
@@ -127,7 +134,7 @@ ENDCLASS.
127134

128135

129136

130-
CLASS zcl_ajson IMPLEMENTATION.
137+
CLASS ZCL_AJSON IMPLEMENTATION.
131138

132139

133140
method constructor.
@@ -217,18 +224,14 @@ CLASS zcl_ajson IMPLEMENTATION.
217224

218225
method get_item.
219226

220-
field-symbols <item> like line of mt_json_tree.
221227
data ls_path_name type zif_ajson_types=>ty_path_name.
222228
ls_path_name = lcl_utils=>split_path( iv_path ).
223229

224230
read table mt_json_tree
225-
assigning <item>
231+
reference into rv_item
226232
with key
227233
path = ls_path_name-path
228234
name = ls_path_name-name.
229-
if sy-subrc = 0.
230-
get reference of <item> into rv_item.
231-
endif.
232235

233236
endmethod.
234237

@@ -242,6 +245,11 @@ CLASS zcl_ajson IMPLEMENTATION.
242245
endmethod.
243246

244247

248+
method normalize_path.
249+
rv_path = lcl_utils=>normalize_path( iv_path ).
250+
endmethod.
251+
252+
245253
method parse.
246254

247255
data lo_parser type ref to lcl_json_parser.
@@ -877,6 +885,11 @@ CLASS zcl_ajson IMPLEMENTATION.
877885

878886
method zif_ajson~slice.
879887

888+
" TODO: idea
889+
" read only mode (for read only jsons or a param)
890+
" which would reuse the original tree, so copy a reference of the tree, presuming that it is not changed
891+
" this will be faster, in particular for array iterations
892+
880893
data lo_section type ref to zcl_ajson.
881894
data ls_item like line of mt_json_tree.
882895
data lv_normalized_path type string.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
interface zif_ajson_iterator
2+
public.
3+
4+
methods has_next
5+
returning
6+
value(rv_yes) type abap_bool.
7+
8+
methods next
9+
returning
10+
value(ri_item) type ref to zif_ajson.
11+
12+
endinterface.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<abapGit version="v1.0.0" serializer="LCL_OBJECT_INTF" serializer_version="v1.0.0">
3+
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
4+
<asx:values>
5+
<VSEOINTERF>
6+
<CLSNAME>ZIF_AJSON_ITERATOR</CLSNAME>
7+
<LANGU>E</LANGU>
8+
<DESCRIPT>AJSON iterator interface</DESCRIPT>
9+
<EXPOSURE>2</EXPOSURE>
10+
<STATE>1</STATE>
11+
<UNICODE>X</UNICODE>
12+
</VSEOINTERF>
13+
</asx:values>
14+
</asx:abap>
15+
</abapGit>

src/libs/zcl_ajson_utilities.clas.abap

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class zcl_ajson_utilities definition
22
public
3-
create public .
3+
create public.
44

55
public section.
66

@@ -19,7 +19,7 @@ class zcl_ajson_utilities definition
1919
!eo_delete type ref to zif_ajson
2020
!eo_change type ref to zif_ajson
2121
raising
22-
zcx_ajson_error .
22+
zcx_ajson_error.
2323
methods merge
2424
importing
2525
!iv_json_a type string optional
@@ -30,15 +30,15 @@ class zcl_ajson_utilities definition
3030
returning
3131
value(ro_json) type ref to zif_ajson
3232
raising
33-
zcx_ajson_error .
33+
zcx_ajson_error.
3434
methods sort
3535
importing
3636
!iv_json type string optional
3737
!io_json type ref to zif_ajson optional
3838
returning
3939
value(rv_sorted) type string
4040
raising
41-
zcx_ajson_error .
41+
zcx_ajson_error.
4242
methods is_equal
4343
importing
4444
!iv_json_a type string optional
@@ -48,17 +48,33 @@ class zcl_ajson_utilities definition
4848
returning
4949
value(rv_yes) type abap_bool
5050
raising
51-
zcx_ajson_error .
51+
zcx_ajson_error.
52+
class-methods iterate_array
53+
importing
54+
ii_json type ref to zif_ajson
55+
iv_path type string
56+
returning
57+
value(ri_iterator) type ref to zif_ajson_iterator
58+
raising
59+
zcx_ajson_error.
60+
class-methods iterate_object
61+
importing
62+
ii_json type ref to zif_ajson
63+
iv_path type string
64+
returning
65+
value(ri_iterator) type ref to zif_ajson_iterator
66+
raising
67+
zcx_ajson_error.
5268

5369
protected section.
5470

5571
private section.
5672

57-
data mo_json_a type ref to zif_ajson .
58-
data mo_json_b type ref to zif_ajson .
59-
data mo_insert type ref to zif_ajson .
60-
data mo_delete type ref to zif_ajson .
61-
data mo_change type ref to zif_ajson .
73+
data mo_json_a type ref to zif_ajson.
74+
data mo_json_b type ref to zif_ajson.
75+
data mo_insert type ref to zif_ajson.
76+
data mo_delete type ref to zif_ajson.
77+
data mo_change type ref to zif_ajson.
6278

6379
methods normalize_input
6480
importing
@@ -67,24 +83,25 @@ class zcl_ajson_utilities definition
6783
returning
6884
value(ro_json) type ref to zif_ajson
6985
raising
70-
zcx_ajson_error .
86+
zcx_ajson_error.
7187
methods diff_a_b
7288
importing
7389
!iv_path type string
7490
raising
75-
zcx_ajson_error .
91+
zcx_ajson_error.
7692
methods diff_b_a
7793
importing
7894
!iv_path type string
7995
!iv_array type abap_bool default abap_false
8096
raising
81-
zcx_ajson_error .
97+
zcx_ajson_error.
8298
methods delete_empty_nodes
8399
importing
84100
!io_json type ref to zif_ajson
85101
!iv_keep_empty_arrays type abap_bool
86102
raising
87-
zcx_ajson_error .
103+
zcx_ajson_error.
104+
88105
ENDCLASS.
89106

90107

@@ -316,6 +333,28 @@ CLASS ZCL_AJSON_UTILITIES IMPLEMENTATION.
316333
endmethod.
317334

318335

336+
method iterate_array.
337+
338+
create object ri_iterator type lcl_node_iterator
339+
exporting
340+
iv_node_type = zif_ajson_types=>node_type-array
341+
ii_json = ii_json
342+
iv_path = iv_path.
343+
344+
endmethod.
345+
346+
347+
method iterate_object.
348+
349+
create object ri_iterator type lcl_node_iterator
350+
exporting
351+
iv_node_type = zif_ajson_types=>node_type-object
352+
ii_json = ii_json
353+
iv_path = iv_path.
354+
355+
endmethod.
356+
357+
319358
method merge.
320359

321360
mo_json_a = normalize_input(
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
**********************************************************************
2+
* ITERATOR
3+
**********************************************************************
4+
5+
class lcl_node_iterator definition final.
6+
public section.
7+
interfaces zif_ajson_iterator.
8+
methods constructor
9+
importing
10+
ii_json type ref to zif_ajson
11+
iv_path type string
12+
iv_node_type type zif_ajson_types=>ty_node_type
13+
raising
14+
zcx_ajson_error.
15+
16+
private section.
17+
data mi_json type ref to zif_ajson.
18+
data mv_node_type type zif_ajson_types=>ty_node_type.
19+
data mv_base_path type string.
20+
data mr_cursor type ref to zif_ajson_types=>ty_node.
21+
data mv_tabix type i.
22+
data mv_has_next type abap_bool.
23+
methods find_first_node.
24+
25+
endclass.
26+
27+
class lcl_node_iterator implementation.
28+
29+
method constructor.
30+
31+
if not ( iv_node_type = zif_ajson_types=>node_type-array or iv_node_type = zif_ajson_types=>node_type-object ).
32+
zcx_ajson_error=>raise( |Iterator can iterate arrays or objects only ("{ iv_node_type }" passed)| ).
33+
endif.
34+
35+
mv_base_path = zcl_ajson=>normalize_path( iv_path ).
36+
mv_node_type = iv_node_type.
37+
mi_json = ii_json.
38+
39+
data lv_node_type like mv_node_type.
40+
lv_node_type = ii_json->get_node_type( mv_base_path ).
41+
42+
if lv_node_type is initial.
43+
zcx_ajson_error=>raise( |Path not found: { iv_path }| ).
44+
elseif mv_node_type = zif_ajson_types=>node_type-array and lv_node_type <> mv_node_type.
45+
zcx_ajson_error=>raise( |Array expected at: { iv_path }| ).
46+
elseif mv_node_type = zif_ajson_types=>node_type-object and lv_node_type <> mv_node_type.
47+
zcx_ajson_error=>raise( |Object expected at: { iv_path }| ).
48+
endif.
49+
50+
find_first_node( ).
51+
52+
endmethod.
53+
54+
method find_first_node.
55+
56+
case mv_node_type.
57+
when zif_ajson_types=>node_type-array.
58+
" path + array index key
59+
loop at mi_json->mt_json_tree reference into mr_cursor using key array_index where path = mv_base_path.
60+
mv_has_next = abap_true.
61+
mv_tabix = sy-tabix.
62+
exit. " first found
63+
endloop.
64+
when zif_ajson_types=>node_type-object.
65+
" regular path + name key
66+
loop at mi_json->mt_json_tree reference into mr_cursor where path = mv_base_path.
67+
mv_has_next = abap_true.
68+
mv_tabix = sy-tabix.
69+
exit. " first found
70+
endloop.
71+
when others.
72+
assert 1 = 0.
73+
endcase.
74+
75+
endmethod.
76+
77+
method zif_ajson_iterator~has_next.
78+
rv_yes = mv_has_next.
79+
endmethod.
80+
81+
method zif_ajson_iterator~next.
82+
83+
if mv_has_next = abap_false.
84+
return.
85+
endif.
86+
87+
ri_item = mi_json->slice( |{ mr_cursor->path }{ mr_cursor->name }| ).
88+
" TODO: improve performance, see comment in slice, maybe reuse read only reference to node_tree
89+
90+
mv_tabix = mv_tabix + 1.
91+
case mv_node_type.
92+
when zif_ajson_types=>node_type-array.
93+
" path + array index key
94+
read table mi_json->mt_json_tree
95+
index mv_tabix using key array_index
96+
reference into mr_cursor.
97+
when zif_ajson_types=>node_type-object.
98+
" regular path + name key
99+
read table mi_json->mt_json_tree
100+
index mv_tabix
101+
reference into mr_cursor.
102+
when others.
103+
assert 1 = 0.
104+
endcase.
105+
mv_has_next = boolc( sy-subrc = 0 and mr_cursor->path = mv_base_path ).
106+
107+
endmethod.
108+
109+
endclass.

0 commit comments

Comments
 (0)