-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathzcl_ce_metadata_service.clas.abap
More file actions
217 lines (176 loc) · 7.13 KB
/
Copy pathzcl_ce_metadata_service.clas.abap
File metadata and controls
217 lines (176 loc) · 7.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
CLASS zcl_ce_metadata_service DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES if_rap_query_provider.
PROTECTED SECTION.
PRIVATE SECTION.
TYPES: BEGIN OF ty_metadata_result,
request_id TYPE c LENGTH 36,
request_type TYPE c LENGTH 20,
object_names TYPE string,
status TYPE c LENGTH 10,
result_data TYPE string,
error_message TYPE string,
created_at TYPE dats,
created_time TYPE tims,
END OF ty_metadata_result,
ty_metadata_results TYPE TABLE OF ty_metadata_result.
METHODS: get_cds_metadata
IMPORTING iv_object_names TYPE string
RETURNING VALUE(rv_result) TYPE string,
get_table_metadata
IMPORTING iv_object_names TYPE string
RETURNING VALUE(rv_result) TYPE string,
parse_object_names
IMPORTING iv_names TYPE string
RETURNING VALUE(rt_names) TYPE zcl_metadata_service=>ddlname_tab.
ENDCLASS.
CLASS zcl_ce_metadata_service IMPLEMENTATION.
METHOD if_rap_query_provider~select.
DATA: lt_result TYPE ty_metadata_results.
" Get filter values
DATA(lt_filter_conditions) = io_request->get_filter( )->get_as_ranges( ).
" Process each request
DATA: lv_request_type TYPE string,
lv_object_names TYPE string.
" Read filter values
READ TABLE lt_filter_conditions WITH KEY name = 'REQUEST_TYPE' INTO DATA(ls_request_type).
IF sy-subrc = 0 AND lines( ls_request_type-range ) > 0.
lv_request_type = ls_request_type-range[ 1 ]-low.
ENDIF.
READ TABLE lt_filter_conditions WITH KEY name = 'OBJECT_NAMES' INTO DATA(ls_object_names).
IF sy-subrc = 0 AND lines( ls_object_names-range ) > 0.
lv_object_names = ls_object_names-range[ 1 ]-low.
ENDIF.
" Generate unique request ID
DATA(lv_request_id) = cl_system_uuid=>create_uuid_x16_static( ).
" Create result entry
DATA: ls_result TYPE ty_metadata_result.
ls_result-request_id = lv_request_id.
ls_result-request_type = lv_request_type.
ls_result-object_names = lv_object_names.
ls_result-created_at = sy-datum.
ls_result-created_time = sy-uzeit.
" Process based on request type
CASE lv_request_type.
WHEN 'CDS_SOURCE'.
TRY.
ls_result-result_data = get_cds_metadata( lv_object_names ).
ls_result-status = 'SUCCESS'.
CATCH cx_root INTO DATA(lx_cds_error).
ls_result-status = 'ERROR'.
ls_result-error_message = lx_cds_error->get_text( ).
ENDTRY.
WHEN 'TABLE_FIELDS'.
TRY.
ls_result-result_data = get_table_metadata( lv_object_names ).
ls_result-status = 'SUCCESS'.
CATCH cx_root INTO DATA(lx_table_error).
ls_result-status = 'ERROR'.
ls_result-error_message = lx_table_error->get_text( ).
ENDTRY.
WHEN OTHERS.
ls_result-status = 'ERROR'.
ls_result-error_message = 'Invalid request type. Use CDS_SOURCE or TABLE_FIELDS'.
ENDCASE.
APPEND ls_result TO lt_result.
" Set total number of records if requested
IF io_request->is_total_numb_of_rec_requested( ).
io_response->set_total_number_of_records( lines( lt_result ) ).
ENDIF.
" Apply paging if requested
DATA(ls_paging) = io_request->get_paging( ).
IF ls_paging IS NOT INITIAL.
DATA(lv_offset) = ls_paging->get_offset( ).
DATA(lv_page_size) = ls_paging->get_page_size( ).
IF lv_page_size <> if_rap_query_paging=>page_size_unlimited.
" Apply manual paging
DATA: lt_paged_result TYPE ty_metadata_results.
LOOP AT lt_result INTO DATA(ls_entry).
IF sy-tabix > lv_offset.
APPEND ls_entry TO lt_paged_result.
IF lines( lt_paged_result ) >= lv_page_size.
EXIT.
ENDIF.
ENDIF.
ENDLOOP.
lt_result = lt_paged_result.
ENDIF.
ENDIF.
" Return result
io_response->set_data( lt_result ).
ENDMETHOD.
METHOD get_cds_metadata.
DATA: lo_metadata TYPE REF TO zcl_metadata_service.
CREATE OBJECT lo_metadata.
" Parse object names from JSON
DATA(lt_cds_names) = parse_object_names( iv_object_names ).
" Get CDS sources
DATA(lt_sources) = lo_metadata->get_cds_source( lt_cds_names ).
" Convert to JSON
DATA: lv_json TYPE string.
lv_json = '['.
LOOP AT lt_sources INTO DATA(ls_source).
IF sy-tabix > 1.
lv_json = lv_json && ','.
ENDIF.
" Escape special characters in source code
DATA(lv_escaped_source) = ls_source-source.
REPLACE ALL OCCURRENCES OF '\' IN lv_escaped_source WITH '\\'.
REPLACE ALL OCCURRENCES OF '"' IN lv_escaped_source WITH '\"'.
REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>cr_lf IN lv_escaped_source WITH '\n'.
REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN lv_escaped_source WITH '\n'.
lv_json = lv_json && '{"cds_name":"' && ls_source-cds_name && '","source":"' && lv_escaped_source && '"}'.
ENDLOOP.
lv_json = lv_json && ']'.
rv_result = lv_json.
ENDMETHOD.
METHOD get_table_metadata.
DATA: lo_metadata TYPE REF TO zcl_metadata_service.
CREATE OBJECT lo_metadata.
" Parse object names from JSON
DATA(lt_table_names) = parse_object_names( iv_object_names ).
" Get table fields
DATA(lt_fields) = lo_metadata->get_table_stru_fields( lt_table_names ).
" Convert to JSON
DATA: lv_json TYPE string.
lv_json = '['.
LOOP AT lt_fields INTO DATA(ls_field).
IF sy-tabix > 1.
lv_json = lv_json && ','.
ENDIF.
lv_json = lv_json && '{"tab_name":"' && ls_field-tab_name && '",'
&& '"field_name":"' && ls_field-field_name && '",'
&& '"key_flag":"' && ls_field-key_flag && '",'
&& '"rollname":"' && ls_field-rollname && '",'
&& '"domain_name":"' && ls_field-domain_name && '",'
&& '"abap_dtype":"' && ls_field-abap_dtype && '",'
&& '"db_dtype":"' && ls_field-db_dtype && '",'
&& '"length":"' && ls_field-length && '",'
&& '"decimals":"' && ls_field-decimals && '",'
&& '"description":"' && ls_field-description && '"}'.
ENDLOOP.
lv_json = lv_json && ']'.
rv_result = lv_json.
ENDMETHOD.
METHOD parse_object_names.
" Simple JSON array parser for ["name1","name2","name3"]
DATA: lv_names TYPE string.
lv_names = iv_names.
" Remove brackets and quotes
REPLACE ALL OCCURRENCES OF '[' IN lv_names WITH ''.
REPLACE ALL OCCURRENCES OF ']' IN lv_names WITH ''.
REPLACE ALL OCCURRENCES OF '"' IN lv_names WITH ''.
" Split by comma and add to table
SPLIT lv_names AT ',' INTO TABLE DATA(lt_name_strings).
LOOP AT lt_name_strings INTO DATA(lv_name).
" Trim spaces
CONDENSE lv_name.
IF lv_name IS NOT INITIAL.
APPEND lv_name TO rt_names.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.