├── .abapgit.xml
├── LICENSE
├── README.md
├── _config.yml
├── docs
└── img
│ └── retrieve_keys.JPG
└── src
├── package.devc.xml
├── zabapfire_cl_firebase.clas.abap
├── zabapfire_cl_firebase.clas.xml
├── zabapfire_cl_firebase_auth.clas.abap
├── zabapfire_cl_firebase_auth.clas.xml
├── zabapfire_cl_firebase_db.clas.abap
├── zabapfire_cl_firebase_db.clas.xml
├── zabapfire_cl_http_util.clas.abap
├── zabapfire_cl_http_util.clas.xml
├── zabapfire_cl_json_deserializer.clas.abap
├── zabapfire_cl_json_deserializer.clas.xml
├── zabapfire_cl_json_node.clas.abap
├── zabapfire_cl_json_node.clas.xml
├── zabapfire_cl_json_serializer.clas.abap
├── zabapfire_cl_json_serializer.clas.xml
├── zabapfire_demo.prog.abap
├── zabapfire_demo.prog.xml
├── zabapfire_msg.msag.xml
├── zcx_abapfire_firebase.clas.abap
├── zcx_abapfire_firebase.clas.xml
├── zcx_abapfire_json.clas.abap
└── zcx_abapfire_json.clas.xml
/.abapgit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | E
6 | /src/
7 | PREFIX
8 |
9 | - /.gitignore
10 | - /LICENSE
11 | - /README.md
12 | - /package.json
13 | - /.travis.yml
14 | - /_config.yml
15 | - /docs/img/retrieve_keys.JPG
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 inquaero
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # ABAPFire #
4 | ABAP Firebase REST API Helper Library
5 |
6 | ## Installation ##
7 |
8 | ### Clone it using abapGit ##
9 |
10 | Install [abapGit](http://larshp.github.io/abapGit/guide-install.html), then clone the repository in a package (e.g. $ABAPFIRE).
11 |
12 | ### Install Google certificate ###
13 |
14 | Install Root CA from [Google Internet Authority G2](https://pki.google.com/) using transaction STRUST in SSL identity ANONYMOUS.
15 |
16 | ## Usage ##
17 |
18 | Program [ZABAPFIRE_DEMO](src/zabapfire_demo.prog.abap) provides usage examples.
19 |
20 | ### Initialize the Application ###
21 |
22 | To initialize the library, just pass to it your firebase configuration:
23 |
24 | ```abap
25 | DATA:
26 | firebase TYPE REF TO zabapfire_cl_firebase,
27 | ls_config TYPE zabapfire_cl_firebase=>ty_firebase_config.
28 |
29 | ls_config-apikey = '[your apikey]'.
30 | ls_config-authdomain = '[your authdomain]'.
31 | ls_config-databaseurl = '[your databaseurl]'.
32 | ls_config-messagingsenderid = '[your messagingsenderid]'.
33 | ls_config-projectid = '[your projectid]'.
34 | ls_config-storagebucket = '[your storagebucket]'.
35 |
36 | firebase = zabapfire_cl_firebase=>initialize_app( ls_config ).
37 | ```
38 |
39 | ### User Authentication ###
40 |
41 | The library support only email and password authentication:
42 |
43 | ```abap
44 | TRY.
45 | firebase->auth->authenticate_with_email(
46 | EXPORTING
47 | email = p_email
48 | password = p_pass ).
49 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
50 | WRITE lcx_firebase->get_text( ).
51 |
52 | ENDTRY.
53 | ```
54 |
55 | ### Retrieve firebase data ###
56 |
57 | ```abap
58 | TRY.
59 | ls_parameters-order_by = 'carrid'.
60 | ls_parameters-equal_to = 'AC'.
61 | firebase->db->get(
62 | EXPORTING
63 | path = p_path
64 | parameters = ls_parameters
65 | IMPORTING
66 | child = lt_abap ).
67 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
68 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
69 | DISPLAY LIKE 'E'.
70 | EXIT.
71 | ENDTRY.
72 |
73 | ```
74 |
75 | If your target ABAP structure contains a column with name $KEY, firebase generated unique keys are saved in this column:
76 |
77 | ```abap
78 | TYPES:
79 | BEGIN OF ty_abap,
80 | $key TYPE string.
81 | INCLUDE STRUCTURE sflight.
82 | TYPES:
83 | END OF ty_abap
84 | ```
85 | 
86 |
87 | For data retrieving, following query parameters are supported:
88 | * **shallow**: Limit the depth of the data returned. If the data at the location is a JSON primitive (string, number, or boolean) its value will simply be returned. If the data snapshot at the location is a JSON object, the values for each key will be truncated to true.
89 | * **orderBy**: Set a sequence order that can be used to filter the data in combination with startAt endAt and equalTo parameters.
90 | * **startAt**: Set an arbitrary starting point.
91 | * **endAt**: Set an arbitrary ending point.
92 | * **equalTo**: Filter on specific value.
93 | * **limitToFirst**: Set a maximum number of children for which to receive data.
94 | * **limitToLast**: Set a maximum number of children for which to receive data in reverse order.
95 |
96 | Refer to official [firebase documentation](https://firebase.google.com/docs/database/rest/retrieve-data) for more info.
97 |
98 | ### Save data to firebase ###
99 |
100 | #### Set ####
101 |
102 | Writes data to firebase Database location.
103 | This will overwrite any data at this location and all child locations.
104 |
105 | ```abap
106 | SELECT * FROM sflight
107 | INTO CORRESPONDING FIELDS OF TABLE lt_abap.
108 | TRY.
109 | firebase->db->set(
110 | EXPORTING
111 | path = p_path
112 | child = lt_abap ).
113 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
114 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
115 | DISPLAY LIKE 'E'.
116 | EXIT.
117 | ENDTRY.
118 | ```
119 |
120 | #### Update ####
121 |
122 | As opposed to the set( ) method, update( ) can be use to selectively update only the referenced properties at the current location (instead of replacing all the child properties at the current location).
123 |
124 |
125 | ```abap
126 | TRY.
127 | firebase->db->update(
128 | EXPORTING
129 | path = p_path
130 | child = lt_abap ).
131 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
132 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
133 | DISPLAY LIKE 'E'.
134 | EXIT.
135 | ENDTRY.
136 | ```
137 |
138 | #### Push ####
139 |
140 | Generates a new child location using a unique key and return the generated unique key.
141 |
142 | ```abap
143 | TRY.
144 | LOOP AT lt_abap ASSIGNING .
145 | -$key = firebase->db->push(
146 | EXPORTING
147 | path = p_path
148 | child = ).
149 | ENDLOOP.
150 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
151 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
152 | DISPLAY LIKE 'E'.
153 | EXIT.
154 | ENDTRY.
155 | ```
156 |
157 | #### Remove ####
158 |
159 | Removes the data at this firebase Database location.
160 |
161 | ```abap
162 | TRY.
163 | firebase->db->remove(
164 | EXPORTING
165 | path = p_path ).
166 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
167 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
168 | DISPLAY LIKE 'E'.
169 | EXIT.
170 | ENDTRY.
171 | ```
172 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-minimal
--------------------------------------------------------------------------------
/docs/img/retrieve_keys.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/alborghetti/ABAPFire/667866effd77c13ce1d2a151bd916a79671cc36e/docs/img/retrieve_keys.JPG
--------------------------------------------------------------------------------
/src/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ABAPFire
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_firebase.clas.abap:
--------------------------------------------------------------------------------
1 | class ZABAPFIRE_CL_FIREBASE definition
2 | public
3 | final
4 | create private .
5 |
6 | public section.
7 |
8 | types:
9 | BEGIN OF ty_firebase_config,
10 | apikey TYPE string,
11 | authdomain TYPE string,
12 | databaseurl TYPE string,
13 | projectid TYPE string,
14 | storagebucket TYPE string,
15 | messagingsenderid TYPE string,
16 | END OF ty_firebase_config .
17 |
18 | data DB type ref to ZABAPFIRE_CL_FIREBASE_DB .
19 | data AUTH type ref to ZABAPFIRE_CL_FIREBASE_AUTH .
20 |
21 | class-methods INITIALIZE_APP
22 | importing
23 | !CONFIG type TY_FIREBASE_CONFIG
24 | !PROXY type STRING optional
25 | !PROXY_PORT type STRING optional
26 | returning
27 | value(RREF_FIREBASE) type ref to ZABAPFIRE_CL_FIREBASE
28 | raising
29 | ZCX_ABAPFIRE_FIREBASE .
30 | methods GET_CONFIG
31 | returning
32 | value(RS_CONFIG) type TY_FIREBASE_CONFIG .
33 | methods GET_CLIENT
34 | returning
35 | value(RREF_HTTP_CLIENT) type ref to IF_HTTP_CLIENT .
36 | methods GET_PROXY_CONF
37 | exporting
38 | !PROXY type STRING
39 | !PROXY_PORT type STRING .
40 | protected section.
41 | private section.
42 |
43 | class-data SREF_FIREBASE type ref to ZABAPFIRE_CL_FIREBASE .
44 | data MV_PROXY type STRING .
45 | data MV_PROXY_PORT type STRING .
46 | data MS_CONFIG type TY_FIREBASE_CONFIG .
47 | data MREF_HTTP_CLIENT type ref to IF_HTTP_CLIENT .
48 |
49 | methods CONSTRUCTOR
50 | importing
51 | !CONFIG type TY_FIREBASE_CONFIG optional
52 | !PROXY type STRING
53 | !PROXY_PORT type STRING
54 | raising
55 | ZCX_ABAPFIRE_FIREBASE .
56 | ENDCLASS.
57 |
58 |
59 |
60 | CLASS ZABAPFIRE_CL_FIREBASE IMPLEMENTATION.
61 |
62 |
63 | METHOD constructor.
64 | DATA lv_url TYPE string.
65 | mv_proxy = proxy.
66 | mv_proxy_port = proxy_port.
67 | * Create API Url
68 | ASSERT CONDITION NOT config-projectid IS INITIAL.
69 | ms_config = config.
70 | lv_url = ms_config-databaseurl.
71 | * Create HTTP Client
72 | CALL METHOD cl_http_client=>create_by_url
73 | EXPORTING
74 | url = lv_url
75 | proxy_host = mv_proxy
76 | proxy_service = mv_proxy_port
77 | ssl_id = 'ANONYM'
78 | IMPORTING
79 | client = mref_http_client
80 | EXCEPTIONS
81 | argument_not_found = 1
82 | plugin_not_active = 2
83 | internal_error = 3
84 | OTHERS = 4.
85 | IF sy-subrc <> 0.
86 | zcx_abapfire_firebase=>raise(
87 | 'HTTP Connection fails' ). "#EC NOTEXT
88 | ENDIF.
89 |
90 | * Create DB Helper
91 | db = zabapfire_cl_firebase_db=>create( me ).
92 | * Create authentication Helper
93 | auth = zabapfire_cl_firebase_auth=>create( me ).
94 |
95 | ENDMETHOD.
96 |
97 |
98 | METHOD get_client.
99 |
100 | rref_http_client = mref_http_client.
101 |
102 | ENDMETHOD.
103 |
104 |
105 | METHOD get_config.
106 |
107 | rs_config = ms_config.
108 |
109 | ENDMETHOD.
110 |
111 |
112 | METHOD get_proxy_conf.
113 |
114 | proxy = mv_proxy.
115 | proxy_port = mv_proxy_port.
116 |
117 | ENDMETHOD.
118 |
119 |
120 | METHOD initialize_app.
121 |
122 | IF sref_firebase IS INITIAL.
123 | CREATE OBJECT sref_firebase
124 | EXPORTING
125 | config = config
126 | proxy = proxy
127 | proxy_port = proxy_port.
128 |
129 | ENDIF.
130 |
131 | rref_firebase = sref_firebase.
132 |
133 | ENDMETHOD.
134 | ENDCLASS.
135 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_firebase.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_FIREBASE
7 | 1
8 | E
9 | ABAP Firebase REST API Helper
10 | 1
11 | X
12 | X
13 | X
14 | X
15 |
16 |
17 |
18 | ZABAPFIRE_CL_FIREBASE
19 | AUTH
20 | E
21 | ABAP Firebase Authentication Helper
22 |
23 |
24 | ZABAPFIRE_CL_FIREBASE
25 | CONSTRUCTOR
26 | E
27 | Constructor
28 |
29 |
30 | ZABAPFIRE_CL_FIREBASE
31 | DB
32 | E
33 | ABAP Firebase DB Helper
34 |
35 |
36 | ZABAPFIRE_CL_FIREBASE
37 | GET_CLIENT
38 | E
39 | Get HTTP Client
40 |
41 |
42 | ZABAPFIRE_CL_FIREBASE
43 | GET_CONFIG
44 | E
45 | Get application config
46 |
47 |
48 | ZABAPFIRE_CL_FIREBASE
49 | INITIALIZE_APP
50 | E
51 | Initialize Application
52 |
53 |
54 | ZABAPFIRE_CL_FIREBASE
55 | MREF_HTTP_CLIENT
56 | E
57 | HTTP Client
58 |
59 |
60 | ZABAPFIRE_CL_FIREBASE
61 | MV_PROXY
62 | E
63 | Proxy
64 |
65 |
66 | ZABAPFIRE_CL_FIREBASE
67 | MV_PROXY_PORT
68 | E
69 | Proxy Port
70 |
71 |
72 | ZABAPFIRE_CL_FIREBASE
73 | SREF_FIREBASE
74 | E
75 | ABAP Firebase REST API Helper
76 |
77 |
78 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_firebase_auth.clas.abap:
--------------------------------------------------------------------------------
1 | class ZABAPFIRE_CL_FIREBASE_AUTH definition
2 | public
3 | final
4 | create private .
5 |
6 | public section.
7 |
8 | types:
9 | BEGIN OF ty_firebase_config,
10 | apikey TYPE string,
11 | authdomain TYPE string,
12 | databaseurl TYPE string,
13 | projectid TYPE string,
14 | storagebucket TYPE string,
15 | messagingsenderid TYPE string,
16 | END OF ty_firebase_config .
17 |
18 | class-methods CREATE
19 | importing
20 | !APPLICATION type ref to ZABAPFIRE_CL_FIREBASE
21 | returning
22 | value(AUTH) type ref to ZABAPFIRE_CL_FIREBASE_AUTH .
23 | methods AUTHENTICATE_WITH_EMAIL
24 | importing
25 | !EMAIL type STRING
26 | !PASSWORD type STRING
27 | raising
28 | ZCX_ABAPFIRE_FIREBASE .
29 | methods GET_TOKEN
30 | returning
31 | value(IDTOKEN) type STRING .
32 | PROTECTED SECTION.
33 | PRIVATE SECTION.
34 |
35 | CONSTANTS cv_url TYPE string VALUE
36 | 'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key='.
37 | "#EC NOTEXT
38 | CLASS-DATA sref_auth TYPE REF TO zabapfire_cl_firebase_auth .
39 | DATA application TYPE REF TO zabapfire_cl_firebase .
40 | DATA mv_email TYPE string . "#EC NEEDED
41 | DATA mv_password TYPE string . "#EC NEEDED
42 | DATA mv_id_token TYPE string .
43 | DATA mv_refresh_token TYPE string . "#EC NEEDED
44 |
45 | METHODS constructor
46 | IMPORTING
47 | !application TYPE REF TO zabapfire_cl_firebase .
48 | ENDCLASS.
49 |
50 |
51 |
52 | CLASS ZABAPFIRE_CL_FIREBASE_AUTH IMPLEMENTATION.
53 |
54 |
55 | METHOD authenticate_with_email.
56 |
57 | TYPES:
58 | BEGIN OF lty_payload,
59 | email TYPE string,
60 | password TYPE string,
61 | return_secure_token TYPE abap_bool,
62 | END OF lty_payload,
63 | BEGIN OF lty_response_payload,
64 | kind TYPE string,
65 | local_id TYPE string,
66 | email TYPE string,
67 | display_name TYPE string,
68 | id_token TYPE string,
69 | registered TYPE boolean,
70 | refresh_token TYPE string,
71 | expires_in TYPE string,
72 | END OF lty_response_payload.
73 |
74 | DATA: lv_config
75 | TYPE zabapfire_cl_firebase=>ty_firebase_config,
76 | lv_proxy TYPE string,
77 | lv_proxy_port TYPE string,
78 | lv_http_client TYPE REF TO if_http_client,
79 | lv_body TYPE string,
80 | lv_url TYPE string,
81 | ls_payload TYPE lty_payload,
82 | lref_json_serializer
83 | TYPE REF TO zabapfire_cl_json_serializer,
84 | lv_response_data TYPE string,
85 | lref_json_deserializer
86 | TYPE REF TO zabapfire_cl_json_deserializer,
87 | ls_response_abap TYPE lty_response_payload,
88 | lv_http_status TYPE i,
89 | lcx_json TYPE REF TO zcx_abapfire_json.
90 |
91 | IF email IS INITIAL OR password IS INITIAL.
92 | zcx_abapfire_firebase=>raise(
93 | 'Incorrect authentication parameters (email, password)'
94 | ). "#EC NOTEXT
95 | ELSE.
96 | mv_email = email.
97 | mv_password = password.
98 | ENDIF.
99 |
100 | * Get ApyKey from application configuration
101 | lv_config = application->get_config( ).
102 | CALL METHOD application->get_proxy_conf
103 | IMPORTING
104 | proxy = lv_proxy
105 | proxy_port = lv_proxy_port.
106 | IF lv_config-apikey IS INITIAL.
107 | zcx_abapfire_firebase=>raise(
108 | 'Wrong firebase configuration: APIKEY' ). "#EC NOTEXT
109 | ELSE.
110 | CONCATENATE cv_url lv_config-apikey
111 | INTO lv_url.
112 | ENDIF.
113 |
114 | * Create HTTP Client
115 | CALL METHOD cl_http_client=>create_by_url
116 | EXPORTING
117 | url = lv_url
118 | proxy_host = lv_proxy
119 | proxy_service = lv_proxy_port
120 | ssl_id = 'ANONYM' "#EC NOTEXT
121 | IMPORTING
122 | client = lv_http_client
123 | EXCEPTIONS
124 | argument_not_found = 1
125 | plugin_not_active = 2
126 | internal_error = 3
127 | OTHERS = 4.
128 |
129 | * Get authorization token - begin
130 | lv_http_client->request->set_method( 'POST' ). "#EC NOTEXT
131 | lv_http_client->request->set_content_type( 'application/json' ).
132 | "#EC NOTEXT
133 |
134 | * Build request payload
135 | ls_payload-email = email.
136 | ls_payload-password = password.
137 | ls_payload-return_secure_token = abap_true.
138 | TRY.
139 | CREATE OBJECT lref_json_serializer.
140 | lv_body = lref_json_serializer->serialize( ls_payload ).
141 | CATCH zcx_abapfire_json INTO lcx_json.
142 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
143 | ENDTRY.
144 |
145 | lv_http_client->request->set_cdata( lv_body ).
146 |
147 | * Send request
148 | CALL METHOD lv_http_client->send
149 | EXCEPTIONS
150 | http_communication_failure = 1
151 | http_invalid_state = 2
152 | http_processing_failed = 3
153 | http_invalid_timeout = 4
154 | OTHERS = 5.
155 | IF sy-subrc NE 0.
156 | zcx_abapfire_firebase=>raise(
157 | 'HTTP Connection fails' ). "#EC NOTEXT
158 | ENDIF.
159 |
160 | * Get response
161 | CALL METHOD lv_http_client->receive
162 | EXCEPTIONS
163 | http_communication_failure = 1
164 | http_invalid_state = 2
165 | http_processing_failed = 3.
166 | IF sy-subrc <> 0.
167 | zcx_abapfire_firebase=>raise(
168 | 'HTTP Connection fails' ). "#EC NOTEXT
169 | ENDIF.
170 |
171 | lv_response_data = lv_http_client->response->get_cdata( ).
172 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline
173 | IN lv_response_data WITH ''.
174 |
175 | * Check response code
176 | lv_http_client->response->get_status(
177 | IMPORTING
178 | code = lv_http_status ).
179 |
180 | CASE lv_http_status.
181 | WHEN 302.
182 | zcx_abapfire_firebase=>raise(
183 | 'HTTP redirect, check URL' ). "#EC NOTEXT
184 | WHEN 401.
185 | zcx_abapfire_firebase=>raise(
186 | 'HTTP 401, unauthorized' ). "#EC NOTEXT
187 | WHEN 403.
188 | zcx_abapfire_firebase=>raise(
189 | 'HTTP 403, forbidden' ). "#EC NOTEXT
190 | WHEN 404.
191 | zcx_abapfire_firebase=>raise(
192 | 'HTTP 404, not found' ). "#EC NOTEXT
193 | WHEN 415.
194 | zcx_abapfire_firebase=>raise(
195 | 'HTTP 415, unsupported media type' ). "#EC NOTEXT
196 | WHEN 400.
197 | zcx_abapfire_firebase=>raise(
198 | zabapfire_cl_http_util=>get_http_error_msg(
199 | EXPORTING
200 | code = lv_http_status
201 | api = 'google' "#EC NOTEXT
202 | payload = lv_response_data )
203 | ).
204 |
205 | ENDCASE.
206 |
207 | * Deserialize JSON Payload
208 | TRY.
209 | CREATE OBJECT lref_json_deserializer.
210 | CALL METHOD lref_json_deserializer->deserialize
211 | EXPORTING
212 | json = lv_response_data
213 | IMPORTING
214 | abap = ls_response_abap.
215 | CATCH zcx_abapfire_json INTO lcx_json.
216 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
217 | ENDTRY.
218 |
219 | * Store token
220 | mv_id_token = ls_response_abap-id_token.
221 | mv_refresh_token = ls_response_abap-refresh_token.
222 |
223 | lv_http_client->close( ).
224 |
225 | ENDMETHOD.
226 |
227 |
228 | METHOD constructor.
229 |
230 | me->application = application.
231 |
232 | ENDMETHOD.
233 |
234 |
235 | METHOD create.
236 |
237 | IF sref_auth IS INITIAL.
238 | CREATE OBJECT sref_auth
239 | EXPORTING
240 | application = application.
241 |
242 | ENDIF.
243 |
244 | auth = sref_auth.
245 |
246 | ENDMETHOD.
247 |
248 |
249 | METHOD get_token.
250 |
251 | idtoken = mv_id_token.
252 |
253 | ENDMETHOD.
254 | ENDCLASS.
255 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_firebase_auth.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_FIREBASE_AUTH
7 | 1
8 | E
9 | ABAP Firebase Authentication Helper
10 | 1
11 | X
12 | X
13 | X
14 | X
15 |
16 |
17 |
18 | ZABAPFIRE_CL_FIREBASE_AUTH
19 | APPLICATION
20 | E
21 | ABAP Firebase REST API Helper
22 |
23 |
24 | ZABAPFIRE_CL_FIREBASE_AUTH
25 | CREATE
26 | E
27 | Create
28 |
29 |
30 | ZABAPFIRE_CL_FIREBASE_AUTH
31 | MV_EMAIL
32 | E
33 | Authentication mail
34 |
35 |
36 | ZABAPFIRE_CL_FIREBASE_AUTH
37 | MV_PASSWORD
38 | E
39 | Authentication password
40 |
41 |
42 | ZABAPFIRE_CL_FIREBASE_AUTH
43 | SREF_AUTH
44 | E
45 | ABAP Firebase Authentication Helper
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_firebase_db.clas.abap:
--------------------------------------------------------------------------------
1 | class ZABAPFIRE_CL_FIREBASE_DB definition
2 | public
3 | final
4 | create private .
5 |
6 | public section.
7 |
8 | types:
9 | BEGIN OF ty_get_parameters,
10 | shallow TYPE abap_bool,
11 | order_by TYPE string,
12 | start_at TYPE string,
13 | end_at TYPE string,
14 | limit_to_first TYPE string,
15 | limit_to_last TYPE string,
16 | equal_to TYPE string,
17 | END OF ty_get_parameters .
18 | types:
19 | BEGIN OF ty_firebase_config,
20 | apikey TYPE string,
21 | authdomain TYPE string,
22 | databaseurl TYPE string,
23 | projectid TYPE string,
24 | storagebucket TYPE string,
25 | messagingsenderid TYPE string,
26 | END OF ty_firebase_config .
27 |
28 | class-methods CREATE
29 | importing
30 | !APPLICATION type ref to ZABAPFIRE_CL_FIREBASE
31 | returning
32 | value(RREF_DB) type ref to ZABAPFIRE_CL_FIREBASE_DB .
33 | methods GET
34 | importing
35 | !PATH type STRING
36 | !PARAMETERS type TY_GET_PARAMETERS optional
37 | exporting
38 | value(CHILD) type ANY
39 | raising
40 | ZCX_ABAPFIRE_FIREBASE .
41 | methods REMOVE
42 | importing
43 | !PATH type STRING
44 | raising
45 | ZCX_ABAPFIRE_FIREBASE .
46 | methods PUSH
47 | importing
48 | !PATH type STRING
49 | !CHILD type ANY
50 | returning
51 | value(KEY) type STRING
52 | raising
53 | ZCX_ABAPFIRE_FIREBASE .
54 | methods SET
55 | importing
56 | !PATH type STRING
57 | !CHILD type ANY
58 | raising
59 | ZCX_ABAPFIRE_FIREBASE .
60 | methods UPDATE
61 | importing
62 | !PATH type STRING
63 | !CHILD type ANY
64 | raising
65 | ZCX_ABAPFIRE_FIREBASE .
66 | PROTECTED SECTION.
67 |
68 | private section.
69 |
70 | class-data SREF_DB type ref to ZABAPFIRE_CL_FIREBASE_DB .
71 | data APPLICATION type ref to ZABAPFIRE_CL_FIREBASE .
72 |
73 | methods CONSTRUCTOR
74 | importing
75 | !APPLICATION type ref to ZABAPFIRE_CL_FIREBASE .
76 | methods ADD_PARAMETERS
77 | importing
78 | !PARAMETERS type ANY
79 | changing
80 | !URI type STRING
81 | !QUERY_DELIMITER type CHAR1
82 | raising
83 | ZCX_ABAPFIRE_FIREBASE .
84 | ENDCLASS.
85 |
86 |
87 |
88 | CLASS ZABAPFIRE_CL_FIREBASE_DB IMPLEMENTATION.
89 |
90 |
91 | METHOD add_parameters.
92 |
93 | DATA:
94 | l_abap_type TYPE REF TO cl_abap_typedescr,
95 | l_abap_stru TYPE REF TO cl_abap_structdescr,
96 | lt_components TYPE cl_abap_structdescr=>component_table,
97 | l_component TYPE cl_abap_structdescr=>component,
98 | l_parameter TYPE string,
99 | l_parameter_value TYPE string.
100 | FIELD-SYMBOLS:
101 | TYPE any.
102 |
103 | l_abap_type = cl_abap_typedescr=>describe_by_data( parameters ).
104 | IF l_abap_type->kind = cl_abap_typedescr=>kind_struct.
105 | l_abap_stru ?= cl_abap_typedescr=>describe_by_data( parameters ).
106 | lt_components = l_abap_stru->get_components( ).
107 | LOOP AT lt_components INTO l_component.
108 | ASSIGN COMPONENT l_component-name OF STRUCTURE parameters
109 | TO .
110 | IF sy-subrc NE 0.
111 | zcx_abapfire_firebase=>raise(
112 | 'Wrong URI parameters' ). "#EC NOTEXT
113 | ENDIF.
114 | CHECK NOT IS INITIAL.
115 | l_parameter =
116 | zabapfire_cl_http_util=>abap_lcc( l_component-name ).
117 | l_parameter_value =
118 | zabapfire_cl_http_util=>serialize_value( ).
119 | CONCATENATE
120 | uri
121 | query_delimiter
122 | l_parameter
123 | '='
124 | l_parameter_value
125 | INTO uri.
126 | query_delimiter = '&'. "#EC NOTEXT
127 | ENDLOOP.
128 | ELSE.
129 | zcx_abapfire_firebase=>raise(
130 | 'Wrong URI parameters' ). "#EC NOTEXT
131 | ENDIF.
132 |
133 | ENDMETHOD.
134 |
135 |
136 | METHOD constructor.
137 |
138 | me->application = application.
139 |
140 | ENDMETHOD.
141 |
142 |
143 | METHOD create.
144 |
145 | IF sref_db IS INITIAL.
146 | CREATE OBJECT sref_db
147 | EXPORTING
148 | application = application.
149 |
150 | ENDIF.
151 |
152 | rref_db = sref_db.
153 |
154 | ENDMETHOD.
155 |
156 |
157 | METHOD get.
158 |
159 | DATA:
160 | lv_uri TYPE string,
161 | lv_idtoken TYPE string,
162 | lv_response_data TYPE string,
163 | lv_http_status TYPE i,
164 | lref_json_deserializer TYPE REF TO
165 | zabapfire_cl_json_deserializer,
166 | l_query_delimiter TYPE c LENGTH 1 VALUE '?',
167 | lcx_json TYPE REF TO zcx_abapfire_json.
168 |
169 | ASSERT CONDITION NOT path IS INITIAL.
170 |
171 | application->get_client( )->request->set_method( 'GET' ).
172 | application->get_client( )->request->set_content_type(
173 | 'application/json' ).
174 |
175 | CONCATENATE path '.json' INTO lv_uri.
176 |
177 | * Set parameters
178 | add_parameters(
179 | EXPORTING
180 | parameters = parameters
181 | CHANGING
182 | uri = lv_uri
183 | query_delimiter = l_query_delimiter ).
184 |
185 | * Get authentication token
186 | lv_idtoken = application->auth->get_token( ).
187 |
188 | IF NOT lv_idtoken IS INITIAL.
189 | CONCATENATE lv_uri l_query_delimiter 'auth=' lv_idtoken
190 | INTO lv_uri.
191 | ENDIF.
192 |
193 | * Set URI
194 | cl_http_utility=>set_request_uri(
195 | EXPORTING
196 | request = application->get_client( )->request
197 | uri = lv_uri
198 | ).
199 |
200 | * Send request
201 | application->get_client( )->send(
202 | EXCEPTIONS
203 | http_communication_failure = 1
204 | http_invalid_state = 2
205 | http_processing_failed = 3
206 | http_invalid_timeout = 4
207 | OTHERS = 5
208 | ).
209 | IF sy-subrc NE 0.
210 | zcx_abapfire_firebase=>raise(
211 | 'HTTP Connection fails' ). "#EC NOTEXT
212 | ENDIF.
213 |
214 | * Get response
215 | application->get_client( )->receive(
216 | EXCEPTIONS
217 | http_communication_failure = 1
218 | http_invalid_state = 2
219 | http_processing_failed = 3
220 | ).
221 | IF sy-subrc <> 0.
222 | zcx_abapfire_firebase=>raise(
223 | 'HTTP Connection fails' ). "#EC NOTEXT
224 | ENDIF.
225 |
226 | lv_response_data =
227 | application->get_client( )->response->get_cdata( ).
228 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline
229 | IN lv_response_data WITH ''.
230 |
231 | * Check response code
232 | application->get_client( )->response->get_status(
233 | IMPORTING
234 | code = lv_http_status ).
235 |
236 | CASE lv_http_status.
237 | WHEN 302.
238 | zcx_abapfire_firebase=>raise( 'HTTP redirect, check URL' ).
239 | "#EC NOTEXT
240 | WHEN 401.
241 | zcx_abapfire_firebase=>raise( 'HTTP 401, unauthorized' ).
242 | "#EC NOTEXT
243 | WHEN 403.
244 | zcx_abapfire_firebase=>raise( 'HTTP 403, forbidden' ).
245 | "#EC NOTEXT
246 | WHEN 404.
247 | zcx_abapfire_firebase=>raise( 'HTTP 404, not found' ).
248 | "#EC NOTEXT
249 | WHEN 415.
250 | zcx_abapfire_firebase=>raise(
251 | 'HTTP 415, unsupported media type' ). "#EC NOTEXT
252 |
253 | WHEN 400.
254 | zcx_abapfire_firebase=>raise(
255 | zabapfire_cl_http_util=>get_http_error_msg(
256 | EXPORTING
257 | code = lv_http_status
258 | api = 'firebase'
259 | payload = lv_response_data )
260 | ).
261 |
262 | ENDCASE.
263 |
264 | * Deserialize JSON Payload
265 | TRY.
266 | CREATE OBJECT lref_json_deserializer.
267 | CALL METHOD lref_json_deserializer->deserialize
268 | EXPORTING
269 | json = lv_response_data
270 | IMPORTING
271 | abap = child.
272 | CATCH zcx_abapfire_json INTO lcx_json.
273 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
274 | ENDTRY.
275 |
276 | ENDMETHOD.
277 |
278 |
279 | METHOD push.
280 |
281 | DATA:
282 | BEGIN OF ls_key,
283 | name TYPE string,
284 | END OF ls_key,
285 | lv_uri TYPE string,
286 | lv_idtoken TYPE string,
287 | lv_body TYPE string,
288 | lv_response_data TYPE string,
289 | lv_http_status TYPE i,
290 | lref_json_serializer TYPE REF TO zabapfire_cl_json_serializer,
291 | lref_json_deserializer TYPE REF TO
292 | zabapfire_cl_json_deserializer,
293 | l_query_delimiter TYPE c LENGTH 1 VALUE '?',
294 | lcx_json TYPE REF TO zcx_abapfire_json.
295 |
296 | ASSERT CONDITION NOT path IS INITIAL.
297 |
298 | application->get_client( )->request->set_method( 'POST' ).
299 | application->get_client( )->request->set_content_type(
300 | 'application/json' ).
301 |
302 | CONCATENATE path '.json' INTO lv_uri.
303 |
304 | * Get authentication token
305 | lv_idtoken = application->auth->get_token( ).
306 |
307 | IF NOT lv_idtoken IS INITIAL.
308 | CONCATENATE lv_uri l_query_delimiter 'auth=' lv_idtoken
309 | INTO lv_uri.
310 | ENDIF.
311 |
312 | * Set URI
313 | cl_http_utility=>set_request_uri(
314 | EXPORTING
315 | request = application->get_client( )->request
316 | uri = lv_uri
317 | ).
318 |
319 | * Set request body
320 | TRY.
321 | CREATE OBJECT lref_json_serializer.
322 | lv_body = lref_json_serializer->serialize( child ).
323 | CATCH zcx_abapfire_json INTO lcx_json.
324 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
325 | ENDTRY.
326 |
327 | application->get_client( )->request->set_cdata( lv_body ).
328 |
329 | * Send request
330 | application->get_client( )->send(
331 | EXCEPTIONS
332 | http_communication_failure = 1
333 | http_invalid_state = 2
334 | http_processing_failed = 3
335 | http_invalid_timeout = 4
336 | OTHERS = 5
337 | ).
338 | IF sy-subrc NE 0.
339 | zcx_abapfire_firebase=>raise(
340 | 'HTTP Connection fails' ). "#EC NOTEXT
341 | ENDIF.
342 |
343 | * Get response
344 | application->get_client( )->receive(
345 | EXCEPTIONS
346 | http_communication_failure = 1
347 | http_invalid_state = 2
348 | http_processing_failed = 3
349 | ).
350 | IF sy-subrc <> 0.
351 | zcx_abapfire_firebase=>raise(
352 | 'HTTP Connection fails' ). "#EC NOTEXT
353 | ENDIF.
354 |
355 | * Get response data
356 | lv_response_data =
357 | application->get_client( )->response->get_cdata( ).
358 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline
359 | IN lv_response_data WITH ''.
360 |
361 | * Check response code
362 | application->get_client( )->response->get_status(
363 | IMPORTING
364 | code = lv_http_status ).
365 |
366 | CASE lv_http_status.
367 | WHEN 302.
368 | zcx_abapfire_firebase=>raise( 'HTTP redirect, check URL' ).
369 | "#EC NOTEXT
370 | WHEN 401.
371 | zcx_abapfire_firebase=>raise( 'HTTP 401, unauthorized' ).
372 | "#EC NOTEXT
373 | WHEN 403.
374 | zcx_abapfire_firebase=>raise( 'HTTP 403, forbidden' ).
375 | "#EC NOTEXT
376 | WHEN 404.
377 | zcx_abapfire_firebase=>raise( 'HTTP 404, not found' ).
378 | "#EC NOTEXT
379 | WHEN 415.
380 | zcx_abapfire_firebase=>raise(
381 | 'HTTP 415, unsupported media type' ). "#EC NOTEXT
382 |
383 | WHEN 400.
384 | zcx_abapfire_firebase=>raise(
385 | zabapfire_cl_http_util=>get_http_error_msg(
386 | EXPORTING
387 | code = lv_http_status
388 | api = 'firebase'
389 | payload = lv_response_data )
390 | ).
391 |
392 | ENDCASE.
393 |
394 | * Deserialize JSON Payload
395 | TRY.
396 | CREATE OBJECT lref_json_deserializer.
397 | CALL METHOD lref_json_deserializer->deserialize
398 | EXPORTING
399 | json = lv_response_data
400 | IMPORTING
401 | abap = ls_key.
402 | CATCH zcx_abapfire_json INTO lcx_json.
403 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
404 | ENDTRY.
405 |
406 | key = ls_key-name.
407 |
408 | ENDMETHOD.
409 |
410 |
411 | METHOD REMOVE.
412 |
413 | DATA:
414 | lv_uri TYPE string,
415 | lv_idtoken TYPE string,
416 | lv_body TYPE string,
417 | lv_response_data TYPE string,
418 | lv_http_status TYPE i,
419 | lref_json_serializer TYPE REF TO zabapfire_cl_json_serializer,
420 | l_query_delimiter TYPE c LENGTH 1 VALUE '?',
421 | lcx_json TYPE REF TO zcx_abapfire_json.
422 |
423 | ASSERT CONDITION NOT path IS INITIAL.
424 |
425 | application->get_client( )->request->set_method( 'DELETE' ).
426 |
427 | CONCATENATE path '.json' INTO lv_uri.
428 |
429 | * Get authentication token
430 | lv_idtoken = application->auth->get_token( ).
431 |
432 | IF NOT lv_idtoken IS INITIAL.
433 | CONCATENATE lv_uri l_query_delimiter 'auth=' lv_idtoken
434 | INTO lv_uri.
435 | ENDIF.
436 |
437 | * Set URI
438 | cl_http_utility=>set_request_uri(
439 | EXPORTING
440 | request = application->get_client( )->request
441 | uri = lv_uri
442 | ).
443 |
444 | * Send request
445 | application->get_client( )->send(
446 | EXCEPTIONS
447 | http_communication_failure = 1
448 | http_invalid_state = 2
449 | http_processing_failed = 3
450 | http_invalid_timeout = 4
451 | OTHERS = 5
452 | ).
453 | IF sy-subrc NE 0.
454 | zcx_abapfire_firebase=>raise(
455 | 'HTTP Connection fails' ). "#EC NOTEXT
456 | ENDIF.
457 |
458 | * Get response
459 | application->get_client( )->receive(
460 | EXCEPTIONS
461 | http_communication_failure = 1
462 | http_invalid_state = 2
463 | http_processing_failed = 3
464 | ).
465 | IF sy-subrc <> 0.
466 | zcx_abapfire_firebase=>raise(
467 | 'HTTP Connection fails' ). "#EC NOTEXT
468 | ENDIF.
469 |
470 | * Check response code
471 | application->get_client( )->response->get_status(
472 | IMPORTING
473 | code = lv_http_status ).
474 |
475 | CASE lv_http_status.
476 | WHEN 302.
477 | zcx_abapfire_firebase=>raise( 'HTTP redirect, check URL' ).
478 | "#EC NOTEXT
479 | WHEN 401.
480 | zcx_abapfire_firebase=>raise( 'HTTP 401, unauthorized' ).
481 | "#EC NOTEXT
482 | WHEN 403.
483 | zcx_abapfire_firebase=>raise( 'HTTP 403, forbidden' ).
484 | "#EC NOTEXT
485 | WHEN 404.
486 | zcx_abapfire_firebase=>raise( 'HTTP 404, not found' ).
487 | "#EC NOTEXT
488 | WHEN 415.
489 | zcx_abapfire_firebase=>raise(
490 | 'HTTP 415, unsupported media type' ). "#EC NOTEXT
491 |
492 | WHEN 400.
493 | lv_response_data =
494 | application->get_client( )->response->get_cdata( ).
495 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline
496 | IN lv_response_data WITH ''.
497 | zcx_abapfire_firebase=>raise(
498 | zabapfire_cl_http_util=>get_http_error_msg(
499 | EXPORTING
500 | code = lv_http_status
501 | api = 'firebase'
502 | payload = lv_response_data )
503 | ).
504 |
505 | ENDCASE.
506 |
507 | ENDMETHOD.
508 |
509 |
510 | METHOD set.
511 |
512 | DATA:
513 | lv_uri TYPE string,
514 | lv_idtoken TYPE string,
515 | lv_body TYPE string,
516 | lv_response_data TYPE string,
517 | lv_http_status TYPE i,
518 | lref_json_serializer TYPE REF TO zabapfire_cl_json_serializer,
519 | l_query_delimiter TYPE c LENGTH 1 VALUE '?',
520 | lcx_json TYPE REF TO zcx_abapfire_json.
521 |
522 | ASSERT CONDITION NOT path IS INITIAL.
523 |
524 | application->get_client( )->request->set_method( 'PUT' ).
525 | application->get_client( )->request->set_content_type(
526 | 'application/json' ).
527 |
528 | CONCATENATE path '.json' INTO lv_uri.
529 |
530 | * Get authentication token
531 | lv_idtoken = application->auth->get_token( ).
532 |
533 | IF NOT lv_idtoken IS INITIAL.
534 | CONCATENATE lv_uri l_query_delimiter 'auth=' lv_idtoken
535 | INTO lv_uri.
536 | ENDIF.
537 |
538 | * Set URI
539 | cl_http_utility=>set_request_uri(
540 | EXPORTING
541 | request = application->get_client( )->request
542 | uri = lv_uri
543 | ).
544 |
545 | * Set request body
546 | TRY.
547 | CREATE OBJECT lref_json_serializer.
548 | lv_body = lref_json_serializer->serialize( child ).
549 | CATCH zcx_abapfire_json INTO lcx_json.
550 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
551 | ENDTRY.
552 |
553 | application->get_client( )->request->set_cdata( lv_body ).
554 |
555 | * Send request
556 | application->get_client( )->send(
557 | EXCEPTIONS
558 | http_communication_failure = 1
559 | http_invalid_state = 2
560 | http_processing_failed = 3
561 | http_invalid_timeout = 4
562 | OTHERS = 5
563 | ).
564 | IF sy-subrc NE 0.
565 | zcx_abapfire_firebase=>raise(
566 | 'HTTP Connection fails' ). "#EC NOTEXT
567 | ENDIF.
568 |
569 | * Get response
570 | application->get_client( )->receive(
571 | EXCEPTIONS
572 | http_communication_failure = 1
573 | http_invalid_state = 2
574 | http_processing_failed = 3
575 | ).
576 | IF sy-subrc <> 0.
577 | zcx_abapfire_firebase=>raise(
578 | 'HTTP Connection fails' ). "#EC NOTEXT
579 | ENDIF.
580 |
581 | * Check response code
582 | application->get_client( )->response->get_status(
583 | IMPORTING
584 | code = lv_http_status ).
585 |
586 | CASE lv_http_status.
587 | WHEN 302.
588 | zcx_abapfire_firebase=>raise( 'HTTP redirect, check URL' ).
589 | "#EC NOTEXT
590 | WHEN 401.
591 | zcx_abapfire_firebase=>raise( 'HTTP 401, unauthorized' ).
592 | "#EC NOTEXT
593 | WHEN 403.
594 | zcx_abapfire_firebase=>raise( 'HTTP 403, forbidden' ).
595 | "#EC NOTEXT
596 | WHEN 404.
597 | zcx_abapfire_firebase=>raise( 'HTTP 404, not found' ).
598 | "#EC NOTEXT
599 | WHEN 415.
600 | zcx_abapfire_firebase=>raise(
601 | 'HTTP 415, unsupported media type' ). "#EC NOTEXT
602 |
603 | WHEN 400.
604 | lv_response_data =
605 | application->get_client( )->response->get_cdata( ).
606 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline
607 | IN lv_response_data WITH ''.
608 | zcx_abapfire_firebase=>raise(
609 | zabapfire_cl_http_util=>get_http_error_msg(
610 | EXPORTING
611 | code = lv_http_status
612 | api = 'firebase'
613 | payload = lv_response_data )
614 | ).
615 |
616 | ENDCASE.
617 |
618 | ENDMETHOD.
619 |
620 |
621 | METHOD update.
622 |
623 | DATA:
624 | lv_uri TYPE string,
625 | lv_idtoken TYPE string,
626 | lv_body TYPE string,
627 | lv_response_data TYPE string,
628 | lv_http_status TYPE i,
629 | lref_json_serializer TYPE REF TO zabapfire_cl_json_serializer,
630 | l_query_delimiter TYPE c LENGTH 1 VALUE '?',
631 | lcx_json TYPE REF TO zcx_abapfire_json.
632 |
633 | ASSERT CONDITION NOT path IS INITIAL.
634 |
635 | application->get_client( )->request->set_method( 'PATCH' ).
636 | application->get_client( )->request->set_content_type(
637 | 'application/json' ).
638 |
639 | CONCATENATE path '.json' INTO lv_uri.
640 |
641 | * Get authentication token
642 | lv_idtoken = application->auth->get_token( ).
643 |
644 | IF NOT lv_idtoken IS INITIAL.
645 | CONCATENATE lv_uri l_query_delimiter 'auth=' lv_idtoken
646 | INTO lv_uri.
647 | ENDIF.
648 |
649 | * Set URI
650 | cl_http_utility=>set_request_uri(
651 | EXPORTING
652 | request = application->get_client( )->request
653 | uri = lv_uri
654 | ).
655 |
656 | * Set request body
657 | TRY.
658 | CREATE OBJECT lref_json_serializer.
659 | lv_body = lref_json_serializer->serialize( child ).
660 | CATCH zcx_abapfire_json INTO lcx_json.
661 | zcx_abapfire_firebase=>raise( lcx_json->get_text( ) ).
662 | ENDTRY.
663 |
664 | application->get_client( )->request->set_cdata( lv_body ).
665 |
666 | * Send request
667 | application->get_client( )->send(
668 | EXCEPTIONS
669 | http_communication_failure = 1
670 | http_invalid_state = 2
671 | http_processing_failed = 3
672 | http_invalid_timeout = 4
673 | OTHERS = 5
674 | ).
675 | IF sy-subrc NE 0.
676 | zcx_abapfire_firebase=>raise(
677 | 'HTTP Connection fails' ). "#EC NOTEXT
678 | ENDIF.
679 |
680 | * Get response
681 | application->get_client( )->receive(
682 | EXCEPTIONS
683 | http_communication_failure = 1
684 | http_invalid_state = 2
685 | http_processing_failed = 3
686 | ).
687 | IF sy-subrc <> 0.
688 | zcx_abapfire_firebase=>raise(
689 | 'HTTP Connection fails' ). "#EC NOTEXT
690 | ENDIF.
691 |
692 | * Check response code
693 | application->get_client( )->response->get_status(
694 | IMPORTING
695 | code = lv_http_status ).
696 |
697 | CASE lv_http_status.
698 | WHEN 302.
699 | zcx_abapfire_firebase=>raise( 'HTTP redirect, check URL' ).
700 | "#EC NOTEXT
701 | WHEN 401.
702 | zcx_abapfire_firebase=>raise( 'HTTP 401, unauthorized' ).
703 | "#EC NOTEXT
704 | WHEN 403.
705 | zcx_abapfire_firebase=>raise( 'HTTP 403, forbidden' ).
706 | "#EC NOTEXT
707 | WHEN 404.
708 | zcx_abapfire_firebase=>raise( 'HTTP 404, not found' ).
709 | "#EC NOTEXT
710 | WHEN 415.
711 | zcx_abapfire_firebase=>raise(
712 | 'HTTP 415, unsupported media type' ). "#EC NOTEXT
713 |
714 | WHEN 400.
715 | lv_response_data =
716 | application->get_client( )->response->get_cdata( ).
717 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline
718 | IN lv_response_data WITH ''.
719 | zcx_abapfire_firebase=>raise(
720 | zabapfire_cl_http_util=>get_http_error_msg(
721 | EXPORTING
722 | code = lv_http_status
723 | api = 'firebase'
724 | payload = lv_response_data )
725 | ).
726 |
727 | ENDCASE.
728 |
729 | ENDMETHOD.
730 | ENDCLASS.
731 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_firebase_db.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_FIREBASE_DB
7 | 1
8 | E
9 | ABAP Firebase DB Helper
10 | 1
11 | X
12 | X
13 | X
14 | X
15 |
16 |
17 |
18 | ZABAPFIRE_CL_FIREBASE_DB
19 | APPLICATION
20 | E
21 | ABAP Firebase REST API Helper
22 |
23 |
24 | ZABAPFIRE_CL_FIREBASE_DB
25 | CREATE
26 | E
27 | Create
28 |
29 |
30 | ZABAPFIRE_CL_FIREBASE_DB
31 | SREF_DB
32 | E
33 | ABAP Firebase REST API Helper
34 |
35 |
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_http_util.clas.abap:
--------------------------------------------------------------------------------
1 | class ZABAPFIRE_CL_HTTP_UTIL definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 |
8 | class-methods GET_HTTP_ERROR_MSG
9 | importing
10 | !CODE type I
11 | !PAYLOAD type STRING
12 | !API type STRING
13 | returning
14 | value(RV_MSG) type STRING
15 | raising
16 | ZCX_ABAPFIRE_FIREBASE .
17 | class-methods ABAP_LCC
18 | importing
19 | !IN type STRING
20 | returning
21 | value(OUT) type STRING .
22 | class-methods LCC_ABAP
23 | importing
24 | !IN type STRING
25 | returning
26 | value(OUT) type STRING .
27 | class-methods DESERIALIZE_VALUE
28 | importing
29 | !JSON_VALUE type STRING
30 | !JSON_TYPE type STRING
31 | exporting
32 | value(ABAP_VALUE) type ANY .
33 | class-methods SERIALIZE_VALUE
34 | importing
35 | !ABAP_VALUE type ANY
36 | returning
37 | value(JSON_VALUE) type STRING .
38 | PROTECTED SECTION.
39 | private section.
40 |
41 | constants C_BOOL_TYPES type STRING value `\TYPE-POOL=ABAP\TYPE=ABAP_BOOL\TYPE=BOOLEAN\TYPE=BOOLE_D\TYPE=XFELD` ##NO_TEXT.
42 |
43 | class-methods XSTRING_TO_STRING
44 | importing
45 | !IN type ANY
46 | returning
47 | value(OUT) type STRING .
48 | class-methods STRING_TO_XSTRING
49 | importing
50 | !IN type STRING
51 | changing
52 | !OUT type ANY .
53 | ENDCLASS.
54 |
55 |
56 |
57 | CLASS ZABAPFIRE_CL_HTTP_UTIL IMPLEMENTATION.
58 |
59 |
60 | METHOD ABAP_LCC.
61 |
62 | DATA: tokens TYPE TABLE OF char128.
63 |
64 | FIELD-SYMBOLS:
65 | TYPE any.
66 |
67 | CHECK NOT in IS INITIAL.
68 |
69 | out = in.
70 | TRANSLATE out TO LOWER CASE.
71 |
72 | SPLIT out AT `_` INTO TABLE tokens.
73 | LOOP AT tokens ASSIGNING FROM 2.
74 | TRANSLATE (1) TO UPPER CASE.
75 | ENDLOOP.
76 |
77 | CONCATENATE LINES OF tokens INTO out.
78 |
79 | ENDMETHOD.
80 |
81 |
82 | METHOD DESERIALIZE_VALUE.
83 | DATA: l_elem_descr TYPE REF TO cl_abap_elemdescr,
84 | l_string TYPE string,
85 | l_year TYPE n LENGTH 4,
86 | l_month TYPE n LENGTH 2,
87 | l_day TYPE n LENGTH 2,
88 | l_hour TYPE n LENGTH 2,
89 | l_minute TYPE n LENGTH 2,
90 | l_second TYPE n LENGTH 2,
91 | l_decimals TYPE n LENGTH 7,
92 | tk LIKE l_elem_descr->type_kind.
93 |
94 | DEFINE escape_string.
95 | REPLACE ALL OCCURRENCES OF `\"` IN &1 WITH `"`.
96 | REPLACE ALL OCCURRENCES OF `\\` IN &1 WITH `\`.
97 | END-OF-DEFINITION.
98 |
99 | l_elem_descr ?= cl_abap_typedescr=>describe_by_data( abap_value ).
100 | tk = l_elem_descr->type_kind.
101 |
102 | CASE json_type.
103 | WHEN 'string'.
104 | l_string = json_value.
105 | escape_string l_string.
106 | CASE tk.
107 | WHEN cl_abap_typedescr=>typekind_xstring OR
108 | cl_abap_typedescr=>typekind_hex.
109 | string_to_xstring( EXPORTING in = l_string CHANGING out = abap_value ).
110 | WHEN cl_abap_typedescr=>typekind_date.
111 | FIND FIRST OCCURRENCE OF REGEX '(\d{4})-(\d{2})-(\d{2})' IN json_value
112 | SUBMATCHES l_year l_month l_day.
113 | IF sy-subrc EQ 0.
114 | CONCATENATE l_year l_month l_day INTO abap_value.
115 | ENDIF.
116 | WHEN cl_abap_typedescr=>typekind_time.
117 | FIND FIRST OCCURRENCE OF REGEX '(\d{2}):(\d{2}):(\d{2})' IN json_value
118 | SUBMATCHES l_hour l_minute l_second.
119 | IF sy-subrc EQ 0.
120 | CONCATENATE l_hour l_minute l_second INTO abap_value.
121 | ENDIF.
122 | WHEN cl_abap_typedescr=>typekind_packed.
123 | FIND FIRST OCCURRENCE OF REGEX
124 | '(\d{4})-?(\d{2})-?(\d{2})T(\d{2}):?(\d{2}):?(\d{2})(?:[\.,](\d{0,7}))?Z?'
125 | "#EC NOTEXT
126 | IN json_value
127 | SUBMATCHES l_year l_month l_day l_hour l_minute l_second l_decimals.
128 | IF sy-subrc EQ 0.
129 | CONCATENATE l_year l_month l_day
130 | l_hour l_minute l_second '.' l_decimals INTO l_string.
131 | abap_value = l_string.
132 | ENDIF.
133 | WHEN OTHERS.
134 | abap_value = l_string.
135 | ENDCASE.
136 | WHEN 'boolean'.
137 | CASE json_value.
138 | WHEN 'true'.
139 | abap_value = abap_true.
140 | WHEN 'false' OR 'null'. "TODO Manage 3 values boolean
141 | abap_value = abap_false.
142 | ENDCASE.
143 | WHEN 'number'.
144 | abap_value = json_value.
145 | ENDCASE.
146 |
147 | ENDMETHOD.
148 |
149 |
150 | METHOD get_http_error_msg.
151 |
152 | TYPES:
153 | BEGIN OF ty_error_array,
154 | domain TYPE string,
155 | reason TYPE string,
156 | message TYPE string,
157 | END OF ty_error_array,
158 | BEGIN OF ty_error_google,
159 | errors TYPE STANDARD TABLE OF ty_error_array
160 | WITH DEFAULT KEY,
161 | code TYPE i,
162 | message TYPE string,
163 | END OF ty_error_google,
164 | BEGIN OF ty_response_google,
165 | error TYPE ty_error_google,
166 | END OF ty_response_google,
167 | BEGIN OF ty_response_firebase,
168 | error TYPE string,
169 | END OF ty_response_firebase.
170 |
171 | DATA:
172 | lref_json_deserializer TYPE REF TO zabapfire_cl_json_deserializer,
173 | ls_error_google TYPE ty_response_google,
174 | ls_error_firebase TYPE ty_response_firebase,
175 | lv_code TYPE n LENGTH 4,
176 | lcx_exception TYPE REF TO zcx_abapfire_json.
177 |
178 | FIELD-SYMBOLS:
179 | TYPE any,
180 | TYPE any.
181 |
182 | lv_code = code.
183 |
184 | CASE api.
185 | WHEN 'google'.
186 | ASSIGN ls_error_google TO .
187 | WHEN 'firebase'.
188 | ASSIGN ls_error_firebase TO .
189 | WHEN OTHERS.
190 | CONCATENATE 'HTTP ERROR:' lv_code INTO rv_msg SEPARATED BY space.
191 | RETURN.
192 | ENDCASE.
193 |
194 | TRY.
195 | CREATE OBJECT lref_json_deserializer.
196 | CALL METHOD lref_json_deserializer->deserialize
197 | EXPORTING
198 | json = payload
199 | IMPORTING
200 | abap = .
201 | CATCH zcx_abapfire_json INTO lcx_exception.
202 | zcx_abapfire_firebase=>raise( lcx_exception->get_text( ) ).
203 | ENDTRY.
204 |
205 | CASE api.
206 | WHEN 'google'. "#EC NOTEXT
207 | ASSIGN COMPONENT 'message'
208 | OF STRUCTURE ls_error_google-error
209 | TO . "#EC NOTEXT
210 | WHEN 'firebase'. "#EC NOTEXT
211 | ASSIGN ls_error_firebase-error TO .
212 | ENDCASE.
213 |
214 | IF IS ASSIGNED.
215 | CONCATENATE 'HTTP ERROR:' lv_code
216 | INTO rv_msg SEPARATED BY space.
217 | ENDIF.
218 |
219 | ENDMETHOD.
220 |
221 |
222 | METHOD lcc_abap.
223 |
224 | CHECK NOT in IS INITIAL.
225 |
226 | out = in.
227 | REPLACE ALL OCCURRENCES OF REGEX `([a-z])([A-Z])`
228 | IN out WITH `$1_$2`. "#EC NOTEXT
229 | TRANSLATE out TO UPPER CASE.
230 |
231 | ENDMETHOD.
232 |
233 |
234 | METHOD SERIALIZE_VALUE.
235 | DATA: l_elem_descr TYPE REF TO cl_abap_elemdescr,
236 | tk LIKE l_elem_descr->type_kind,
237 | an LIKE l_elem_descr->absolute_name,
238 | ol LIKE l_elem_descr->output_length.
239 |
240 | DEFINE escape_string.
241 | REPLACE ALL OCCURRENCES OF `\` IN &1 WITH `\\`.
242 | REPLACE ALL OCCURRENCES OF `"` IN &1 WITH `\"`.
243 | END-OF-DEFINITION.
244 |
245 | l_elem_descr ?= cl_abap_typedescr=>describe_by_data( abap_value ).
246 | tk = l_elem_descr->type_kind.
247 | an = l_elem_descr->absolute_name.
248 | ol = l_elem_descr->output_length.
249 |
250 | CASE tk.
251 | WHEN cl_abap_typedescr=>typekind_float OR
252 | cl_abap_typedescr=>typekind_int OR
253 | cl_abap_typedescr=>typekind_int1 OR
254 | cl_abap_typedescr=>typekind_int2 OR
255 | cl_abap_typedescr=>typekind_packed OR
256 | `8`. "typekind_int8 -> '8' only from 7.40.
257 | IF tk EQ cl_abap_typedescr=>typekind_packed AND
258 | an CP `\TYPE=TIMESTAMP*`.
259 | IF abap_value IS INITIAL.
260 | json_value = `""`.
261 | ELSE.
262 | MOVE abap_value TO json_value.
263 | IF an EQ `\TYPE=TIMESTAMP`.
264 | CONCATENATE `"` json_value(4)
265 | `-` json_value+4(2)
266 | `-` json_value+6(2)
267 | `T` json_value+8(2)
268 | `:` json_value+10(2)
269 | `:` json_value+12(2)
270 | `.0000000Z"` INTO json_value.
271 | ELSEIF an EQ `\TYPE=TIMESTAMPL`.
272 | CONCATENATE `"` json_value(4)
273 | `-` json_value+4(2)
274 | `-` json_value+6(2)
275 | `T` json_value+8(2)
276 | `:` json_value+10(2)
277 | `:` json_value+12(2)
278 | `.` json_value+15(7) `Z"` INTO json_value.
279 | ENDIF.
280 | ENDIF.
281 | ELSEIF abap_value IS INITIAL.
282 | json_value = `0`.
283 | ELSE.
284 | MOVE abap_value TO json_value.
285 | IF abap_value LT 0.
286 | IF tk <> cl_abap_typedescr=>typekind_float. "float: sign is already at the beginning
287 | SHIFT json_value RIGHT CIRCULAR.
288 | ENDIF.
289 | ELSE.
290 | CONDENSE json_value.
291 | ENDIF.
292 | ENDIF.
293 | WHEN cl_abap_typedescr=>typekind_num.
294 | IF abap_value IS INITIAL.
295 | json_value = `0`.
296 | ELSE.
297 | MOVE abap_value TO json_value.
298 | SHIFT json_value LEFT DELETING LEADING ` 0`.
299 | ENDIF.
300 | WHEN cl_abap_typedescr=>typekind_string OR
301 | cl_abap_typedescr=>typekind_csequence OR
302 | cl_abap_typedescr=>typekind_clike.
303 | IF abap_value IS INITIAL.
304 | json_value = `""`.
305 | ELSE.
306 | MOVE abap_value TO json_value.
307 | escape_string json_value.
308 | CONCATENATE `"` json_value `"` INTO json_value.
309 | ENDIF.
310 | WHEN cl_abap_typedescr=>typekind_xstring OR
311 | cl_abap_typedescr=>typekind_hex.
312 | IF abap_value IS INITIAL.
313 | json_value = `""`.
314 | ELSE.
315 | json_value = xstring_to_string( abap_value ).
316 | escape_string json_value.
317 | CONCATENATE `"` json_value `"` INTO json_value.
318 | ENDIF.
319 | WHEN cl_abap_typedescr=>typekind_char.
320 | IF ol EQ 1 AND c_bool_types CS an.
321 | IF abap_value EQ abap_true.
322 | json_value = `true`. "#EC NOTEXT
323 | ELSE.
324 | json_value = `false`. "#EC NOTEXT
325 | ENDIF.
326 | ELSE.
327 | MOVE abap_value TO json_value.
328 | escape_string json_value.
329 | CONCATENATE `"` json_value `"` INTO json_value.
330 | ENDIF.
331 | WHEN cl_abap_typedescr=>typekind_date.
332 | MOVE abap_value TO json_value.
333 | CONCATENATE `"` json_value(4)
334 | `-` json_value+4(2)
335 | `-` json_value+6(2)
336 | `T00:00:00.0000000Z"` INTO json_value.
337 | WHEN cl_abap_typedescr=>typekind_time.
338 | MOVE abap_value TO json_value.
339 | CONCATENATE `"` json_value(2)
340 | `:` json_value+2(2)
341 | `:` json_value+4(2) `"` INTO json_value.
342 | WHEN OTHERS.
343 | IF abap_value IS INITIAL.
344 | json_value = `null`. "#EC NOTEXT
345 | ELSE.
346 | MOVE abap_value TO json_value.
347 | ENDIF.
348 | ENDCASE.
349 |
350 | ENDMETHOD.
351 |
352 |
353 | METHOD STRING_TO_XSTRING.
354 |
355 | DATA: l_xstring TYPE xstring.
356 |
357 | CALL FUNCTION 'SSFC_BASE64_DECODE'
358 | EXPORTING
359 | b64data = in
360 | IMPORTING
361 | bindata = l_xstring
362 | EXCEPTIONS
363 | OTHERS = 1.
364 |
365 | IF sy-subrc IS INITIAL.
366 | MOVE l_xstring TO out.
367 | ELSE.
368 | MOVE in TO out.
369 | ENDIF.
370 |
371 | ENDMETHOD.
372 |
373 |
374 | METHOD XSTRING_TO_STRING.
375 |
376 | DATA: l_xstring TYPE xstring.
377 |
378 | l_xstring = in.
379 |
380 | CALL FUNCTION 'SSFC_BASE64_ENCODE'
381 | EXPORTING
382 | bindata = l_xstring
383 | IMPORTING
384 | b64data = out
385 | EXCEPTIONS
386 | OTHERS = 1.
387 |
388 | IF sy-subrc IS NOT INITIAL.
389 | MOVE in TO out.
390 | ENDIF.
391 |
392 | ENDMETHOD.
393 | ENDCLASS.
394 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_http_util.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_HTTP_UTIL
7 | 1
8 | E
9 | HTTP Utilities
10 | 2
11 | 1
12 | X
13 | X
14 | X
15 | X
16 |
17 |
18 |
19 | ZABAPFIRE_CL_HTTP_UTIL
20 | ABAP_LCC
21 | E
22 | From ABAP to LowerCamelCase
23 |
24 |
25 | ZABAPFIRE_CL_HTTP_UTIL
26 | C_BOOL_TYPES
27 | E
28 | Boolean types
29 |
30 |
31 | ZABAPFIRE_CL_HTTP_UTIL
32 | LCC_ABAP
33 | E
34 | From lowerCamelCase to ABAP
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_json_deserializer.clas.abap:
--------------------------------------------------------------------------------
1 | CLASS zabapfire_cl_json_deserializer DEFINITION
2 | PUBLIC
3 | FINAL
4 | CREATE PUBLIC .
5 |
6 | PUBLIC SECTION.
7 |
8 | METHODS deserialize
9 | IMPORTING
10 | !json TYPE string
11 | EXPORTING
12 | !abap TYPE any
13 | RAISING
14 | zcx_abapfire_json .
15 | PROTECTED SECTION.
16 | *"* protected components of class CL_TREX_JSON_DESERIALIZER
17 | *"* do not include other source files here!!!
18 | private section.
19 |
20 | types TY_NODE type ref to ZABAPFIRE_CL_JSON_NODE .
21 |
22 | data MV_NAME type STRING .
23 | data:
24 | mt_nodes_stack TYPE TABLE OF ty_node .
25 | data JSON_HIERARCHY type ref to ZABAPFIRE_CL_JSON_NODE .
26 |
27 | *"* private components of class CL_TREX_JSON_DESERIALIZER
28 | *"* do not include other source files here!!!
29 | methods DESERIALIZE_NODE
30 | importing
31 | !JSON type STRING
32 | changing
33 | !OFFSET type I default 0
34 | raising
35 | ZCX_ABAPFIRE_JSON .
36 | methods DESERIALIZE_OBJECT
37 | importing
38 | !JSON type STRING
39 | changing
40 | !OFFSET type I default 0
41 | raising
42 | ZCX_ABAPFIRE_JSON .
43 | methods DESERIALIZE_ARRAY
44 | importing
45 | !JSON type STRING
46 | changing
47 | !OFFSET type I default 0
48 | raising
49 | ZCX_ABAPFIRE_JSON .
50 | methods DESERIALIZE_KEY
51 | importing
52 | !JSON type STRING
53 | changing
54 | !OFFSET type I default 0
55 | raising
56 | ZCX_ABAPFIRE_JSON .
57 | methods SET_NODE_LEVEL
58 | importing
59 | !ADD type ABAP_BOOL optional
60 | !REMOVE type ABAP_BOOL optional
61 | !ARRAY type ABAP_BOOL optional
62 | !VALUE type STRING optional
63 | !TYPE type STRING optional
64 | raising
65 | ZCX_ABAPFIRE_JSON .
66 | methods RECURSE
67 | importing
68 | !NODE type ref to ZABAPFIRE_CL_JSON_NODE
69 | changing
70 | !COMP type ANY
71 | raising
72 | ZCX_ABAPFIRE_JSON .
73 | ENDCLASS.
74 |
75 |
76 |
77 | CLASS ZABAPFIRE_CL_JSON_DESERIALIZER IMPLEMENTATION.
78 |
79 |
80 | METHOD deserialize.
81 |
82 | deserialize_node(
83 | EXPORTING
84 | json = json ).
85 |
86 | recurse(
87 | EXPORTING
88 | node = json_hierarchy
89 | CHANGING
90 | comp = abap ).
91 |
92 | ENDMETHOD.
93 |
94 |
95 | METHOD deserialize_array.
96 | DATA:
97 | l_done TYPE abap_bool.
98 |
99 | ADD 1 TO offset . "skip [
100 |
101 | * Add object node to nodes stack
102 | set_node_level(
103 | EXPORTING
104 | add = abap_true
105 | array = abap_true ).
106 |
107 |
108 | WHILE l_done = abap_false .
109 | deserialize_node(
110 | EXPORTING
111 | json = json
112 | CHANGING
113 | offset = offset ) .
114 |
115 | FIND REGEX ',|\]' IN SECTION OFFSET offset OF json MATCH OFFSET offset .
116 | IF sy-subrc <> 0 .
117 | zcx_abapfire_json=>raise( 'Invalid JSON' ). "#EC NOTEXT
118 | ENDIF .
119 | IF json+offset(1) = ']' .
120 | l_done = abap_true .
121 | set_node_level(
122 | EXPORTING
123 | remove = abap_true ).
124 | ENDIF .
125 | ADD 1 TO offset .
126 | ENDWHILE .
127 |
128 | ENDMETHOD.
129 |
130 |
131 | METHOD deserialize_key.
132 |
133 | DATA:
134 | l_len TYPE i,
135 | l_string TYPE string,
136 | l_number TYPE string,
137 | l_boolean TYPE string,
138 | l_value TYPE string,
139 | l_type TYPE string.
140 |
141 | FIND REGEX
142 | '"((?:\\"|(?!").)*)"|(-{1}\d+|\d+)|(true|false|null)'
143 | IN SECTION OFFSET offset OF json
144 | MATCH OFFSET offset MATCH LENGTH l_len
145 | SUBMATCHES l_string l_number l_boolean.
146 | IF sy-subrc <> 0 .
147 | zcx_abapfire_json=>raise( 'Invalid JSON' ). "#EC NOTEXT
148 | ENDIF .
149 |
150 | CASE json+offset(1) .
151 | WHEN '"' .
152 | l_type = 'string'. "#EC NOTEXT
153 | l_value = l_string.
154 | ADD l_len TO offset .
155 | WHEN 't' OR 'f' OR 'n'.
156 | l_type = 'boolean'. "#EC NOTEXT
157 | l_value = l_boolean.
158 | WHEN OTHERS . "0-9 or negative numbers
159 | l_type = 'number'. "#EC NOTEXT
160 | l_value = l_number.
161 | ENDCASE .
162 |
163 | set_node_level(
164 | EXPORTING
165 | value = l_value
166 | type = l_type
167 | add = abap_true ).
168 | CLEAR mv_name.
169 | * key nodes do not have children
170 | set_node_level(
171 | EXPORTING
172 | remove = abap_true ).
173 |
174 | ENDMETHOD.
175 |
176 |
177 | METHOD deserialize_node.
178 |
179 | FIND REGEX
180 | '\{|\[|"((?:\\"|(?!").)*)"|(-{1}\d+|\d+)|(true|false)|\}|\]'
181 | " (\{) --> capturing group 1 {
182 | " (\[) --> capturing group 2 [
183 | " (["]((?:\\"|(?!").)*)") --> capturing group 3 strings
184 | " (-{1}\d+|\d+) --> capturing group 4 numbers
185 | " (true|false) --> capturing group 5 booleans
186 |
187 | IN SECTION OFFSET offset OF json
188 | MATCH OFFSET offset.
189 |
190 | IF sy-subrc <> 0 .
191 | zcx_abapfire_json=>raise( 'Invalid JSON' ). "#EC NOTEXT
192 | ENDIF .
193 |
194 | CASE json+offset(1) .
195 | WHEN '{' .
196 | deserialize_object(
197 | EXPORTING
198 | json = json
199 | CHANGING
200 | offset = offset ).
201 | WHEN '[' .
202 | deserialize_array(
203 | EXPORTING
204 | json = json
205 | CHANGING
206 | offset = offset ).
207 | WHEN '}' OR ']'.
208 | "Ignore it, while cycle on object or array will be closed
209 | WHEN OTHERS.
210 | deserialize_key(
211 | EXPORTING
212 | json = json
213 | CHANGING
214 | offset = offset ).
215 | ENDCASE .
216 |
217 | ENDMETHOD.
218 |
219 |
220 | METHOD deserialize_object.
221 | DATA:
222 | l_done TYPE abap_bool,
223 | l_len TYPE i.
224 |
225 | ADD 1 TO offset . "skip {
226 |
227 | * Add object node to nodes stack
228 | set_node_level(
229 | EXPORTING
230 | add = abap_true ).
231 |
232 | * handle each component
233 | WHILE l_done = abap_false .
234 | "find next key ("key":)
235 | FIND REGEX '"((?:\\"|(?!").)*)"\s*:'
236 | IN SECTION OFFSET offset OF json
237 | MATCH OFFSET offset MATCH LENGTH l_len
238 | SUBMATCHES mv_name.
239 | IF sy-subrc = 0 .
240 | ADD l_len TO offset.
241 | * remove " from l_name
242 | REPLACE ALL OCCURRENCES OF '"' IN mv_name WITH ''.
243 | * deserialize current component
244 | deserialize_node(
245 | EXPORTING
246 | json = json
247 | CHANGING
248 | offset = offset ).
249 | ENDIF .
250 | FIND REGEX ',|\}'
251 | IN SECTION OFFSET offset OF json
252 | MATCH OFFSET offset .
253 | IF sy-subrc <> 0 .
254 | zcx_abapfire_json=>raise( 'Invalid JSON' ). "#EC NOTEXT
255 | ENDIF .
256 | IF json+offset(1) = '}' .
257 | l_done = abap_true .
258 | set_node_level(
259 | EXPORTING
260 | remove = abap_true ).
261 | ENDIF .
262 | ADD 1 TO offset .
263 | ENDWHILE .
264 |
265 | ENDMETHOD.
266 |
267 |
268 | METHOD recurse.
269 |
270 | DATA:
271 | l_children TYPE zabapfire_cl_json_node=>ty_nodes,
272 | l_node TYPE REF TO zabapfire_cl_json_node,
273 | l_abap_type TYPE REF TO cl_abap_typedescr,
274 | l_name TYPE string,
275 | l_data TYPE REF TO data.
276 | FIELD-SYMBOLS:
277 | TYPE ANY TABLE,
278 | TYPE any,
279 | TYPE any.
280 |
281 |
282 | * Iterate on JSON Hierarchy and fill ABAP type
283 | l_abap_type = cl_abap_typedescr=>describe_by_data( comp ).
284 | IF l_abap_type->kind = cl_abap_typedescr=>kind_table.
285 | * JSON Hierarchy children are table rows
286 | ASSIGN comp TO .
287 | CREATE DATA l_data LIKE LINE OF .
288 | ASSIGN l_data->* TO .
289 | l_children = node->get_children( ).
290 | LOOP AT l_children INTO l_node.
291 | CLEAR .
292 | recurse(
293 | EXPORTING
294 | node = l_node
295 | CHANGING
296 | comp = ).
297 | INSERT INTO TABLE .
298 | ENDLOOP.
299 | ELSEIF l_abap_type->kind = cl_abap_typedescr=>kind_struct.
300 | * JSON Hierarchy children are structure fields
301 | ASSIGN comp TO .
302 | l_children = node->get_children( ).
303 | LOOP AT l_children INTO l_node.
304 | l_name =
305 | zabapfire_cl_http_util=>lcc_abap( l_node->get_name( ) ).
306 | ASSIGN COMPONENT l_name OF STRUCTURE TO .
307 | IF sy-subrc NE 0.
308 | zcx_abapfire_json=>raise( 'Invalid ABAP Target' ). "#EC NOTEXT
309 | ENDIF.
310 | recurse(
311 | EXPORTING
312 | node = l_node
313 | CHANGING
314 | comp = ).
315 | ENDLOOP.
316 | * Check if we have to return object key
317 | ASSIGN COMPONENT '$KEY' OF STRUCTURE TO . "#EX NOTEXT
318 | IF sy-subrc EQ 0.
319 | = node->get_name( ).
320 | ENDIF.
321 | ELSE.
322 | * JSON Hierarchy children are key values
323 | TRY.
324 | zabapfire_cl_http_util=>deserialize_value(
325 | EXPORTING
326 | json_value = node->get_value( )
327 | json_type = node->get_type( )
328 | IMPORTING
329 | abap_value = comp ).
330 | CATCH cx_sy_conversion_error.
331 | zcx_abapfire_json=>raise( 'Invalid ABAP Target' ). "#EC NOTEXT
332 | ENDTRY.
333 | ENDIF.
334 |
335 | ENDMETHOD.
336 |
337 |
338 | METHOD set_node_level.
339 |
340 | DATA:
341 | l_len TYPE i,
342 | l_parent TYPE REF TO zabapfire_cl_json_node,
343 | l_node TYPE REF TO zabapfire_cl_json_node.
344 |
345 | DESCRIBE TABLE mt_nodes_stack LINES l_len.
346 |
347 | IF remove = abap_true.
348 | * Remove last node
349 | IF l_len > 0.
350 | READ TABLE mt_nodes_stack INTO json_hierarchy
351 | INDEX l_len.
352 | DELETE mt_nodes_stack INDEX l_len.
353 | ENDIF.
354 | ENDIF.
355 |
356 | IF add = abap_true.
357 | * Add new node
358 | CREATE OBJECT l_node
359 | EXPORTING
360 | name = mv_name
361 | array = array
362 | value = value
363 | type = type.
364 | * Check if a parent node exists
365 | READ TABLE mt_nodes_stack INTO l_parent
366 | INDEX l_len.
367 | IF l_len > 0.
368 | IF NOT l_parent IS INITIAL.
369 | l_parent->add_child( l_node ).
370 | ENDIF.
371 | ENDIF.
372 | CLEAR mv_name.
373 | APPEND l_node TO mt_nodes_stack.
374 | ENDIF.
375 |
376 | ENDMETHOD.
377 | ENDCLASS.
378 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_json_deserializer.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_JSON_DESERIALIZER
7 | 1
8 | E
9 | Deserialize JSON to ABAP data
10 | 2
11 | 1
12 | X
13 | X
14 | X
15 | X
16 |
17 |
18 |
19 | ZABAPFIRE_CL_JSON_DESERIALIZER
20 | JSON_HIERARCHY
21 | E
22 | JSON Node
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_json_node.clas.abap:
--------------------------------------------------------------------------------
1 | class ZABAPFIRE_CL_JSON_NODE definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 |
8 | types TY_NODE type ref to ZABAPFIRE_CL_JSON_NODE .
9 | types:
10 | ty_nodes TYPE SORTED TABLE OF ty_node
11 | WITH UNIQUE DEFAULT KEY .
12 |
13 | methods CONSTRUCTOR
14 | importing
15 | !NAME type STRING optional
16 | !VALUE type STRING optional
17 | !TYPE type STRING optional
18 | !ARRAY type ABAP_BOOL optional
19 | raising
20 | ZCX_ABAPFIRE_JSON .
21 | methods SET_VALUE
22 | importing
23 | !VALUE type STRING .
24 | methods GET_NAME
25 | returning
26 | value(NAME) type STRING .
27 | methods GET_VALUE
28 | returning
29 | value(VALUE) type STRING .
30 | methods GET_TYPE
31 | returning
32 | value(TYPE) type STRING .
33 | methods ADD_CHILD
34 | importing
35 | !CHILD type ref to ZABAPFIRE_CL_JSON_NODE .
36 | methods GET_CHILDREN
37 | returning
38 | value(CHILDREN) type TY_NODES .
39 | methods IS_ARRAY
40 | returning
41 | value(TRUE) type ABAP_BOOL .
42 | protected section.
43 | private section.
44 |
45 | data MV_NAME type STRING .
46 | data MV_VALUE type STRING .
47 | data MV_ARRAY type ABAP_BOOL .
48 | data MV_TYPE type STRING .
49 | data MT_CHILDREN type TY_NODES .
50 | ENDCLASS.
51 |
52 |
53 |
54 | CLASS ZABAPFIRE_CL_JSON_NODE IMPLEMENTATION.
55 |
56 |
57 | METHOD add_child.
58 |
59 | INSERT child INTO TABLE mt_children.
60 |
61 | ENDMETHOD.
62 |
63 |
64 | METHOD constructor.
65 |
66 | mv_name = name.
67 | mv_value = value.
68 | mv_array = array.
69 | mv_type = type.
70 |
71 | ENDMETHOD.
72 |
73 |
74 | METHOD get_children.
75 |
76 | children = mt_children.
77 |
78 | ENDMETHOD.
79 |
80 |
81 | METHOD get_name.
82 |
83 | name = mv_name.
84 |
85 | ENDMETHOD.
86 |
87 |
88 | METHOD get_type.
89 |
90 | type = mv_type.
91 |
92 | ENDMETHOD.
93 |
94 |
95 | METHOD get_value.
96 |
97 | value = mv_value.
98 |
99 | ENDMETHOD.
100 |
101 |
102 | METHOD is_array.
103 |
104 | true = mv_array.
105 |
106 | ENDMETHOD.
107 |
108 |
109 | METHOD set_value.
110 |
111 | mv_value = value.
112 |
113 | ENDMETHOD.
114 | ENDCLASS.
115 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_json_node.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_JSON_NODE
7 | 1
8 | E
9 | JSON Node
10 | 2
11 | 1
12 | X
13 | X
14 | X
15 | X
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_json_serializer.clas.abap:
--------------------------------------------------------------------------------
1 | class ZABAPFIRE_CL_JSON_SERIALIZER definition
2 | public
3 | final
4 | create public .
5 |
6 | public section.
7 |
8 | *"* public components of class CL_TREX_JSON_SERIALIZER
9 | *"* do not include other source files here!!!
10 | class-methods CLASS_CONSTRUCTOR .
11 | methods SERIALIZE
12 | importing
13 | !ABAP type ANY
14 | returning
15 | value(JSON) type STRING
16 | raising
17 | ZCX_ABAPFIRE_JSON .
18 | protected section.
19 | *"* protected components of class ZL_ASXML_TO_JSON
20 | *"* do not include other source files here!!!
21 | private section.
22 |
23 | class-data C_COLON type STRING .
24 | class-data C_COMMA type STRING .
25 | data:
26 | mt_lines TYPE TABLE OF string .
27 | data JSON_HIERARCHY type ref to ZABAPFIRE_CL_JSON_NODE .
28 |
29 | methods RECURSE
30 | importing
31 | !COMP type DATA
32 | !NAME type STRING optional
33 | changing
34 | !NODE type ref to ZABAPFIRE_CL_JSON_NODE optional
35 | raising
36 | ZCX_ABAPFIRE_JSON .
37 | methods WRITE_JSON
38 | changing
39 | !JSON type STRING
40 | raising
41 | ZCX_ABAPFIRE_JSON .
42 | methods RECURSE_JSON
43 | importing
44 | !NODE type ref to ZABAPFIRE_CL_JSON_NODE
45 | raising
46 | ZCX_ABAPFIRE_JSON .
47 | ENDCLASS.
48 |
49 |
50 |
51 | CLASS ZABAPFIRE_CL_JSON_SERIALIZER IMPLEMENTATION.
52 |
53 |
54 | method CLASS_CONSTRUCTOR.
55 |
56 | cl_abap_string_utilities=>c2str_preserving_blanks(
57 | exporting source = ': '
58 | importing dest = c_colon ) .
59 | cl_abap_string_utilities=>c2str_preserving_blanks(
60 | exporting source = ', '
61 | importing dest = c_comma ) .
62 |
63 | endmethod.
64 |
65 |
66 | METHOD recurse.
67 |
68 | DATA:
69 | l_node TYPE REF TO zabapfire_cl_json_node,
70 | l_abap_type TYPE REF TO cl_abap_typedescr,
71 | l_abap_stru TYPE REF TO cl_abap_structdescr,
72 | l_component TYPE abap_compdescr,
73 | l_rec TYPE REF TO data,
74 | l_name TYPE string.
75 | FIELD-SYMBOLS:
76 | TYPE ANY TABLE,
77 | TYPE any,
78 | TYPE any.
79 |
80 | l_abap_type = cl_abap_typedescr=>describe_by_data( comp ).
81 |
82 | * Create current node
83 | CHECK NOT name CA '$#[]/'. "In case ABAP strucutre contains a $KEY
84 |
85 | IF NOT name IS INITIAL.
86 | l_name = zabapfire_cl_http_util=>abap_lcc( name ).
87 | CONCATENATE '"' l_name '"' INTO l_name.
88 | ENDIF.
89 | IF l_abap_type->kind = cl_abap_typedescr=>kind_table.
90 | CREATE OBJECT l_node
91 | EXPORTING
92 | name = l_name
93 | array = abap_true.
94 | ELSE.
95 | CREATE OBJECT l_node
96 | EXPORTING
97 | name = l_name.
98 | ENDIF.
99 | * Add node to father if it exists
100 | IF node IS BOUND.
101 | node->add_child( l_node ).
102 | ENDIF.
103 | * Set first node of hierarchy
104 | IF NOT json_hierarchy IS BOUND.
105 | json_hierarchy = l_node.
106 | ENDIF.
107 |
108 | * Iterate on ABAP and build JSON Hierarchy
109 | IF l_abap_type->kind = cl_abap_typedescr=>kind_table.
110 | * ABAP Table
111 | ASSIGN comp TO .
112 | CREATE DATA l_rec LIKE LINE OF .
113 | ASSIGN l_rec->* TO .
114 | LOOP AT INTO .
115 | recurse(
116 | EXPORTING
117 | comp =
118 | CHANGING
119 | node = l_node ).
120 | ENDLOOP.
121 | ELSEIF l_abap_type->kind = cl_abap_typedescr=>kind_struct.
122 | * ABAP Structure
123 | l_abap_stru ?= cl_abap_typedescr=>describe_by_data( comp ).
124 | LOOP AT l_abap_stru->components INTO l_component.
125 | l_name = l_component-name.
126 | ASSIGN COMPONENT l_name OF STRUCTURE comp TO .
127 | recurse(
128 | EXPORTING
129 | comp =
130 | name = l_name
131 | CHANGING
132 | node = l_node ).
133 | ENDLOOP.
134 | ELSE.
135 | l_node->set_value(
136 | zabapfire_cl_http_util=>serialize_value( comp )
137 | ).
138 | ENDIF.
139 |
140 | ENDMETHOD.
141 |
142 |
143 | METHOD recurse_json.
144 |
145 | DATA:
146 | l_children TYPE zabapfire_cl_json_node=>ty_nodes,
147 | l_node TYPE REF TO zabapfire_cl_json_node,
148 | l_len TYPE i,
149 | l_index TYPE i,
150 | l_name TYPE string,
151 | l_value TYPE string.
152 |
153 | l_children = node->get_children( ).
154 | l_name = node->get_name( ).
155 | l_value = node->get_value( ).
156 |
157 | l_len = lines( l_children ).
158 |
159 | IF NOT l_name IS INITIAL.
160 | APPEND l_name TO mt_lines.
161 | APPEND c_colon TO mt_lines.
162 | ENDIF.
163 |
164 | IF node->is_array( ) = abap_true.
165 | * Array
166 | APPEND '[' TO mt_lines.
167 | LOOP AT l_children INTO l_node.
168 | ADD 1 TO l_index .
169 | recurse_json( l_node ).
170 | IF l_index < l_len .
171 | APPEND c_comma TO mt_lines.
172 | ENDIF .
173 | ENDLOOP.
174 | APPEND ']' TO mt_lines .
175 | ELSEIF l_len > 0.
176 | * Object
177 | APPEND '{' TO mt_lines.
178 | LOOP AT l_children INTO l_node.
179 | ADD 1 TO l_index .
180 | recurse_json( l_node ).
181 | IF l_index < l_len .
182 | APPEND c_comma TO mt_lines.
183 | ENDIF .
184 | ENDLOOP.
185 | APPEND '}' TO mt_lines .
186 | ELSE.
187 | * Scalar value
188 | APPEND l_value TO mt_lines.
189 | ENDIF.
190 |
191 | ENDMETHOD.
192 |
193 |
194 | METHOD serialize.
195 |
196 | recurse(
197 | EXPORTING comp = abap ) .
198 |
199 | write_json(
200 | CHANGING
201 | json = json ).
202 |
203 | ENDMETHOD.
204 |
205 |
206 | METHOD write_json.
207 |
208 | recurse_json( json_hierarchy ).
209 |
210 | CONCATENATE LINES OF mt_lines INTO json .
211 |
212 | ENDMETHOD.
213 | ENDCLASS.
214 |
--------------------------------------------------------------------------------
/src/zabapfire_cl_json_serializer.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_CL_JSON_SERIALIZER
7 | 1
8 | E
9 | Serialize ABAP data into JSON format
10 | 2
11 | 1
12 | X
13 | X
14 | X
15 | X
16 |
17 |
18 |
19 | ZABAPFIRE_CL_JSON_SERIALIZER
20 | CLASS_CONSTRUCTOR
21 | E
22 | CLASS_CONSTRUCTOR
23 |
24 |
25 | ZABAPFIRE_CL_JSON_SERIALIZER
26 | JSON_HIERARCHY
27 | E
28 | JSON Node
29 |
30 |
31 | ZABAPFIRE_CL_JSON_SERIALIZER
32 | RECURSE_JSON
33 | E
34 | todo
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/zabapfire_demo.prog.abap:
--------------------------------------------------------------------------------
1 | *&---------------------------------------------------------------------*
2 | *& Report zabapfire_demo
3 | *&---------------------------------------------------------------------*
4 | *&
5 | *&---------------------------------------------------------------------*
6 | REPORT zabapfire_demo.
7 | TYPE-POOLS : slis.
8 | DATA:
9 | firebase TYPE REF TO zabapfire_cl_firebase,
10 | lcx_firebase TYPE REF TO zcx_abapfire_firebase,
11 | ls_config TYPE zabapfire_cl_firebase=>ty_firebase_config.
12 |
13 | PARAMETERS:
14 | p_email TYPE string LOWER CASE,
15 | p_pass TYPE string LOWER CASE,
16 | p_path TYPE string LOWER CASE DEFAULT '/flights' OBLIGATORY,
17 | p_get TYPE char1 RADIOBUTTON GROUP rb1 DEFAULT 'X',
18 | p_set TYPE char1 RADIOBUTTON GROUP rb1,
19 | p_push TYPE char1 RADIOBUTTON GROUP rb1,
20 | p_del TYPE char1 RADIOBUTTON GROUP rb1.
21 |
22 | AT SELECTION-SCREEN OUTPUT.
23 |
24 | LOOP AT SCREEN.
25 | IF screen-name = 'P_PASS'.
26 | screen-invisible = '1'.
27 | MODIFY SCREEN.
28 | ENDIF.
29 | ENDLOOP.
30 |
31 | START-OF-SELECTION.
32 |
33 | **********************************************************************
34 | * Initialize App
35 | **********************************************************************
36 | ls_config-apikey = '[your_apikey]'.
37 | ls_config-authdomain = '[your_authdomain]'.
38 | ls_config-databaseurl = '[your_databaseurl]'.
39 | ls_config-messagingsenderid = '[your_messagingsenderid]'.
40 | ls_config-projectid = '[your_projectid]'.
41 | ls_config-storagebucket = '[your_storagebucket]'.
42 |
43 | TRY.
44 | firebase = zabapfire_cl_firebase=>initialize_app( ls_config ).
45 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
46 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
47 | DISPLAY LIKE 'E'.
48 | EXIT.
49 | ENDTRY.
50 |
51 | **********************************************************************
52 | * Authenticate
53 | **********************************************************************
54 | TRY.
55 | firebase->auth->authenticate_with_email(
56 | EXPORTING
57 | email = p_email
58 | password = p_pass ).
59 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
60 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
61 | DISPLAY LIKE 'E'.
62 | EXIT.
63 | ENDTRY.
64 |
65 | **********************************************************************
66 | * Get data
67 | **********************************************************************
68 | TYPES:
69 | BEGIN OF ty_abap,
70 | $key TYPE string,
71 | carrid TYPE s_carr_id,
72 | connid TYPE s_conn_id,
73 | fldate TYPE s_date,
74 | planetype TYPE s_planetye,
75 | deptime TYPE s_dep_time,
76 | cityfrom TYPE s_from_cit,
77 | airpfrom TYPE s_fromairp,
78 | cityto TYPE s_to_city,
79 | airpto TYPE s_toairp,
80 | carrname TYPE s_carrname,
81 | END OF ty_abap.
82 | DATA:
83 | ls_parameters TYPE zabapfire_cl_firebase_db=>ty_get_parameters,
84 | lt_abap TYPE TABLE OF ty_abap,
85 | ls_fc TYPE slis_fieldcat_alv,
86 | lt_fc TYPE slis_t_fieldcat_alv.
87 |
88 | FIELD-SYMBOLS:
89 | TYPE ty_abap.
90 |
91 | IF p_get = abap_true.
92 | TRY.
93 | ls_parameters-order_by = 'carrid'.
94 | ls_parameters-equal_to = 'AC'.
95 | firebase->db->get(
96 | EXPORTING
97 | path = p_path
98 | parameters = ls_parameters
99 | IMPORTING
100 | child = lt_abap ).
101 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
102 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
103 | DISPLAY LIKE 'E'.
104 | EXIT.
105 | ENDTRY.
106 | ELSEIF p_del = abap_true.
107 | TRY.
108 | firebase->db->remove(
109 | EXPORTING
110 | path = p_path ).
111 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
112 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
113 | DISPLAY LIKE 'E'.
114 | EXIT.
115 | ENDTRY.
116 | ELSE.
117 | SELECT
118 | sflight~carrid AS carrid
119 | sflight~connid AS connid
120 | sflight~fldate AS fldate
121 | sflight~planetype AS planetype
122 | spfli~deptime AS deptime
123 | spfli~cityfrom AS cityfrom
124 | spfli~airpfrom AS airpfrom
125 | spfli~cityto AS cityto
126 | spfli~airpto AS airpto
127 | scarr~carrname AS carrname
128 | FROM sflight
129 | INNER JOIN spfli ON spfli~carrid = sflight~carrid AND
130 | spfli~connid = sflight~connid
131 | INNER JOIN scarr ON scarr~carrid = sflight~carrid
132 | INTO CORRESPONDING FIELDS OF TABLE lt_abap.
133 |
134 | IF p_set = abap_true.
135 | TRY.
136 | firebase->db->set(
137 | EXPORTING
138 | path = p_path
139 | child = lt_abap ).
140 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
141 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
142 | DISPLAY LIKE 'E'.
143 | EXIT.
144 | ENDTRY.
145 | ELSE.
146 | TRY.
147 | LOOP AT lt_abap ASSIGNING .
148 | -$key = firebase->db->push(
149 | EXPORTING
150 | path = p_path
151 | child = ).
152 | ENDLOOP.
153 | CATCH zcx_abapfire_firebase INTO lcx_firebase.
154 | MESSAGE i000(zabapfire_msg) WITH lcx_firebase->get_text( )
155 | DISPLAY LIKE 'E'.
156 | EXIT.
157 | ENDTRY.
158 | ENDIF.
159 | ENDIF.
160 |
161 | ls_fc-fieldname = '$KEY'.
162 | ls_fc-seltext_m = 'Firebase key'.
163 | ls_fc-lowercase = abap_true.
164 | APPEND ls_fc TO lt_fc. CLEAR ls_fc.
165 | ls_fc-fieldname = 'CARRID'.
166 | ls_fc-seltext_m = 'Carrier Id'.
167 | APPEND ls_fc TO lt_fc.
168 | ls_fc-fieldname = 'CONNID'.
169 | ls_fc-seltext_m = 'Connection Id'.
170 | APPEND ls_fc TO lt_fc.
171 |
172 | CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
173 | EXPORTING
174 | it_fieldcat = lt_fc
175 | TABLES
176 | t_outtab = lt_abap
177 | EXCEPTIONS
178 | program_error = 1
179 | OTHERS = 2.
180 |
--------------------------------------------------------------------------------
/src/zabapfire_demo.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_DEMO
7 | A
8 | X
9 | S
10 | 1
11 | X
12 | D$S
13 | X
14 |
15 |
16 | -
17 | R
18 | ABAP Fire Demo Program
19 | 22
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/zabapfire_msg.msag.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZABAPFIRE_MSG
7 | E
8 | ABAPFire messages
9 |
10 |
11 |
12 | E
13 | ZABAPFIRE_MSG
14 | 000
15 | &
16 |
17 |
18 | E
19 | ZABAPFIRE_MSG
20 | 001
21 | &&
22 |
23 |
24 | E
25 | ZABAPFIRE_MSG
26 | 002
27 | &&&
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/src/zcx_abapfire_firebase.clas.abap:
--------------------------------------------------------------------------------
1 | class ZCX_ABAPFIRE_FIREBASE definition
2 | public
3 | inheriting from CX_STATIC_CHECK
4 | final
5 | create public .
6 |
7 | public section.
8 |
9 | interfaces IF_T100_MESSAGE .
10 |
11 | data RAISE_ATTR1 type STRING .
12 |
13 | methods CONSTRUCTOR
14 | importing
15 | !TEXTID like IF_T100_MESSAGE=>T100KEY optional
16 | !PREVIOUS like PREVIOUS optional
17 | !RAISE_ATTR1 type STRING optional .
18 | class-methods RAISE
19 | importing
20 | !IV_TEXT type CLIKE
21 | raising
22 | ZCX_ABAPFIRE_FIREBASE .
23 | PROTECTED SECTION.
24 | PRIVATE SECTION.
25 | ENDCLASS.
26 |
27 |
28 |
29 | CLASS ZCX_ABAPFIRE_FIREBASE IMPLEMENTATION.
30 |
31 |
32 | method CONSTRUCTOR.
33 | CALL METHOD SUPER->CONSTRUCTOR
34 | EXPORTING
35 | PREVIOUS = PREVIOUS
36 | .
37 | me->RAISE_ATTR1 = RAISE_ATTR1 .
38 | clear me->textid.
39 | if textid is initial.
40 | IF_T100_MESSAGE~T100KEY = IF_T100_MESSAGE=>DEFAULT_TEXTID.
41 | else.
42 | IF_T100_MESSAGE~T100KEY = TEXTID.
43 | endif.
44 | endmethod.
45 |
46 |
47 | METHOD raise.
48 |
49 | DATA: BEGIN OF lv_msg,
50 | msgid TYPE symsgid VALUE 'ZABAPFIRE_MSG',
51 | msgno TYPE symsgno VALUE '000',
52 | attr1 TYPE scx_attrname VALUE 'RAISE_ATTR1',
53 | attr2 TYPE scx_attrname VALUE '',
54 | attr3 TYPE scx_attrname VALUE '',
55 | attr4 TYPE scx_attrname VALUE '',
56 | END OF lv_msg .
57 |
58 | RAISE EXCEPTION TYPE zcx_abapfire_firebase
59 | EXPORTING
60 | textid = lv_msg
61 | raise_attr1 = iv_text.
62 |
63 | ENDMETHOD.
64 | ENDCLASS.
65 |
--------------------------------------------------------------------------------
/src/zcx_abapfire_firebase.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCX_ABAPFIRE_FIREBASE
7 | 1
8 | E
9 | Exceptions
10 | 40
11 | 2
12 | 1
13 | X
14 | X
15 | X
16 | X
17 |
18 |
19 |
20 | ZCX_ABAPFIRE_FIREBASE
21 | CONSTRUCTOR
22 | E
23 | CONSTRUCTOR
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/src/zcx_abapfire_json.clas.abap:
--------------------------------------------------------------------------------
1 | class ZCX_ABAPFIRE_JSON definition
2 | public
3 | inheriting from CX_STATIC_CHECK
4 | final
5 | create public .
6 |
7 | public section.
8 |
9 | interfaces IF_T100_MESSAGE .
10 |
11 | data RAISE_ATTR1 type STRING .
12 |
13 | methods CONSTRUCTOR
14 | importing
15 | !TEXTID like IF_T100_MESSAGE=>T100KEY optional
16 | !PREVIOUS like PREVIOUS optional
17 | !RAISE_ATTR1 type STRING optional .
18 | class-methods RAISE
19 | importing
20 | !IV_TEXT type CLIKE
21 | raising
22 | ZCX_ABAPFIRE_JSON .
23 | PROTECTED SECTION.
24 | PRIVATE SECTION.
25 | ENDCLASS.
26 |
27 |
28 |
29 | CLASS ZCX_ABAPFIRE_JSON IMPLEMENTATION.
30 |
31 |
32 | method CONSTRUCTOR ##ADT_SUPPRESS_GENERATION.
33 | CALL METHOD SUPER->CONSTRUCTOR
34 | EXPORTING
35 | PREVIOUS = PREVIOUS
36 | .
37 | me->RAISE_ATTR1 = RAISE_ATTR1 .
38 | clear me->textid.
39 | if textid is initial.
40 | IF_T100_MESSAGE~T100KEY = IF_T100_MESSAGE=>DEFAULT_TEXTID.
41 | else.
42 | IF_T100_MESSAGE~T100KEY = TEXTID.
43 | endif.
44 | endmethod.
45 |
46 |
47 | METHOD raise.
48 |
49 | DATA: BEGIN OF lv_msg,
50 | msgid TYPE symsgid VALUE 'ZABAPFIRE_MSG',
51 | msgno TYPE symsgno VALUE '000',
52 | attr1 TYPE scx_attrname VALUE 'RAISE_ATTR1',
53 | attr2 TYPE scx_attrname VALUE '',
54 | attr3 TYPE scx_attrname VALUE '',
55 | attr4 TYPE scx_attrname VALUE '',
56 | END OF lv_msg .
57 |
58 | RAISE EXCEPTION TYPE zcx_abapfire_json
59 | EXPORTING
60 | textid = lv_msg
61 | raise_attr1 = iv_text.
62 |
63 | ENDMETHOD.
64 | ENDCLASS.
65 |
--------------------------------------------------------------------------------
/src/zcx_abapfire_json.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | ZCX_ABAPFIRE_JSON
7 | 1
8 | E
9 | Exceptions
10 | 40
11 | 2
12 | 1
13 | X
14 | X
15 | X
16 | X
17 |
18 |
19 |
20 | ZCX_ABAPFIRE_JSON
21 | CONSTRUCTOR
22 | E
23 | CONSTRUCTOR
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------