├── README.md
├── src
├── package.devc.xml
├── yui5_repository_load.fugr.lyui5_repository_loadtop.abap
├── yhttp_test.prog.xml
├── yui5_repository_load.fugr.lyui5_repository_loadd01.xml
├── yui5_repository_load.fugr.lyui5_repository_loadp01.xml
├── ygithub_deploy_test.prog.xml
├── ygithub_deploy_ui5_repository.prog.xml
├── yui5_repository_load.fugr.lyui5_repository_loadtop.xml
├── ycl_github_webhook_handler.clas.xml
├── yui5_repository_load.fugr.saplyui5_repository_load.abap
├── ycl_github_deployer.clas.xml
├── ygithub_deploy_ui5_repository.prog.abap
├── ygithub_deploy_test.prog.abap
├── yhttp_test.prog.abap
├── yui5_repository_load.fugr.xml
├── yui5_repository_load.fugr.saplyui5_repository_load.xml
├── ycl_github_webhook_handler.clas.abap
├── yui5_repository_load.fugr.lyui5_repository_loadd01.abap
├── yui5_repository_load.fugr.yui5_repository_load_http.abap
├── ycl_github_deployer.clas.abap
└── yui5_repository_load.fugr.lyui5_repository_loadp01.abap
└── .abapgit.xml
/README.md:
--------------------------------------------------------------------------------
1 | # sapui5-deployer
2 | ABAP deployment of SAPUI5 apps from Githib
3 |
4 | http://yelcho.github.io/sapui5-deployer/
5 |
--------------------------------------------------------------------------------
/src/package.devc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SAPUI5 Deployer
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.lyui5_repository_loadtop.abap:
--------------------------------------------------------------------------------
1 | FUNCTION-POOL YUI5_REPOSITORY_LOAD. "MESSAGE-ID ..
2 |
3 | type-pools abap.
4 |
5 | CONSTANTS: status_success TYPE char1 VALUE 'S',
6 | status_warning TYPE char1 VALUE 'W',
7 | status_error TYPE char1 VALUE 'E'.
8 | INCLUDE LYUI5_REPOSITORY_LOADD01. "for local class definitions
9 |
--------------------------------------------------------------------------------
/.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 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/yhttp_test.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | YHTTP_TEST
7 | 1
8 | E
9 | X
10 | X
11 |
12 |
13 | -
14 | R
15 | HTTP Test
16 | 9
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.lyui5_repository_loadd01.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | LYUI5_REPOSITORY_LOADD01
7 | I
8 | S
9 | E
10 | X
11 |
12 |
13 | -
14 | R
15 | Include /UI5/LUI5_REPOSITORY_LOADD01
16 | 36
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.lyui5_repository_loadp01.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | LYUI5_REPOSITORY_LOADP01
7 | I
8 | S
9 | E
10 | X
11 |
12 |
13 | -
14 | R
15 | Include /UI5/LUI5_REPOSITORY_LOADP01
16 | 36
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/ygithub_deploy_test.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | YGITHUB_DEPLOY_TEST
7 | 1
8 | E
9 | X
10 | X
11 |
12 |
13 | -
14 | R
15 | Test deployment of SAPUI5 app from GitHub
16 | 41
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/ygithub_deploy_ui5_repository.prog.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | YGITHUB_DEPLOY_UI5_REPOSITORY
7 | 1
8 | E
9 | X
10 | X
11 |
12 |
13 | -
14 | R
15 | Program YGITHUB_DEPLOY_UI5_REPOSITORY
16 | 37
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.lyui5_repository_loadtop.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | LYUI5_REPOSITORY_LOADTOP
7 | S
8 | D$
9 | I
10 | S
11 | E
12 | X
13 | D$S
14 | X
15 |
16 |
17 | -
18 | R
19 | Include /UI5/LUI5_REPOSITORY_LOADP01
20 | 36
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/ycl_github_webhook_handler.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | YCL_GITHUB_WEBHOOK_HANDLER
7 | E
8 | GitHub webhook ICF handler
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 | YCL_GITHUB_WEBHOOK_HANDLER
17 | MT_GITHUB_FIELDS
18 | E
19 | HTTP Framework (iHTTP) Table Name/Value Pairs
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.saplyui5_repository_load.abap:
--------------------------------------------------------------------------------
1 | *******************************************************************
2 | * System-defined Include-files. *
3 | *******************************************************************
4 | INCLUDE LYUI5_REPOSITORY_LOADTOP. " Global Data
5 | INCLUDE LYUI5_REPOSITORY_LOADUXX. " Function Modules
6 |
7 | *******************************************************************
8 | * User-defined Include-files (if necessary). *
9 | *******************************************************************
10 | * INCLUDE /UI5/LUI5_REPOSITORY_LOADF... " Subprograms
11 | * INCLUDE /UI5/LUI5_REPOSITORY_LOADO... " PBO-Modules
12 | * INCLUDE /UI5/LUI5_REPOSITORY_LOADI... " PAI-Modules
13 |
14 | INCLUDE LYUI5_REPOSITORY_LOADP01.
15 | *INCLUDE /UI5/LUI5_REPOSITORY_LOADP01. "for local class implementations
16 |
--------------------------------------------------------------------------------
/src/ycl_github_deployer.clas.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | YCL_GITHUB_DEPLOYER
7 | E
8 | Deploy SAPUI5 apps from GitHub
9 | 1
10 | X
11 | X
12 | X
13 |
14 |
15 |
16 | YCL_GITHUB_DEPLOYER
17 | CSS_MINIFY_PARAMS
18 | E
19 | HTTP Framework (iHTTP) Table Name/Value Pairs
20 |
21 |
22 | YCL_GITHUB_DEPLOYER
23 | JS_MINIFY_PARAMS
24 | E
25 | HTTP Framework (iHTTP) Table Name/Value Pairs
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/src/ygithub_deploy_ui5_repository.prog.abap:
--------------------------------------------------------------------------------
1 | *&---------------------------------------------------------------------*
2 | *& Report YGITHUB_DEPLOY_UI5_REPOSITORY
3 | *&---------------------------------------------------------------------*
4 | *&
5 | *&---------------------------------------------------------------------*
6 | REPORT ygithub_deploy_ui5_repository line-SIZE 120.
7 |
8 | DATA: exc TYPE REF TO cx_root.
9 |
10 | SELECTION-SCREEN BEGIN OF BLOCK blk_main.
11 | PARAMETERS:
12 | git_repo TYPE string OBLIGATORY LOWER CASE,
13 | branch TYPE string OBLIGATORY LOWER CASE DEFAULT `master`,
14 | username TYPE string VISIBLE LENGTH 15 LOWER CASE,
15 | password TYPE string VISIBLE LENGTH 15 LOWER CASE,
16 | tranport TYPE trkorr,
17 | test TYPE boolean DEFAULT 'X'.
18 | SELECTION-SCREEN END OF BLOCK blk_main.
19 |
20 | START-OF-SELECTION.
21 |
22 | TRY.
23 | ycl_github_deployer=>deploy(
24 | repository = git_repo
25 | branch = branch
26 | github_user = username
27 | password = password
28 | transport = tranport
29 | test_only = test ).
30 | CATCH cx_root INTO exc.
31 | MESSAGE exc TYPE 'I' DISPLAY LIKE 'E'.
32 | ENDTRY.
33 |
--------------------------------------------------------------------------------
/src/ygithub_deploy_test.prog.abap:
--------------------------------------------------------------------------------
1 | *&---------------------------------------------------------------------*
2 | *& Report YGITHUB_DEPLOY_TEST
3 | *&---------------------------------------------------------------------*
4 | *&
5 | *&---------------------------------------------------------------------*
6 | REPORT ygithub_deploy_test.
7 |
8 | *--------------------------------------------------------------------*
9 | * This program tests deployment of a GitHub SAPUI5 repository
10 | *
11 | * Check https://github.com/grahamrobbo/demojam to see the repo
12 | * that will be deployted. This is a public repo so no user
13 | * credentials are required.
14 | *
15 | * Note in the .Ui5RepositoryUploadParameters file where the settings
16 | * for this app are defined.
17 | *
18 | * SAPUI5ApplicationName=ZDEMOJAM
19 | * SAPUI5ApplicationPackage=$TMP
20 | * SAPUI5ApplicationDescription=Simple SAPUI5 App
21 | * ExternalCodePage=Cp1252
22 | * AcceptUnixStyleEol=True
23 | * DeltaMode=False
24 | *
25 | * If you want to change these parameters, for example to give the app
26 | * a different name, clone the repo and make changes in your own copy.
27 | *--------------------------------------------------------------------*
28 |
29 | SELECTION-SCREEN BEGIN OF BLOCK blk_main.
30 | PARAMETERS:
31 | user TYPE string LOWER CASE
32 | DEFAULT ``,
33 | password TYPE string LOWER CASE
34 | DEFAULT ``,
35 | repo TYPE string OBLIGATORY LOWER CASE
36 | DEFAULT `grahamrobbo/demojam`,
37 | branch TYPE string OBLIGATORY LOWER CASE
38 | DEFAULT `master`,
39 | test TYPE boolean DEFAULT 'X'.
40 | SELECTION-SCREEN END OF BLOCK blk_main.
41 |
42 | START-OF-SELECTION.
43 |
44 | TRY.
45 | ycl_github_deployer=>deploy(
46 | github_user = user
47 | password = password
48 | repository = repo
49 | branch = branch
50 | test_only = test ).
51 | CATCH cx_root INTO DATA(exc).
52 | MESSAGE exc TYPE 'I' DISPLAY LIKE 'E'.
53 | ENDTRY.
54 |
--------------------------------------------------------------------------------
/src/yhttp_test.prog.abap:
--------------------------------------------------------------------------------
1 | *&---------------------------------------------------------------------*
2 | *& Report YHTTP_TEST
3 | *&---------------------------------------------------------------------*
4 | *&
5 | *&---------------------------------------------------------------------*
6 | REPORT yhttp_test.
7 | *--------------------------------------------------------------------*
8 | * Simple test to ensure we can talk to GitHub.
9 | *--------------------------------------------------------------------*
10 |
11 | DATA: lr_client TYPE REF TO if_http_client.
12 |
13 | cl_http_client=>create_by_url(
14 | EXPORTING
15 | url = 'https://github.com/'
16 | ssl_id = 'ANONYM'
17 | IMPORTING
18 | client = lr_client
19 | EXCEPTIONS
20 | argument_not_found = 1
21 | plugin_not_active = 2
22 | internal_error = 3
23 | OTHERS = 4 ).
24 | IF sy-subrc <> 0.
25 | CASE sy-subrc.
26 | WHEN 1.
27 | " make sure:
28 | " a) SSL is setup properly in STRUST
29 | DATA(lv_message) = 'HTTPS ARGUMENT_NOT_FOUND | STRUST/SSL Setup correct?'. "#EC NOTEXT
30 | WHEN OTHERS.
31 | lv_message = 'While creating HTTP Client'. "#EC NOTEXT
32 |
33 | ENDCASE.
34 | WRITE:/, lv_message COLOR COL_NEGATIVE.
35 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
36 | RETURN.
37 | ENDIF.
38 |
39 | lr_client->send( EXCEPTIONS OTHERS = 1 ).
40 | IF sy-subrc <> 0.
41 | lv_message = |http send error|.
42 | WRITE:/, lv_message COLOR COL_NEGATIVE.
43 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
44 | RETURN.
45 | ENDIF.
46 | lr_client->receive(
47 | EXCEPTIONS
48 | http_communication_failure = 1
49 | http_invalid_state = 2
50 | http_processing_failed = 3
51 | OTHERS = 4 ).
52 | IF sy-subrc <> 0.
53 | CASE sy-subrc.
54 | WHEN 1.
55 | " make sure:
56 | " a) SSL is setup properly in STRUST
57 | " b) no firewalls
58 | " check trace file in transaction SMICM
59 | lv_message = 'HTTP Communication Failure'. "#EC NOTEXT
60 | WHEN 2.
61 | lv_message = 'HTTP Invalid State'. "#EC NOTEXT
62 | WHEN 3.
63 | lv_message = 'HTTP Processing failed'. "#EC NOTEXT
64 | WHEN OTHERS.
65 | lv_message = 'Another error occured'. "#EC NOTEXT
66 | ENDCASE.
67 | WRITE:/, lv_message COLOR COL_NEGATIVE.
68 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
69 | RETURN.
70 | ENDIF.
71 |
72 | lr_client->response->get_status( IMPORTING code = DATA(lv_code) ).
73 |
74 | IF lv_code NE 200.
75 | IF lv_message IS INITIAL.
76 | lv_message = |HTTP Return Code is { lv_code }|. "#EC NOTEXT
77 | ENDIF.
78 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
79 | ELSE.
80 | MESSAGE |All okay| TYPE 'I' DISPLAY LIKE 'I'.
81 | ENDIF.
82 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SAPUI5 Repository Load
6 |
7 | LYUI5_REPOSITORY_LOADD01
8 | LYUI5_REPOSITORY_LOADP01
9 | LYUI5_REPOSITORY_LOADTOP
10 | SAPLYUI5_REPOSITORY_LOAD
11 |
12 |
13 | -
14 | YUI5_REPOSITORY_LOAD_HTTP
15 | R
16 | SAPUI5 Repository Upload via HTTP Protocoll
17 |
18 |
19 | IV_URL
20 | STRING
21 |
22 |
23 | IV_SAPUI5_APPLICATION_NAME
24 | ''
25 | X
26 | STRING
27 |
28 |
29 | IV_SAPUI5_APPLICATION_DESC
30 | ''
31 | X
32 | STRING
33 |
34 |
35 | IV_PACKAGE
36 | ''
37 | X
38 | DEVCLASS
39 |
40 |
41 | IV_WORKBENCH_REQUEST
42 | ''
43 | X
44 | TRKORR
45 |
46 |
47 | IV_EXTERNAL_CODE_PAGE
48 | ''
49 | X
50 | STRING
51 |
52 |
53 | IV_ACCEPT_UNIX_STYLE_EOL
54 | '-'
55 | X
56 | BOOLEAN
57 |
58 |
59 | IV_DELTA_MODE
60 | '-'
61 | X
62 | BOOLEAN
63 |
64 |
65 | IV_TEST_MODE
66 | ''
67 | X
68 | BOOLEAN
69 |
70 |
71 | IV_ZIP_FILE
72 | X
73 | XSTRING
74 |
75 |
76 |
77 |
78 | EV_SUCCESS
79 | CHAR1
80 |
81 |
82 | EV_LOG_MESSAGES
83 | STRING_TABLE
84 |
85 |
86 | EV_MSG_ID
87 | SY-MSGID
88 |
89 |
90 | EV_MSG_NO
91 | SY-MSGNO
92 |
93 |
94 |
95 |
96 | IV_URL
97 | P
98 | Url to load SAPUI5 application from
99 |
100 |
101 | IV_SAPUI5_APPLICATION_NAME
102 | P
103 | Name of SAPUI5 application to be loaded
104 |
105 |
106 | IV_SAPUI5_APPLICATION_DESC
107 | P
108 | Description of SAPUI5 application
109 |
110 |
111 | IV_PACKAGE
112 | P
113 | Package of SAPUI5 application
114 |
115 |
116 | IV_WORKBENCH_REQUEST
117 | P
118 | ABAP workbench request
119 |
120 |
121 | IV_EXTERNAL_CODE_PAGE
122 | P
123 | External code page name for text files
124 |
125 |
126 | IV_ACCEPT_UNIX_STYLE_EOL
127 | P
128 | Accept unix style line endings in text files
129 |
130 |
131 | IV_DELTA_MODE
132 | P
133 | Upload different files and folders, delete obsolete resources
134 |
135 |
136 | IV_TEST_MODE
137 | P
138 | Activate test mode with detailed messages
139 |
140 |
141 | IV_ZIP_FILE
142 | P
143 | ZIP file
144 |
145 |
146 | EV_SUCCESS
147 | P
148 | Outcome of function call: S=Success, W=Warning, E=error
149 |
150 |
151 | EV_LOG_MESSAGES
152 | P
153 | Outcome of function call: Log Messages
154 |
155 |
156 | EV_MSG_ID
157 | P
158 | Outcome of function call: Message Class
159 |
160 |
161 | EV_MSG_NO
162 | P
163 | Outcome of function call: Message Number
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.saplyui5_repository_load.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | SAPLYUI5_REPOSITORY_LOAD
7 | S
8 | D$
9 | F
10 | S
11 | E
12 | X
13 | D$S
14 | X
15 |
16 |
17 | -
18 | I
19 | 001
20 | ***** Upload of SAPUI5 Application from ZIP-Archive into SAPUI5 ABAP Repository *****
21 | 132
22 |
23 | -
24 | I
25 | 002
26 | * Running in test mode: Upload operations are skipped, Detailed Log *
27 | 132
28 |
29 | -
30 | I
31 | 003
32 | * Running in regular mode: Brief Log *
33 | 132
34 |
35 | -
36 | I
37 | 010
38 | * Upload canceled: Url to Zip File containing SAPUI5 App is missing. *
39 | 132
40 |
41 | -
42 | I
43 | 011
44 | * Upload canceled: Unable to access Url "%" to Zip File containing SAPUI5 App. *
45 | 132
46 |
47 | -
48 | I
49 | 012
50 | * Connecting to Zip File containing SAPUI5 Application *
51 | 132
52 |
53 | -
54 | I
55 | 013
56 | * Upload canceled: Archive could not be read or appears to be empty. *
57 | 132
58 |
59 | -
60 | I
61 | 014
62 | . % Files found in Archive.
63 | 132
64 |
65 | -
66 | I
67 | 015
68 | * Upload canceled: SAPUI5 Application Name not specified. *
69 | 79
70 |
71 | -
72 | I
73 | 016
74 | * Upload canceled: ABAP workbench request for SAPUI5 ABAP Repository not specified. *
75 | 132
76 |
77 | -
78 | I
79 | 017
80 | * Upload canceled: Repository Package is not defined. *
81 | 132
82 |
83 | -
84 | I
85 | 018
86 | . The external code page name has been set to "%".
87 | 132
88 |
89 | -
90 | I
91 | 019
92 | * Parameters *
93 | 132
94 |
95 | -
96 | I
97 | 020
98 | . The text files are identified using the standard settings.
99 | 132
100 |
101 | -
102 | I
103 | 021
104 | . The file '.Ui5RepositoryTextFiles' is considered to identify text files.
105 | 132
106 |
107 | -
108 | I
109 | 022
110 | . The binary files are identified using the standard settings.
111 | 132
112 |
113 | -
114 | I
115 | 023
116 | . The file '.Ui5RepositoryBinaryFiles' is considered to identify binary files.
117 | 132
118 |
119 | -
120 | I
121 | 024
122 | . The files and folders to be ignored are determined from the built-in standard settings.
123 | 132
124 |
125 | -
126 | I
127 | 025
128 | . The files and folders to be ignored are determined from the '.Ui5RepositoryIgnore' file.
129 | 132
130 |
131 | -
132 | I
133 | 026
134 | . %1 "%2" has been determined from the '.Ui5RepositoryUploadParameters' file.
135 | 132
136 |
137 | -
138 | I
139 | 027
140 | . %1 "%2" has been determined from the corresponding import parameter.
141 | 132
142 |
143 | -
144 | I
145 | 028
146 | * Creating new SAPUI5 application % *
147 | 132
148 |
149 | -
150 | I
151 | 029
152 | * Updating existing SAPUI5 application % *
153 | 132
154 |
155 | -
156 | I
157 | 030
158 | * Upload canceled: SAPUI5 application has not been created (successfully). *
159 | 132
160 |
161 | -
162 | I
163 | 032
164 | * Upload canceled: External Code Page is invalid. You may use e.g. 'UTF-8' or 'Cp1252' *
165 | 132
166 |
167 | -
168 | I
169 | 033
170 | * Upload canceled: Code Page is invalid. *
171 | 132
172 |
173 | -
174 | I
175 | 034
176 | . The delta mode has been turned on.
177 | 132
178 |
179 | -
180 | I
181 | 035
182 | . The delta mode has been turned off.
183 | 132
184 |
185 | -
186 | I
187 | 036
188 | . The package has been defaulted to "$TMP".
189 | 132
190 |
191 | -
192 | I
193 | 037
194 | . Unix style end of line markers in text files get accepted.
195 | 132
196 |
197 | -
198 | I
199 | 038
200 | . Unix style end of line markers in text files get rejected.
201 | 132
202 |
203 | -
204 | I
205 | 039
206 | . A BAdI implementation for /UI5/BADI_PREVENT_DELETION is active: Repository and app may become out of sync.
207 | 132
208 |
209 | -
210 | I
211 | 040
212 | * Operations *
213 | 132
214 |
215 | -
216 | I
217 | 041
218 | * Analyzing Archive *
219 | 132
220 |
221 | -
222 | I
223 | 043
224 | * Done *
225 | 40
226 |
227 | -
228 | I
229 | 050
230 | * Warning: Content of file % could not be read *
231 | 132
232 |
233 | -
234 | I
235 | 051
236 | * Warning: Unable to determine MD5 hash for file % *
237 | 120
238 |
239 | -
240 | I
241 | 054
242 | * Warning: Folder % has not been created *
243 | 90
244 |
245 | -
246 | I
247 | 055
248 | * Warning: Text file % has not been uploaded *
249 | 100
250 |
251 | -
252 | I
253 | 056
254 | * Warning: Text file % has unix style line delimeter. It is not uploaded *
255 | 132
256 |
257 | -
258 | I
259 | 057
260 | * Error: Unable to convert Unix style text file % *
261 | 132
262 |
263 | -
264 | I
265 | 064
266 | * Warning: Binary file % has not been uploaded *
267 | 100
268 |
269 | -
270 | I
271 | 065
272 | * Binary file has NOT been deleted in ABAP repository on BAdI request *
273 | 132
274 |
275 | -
276 | I
277 | 070
278 | Text
279 | 10
280 |
281 | -
282 | I
283 | 071
284 | Binary
285 | 20
286 |
287 | -
288 | I
289 | 072
290 | Warning: File type unknown
291 | 132
292 |
293 | -
294 | I
295 | 073
296 | Unix style text file
297 | 132
298 |
299 | -
300 | I
301 | 074
302 | Already up-to-date
303 | 132
304 |
305 | -
306 | I
307 | 075
308 | Folder already exists
309 | 132
310 |
311 | -
312 | I
313 | 076
314 | Warning: Unix style text file
315 | 132
316 |
317 | -
318 | I
319 | 090
320 | * Upload canceled: Name of SAPUI5 Application appears to be invalid. Same rules as for BSP applications apply.
321 | 132
322 |
323 | -
324 | I
325 | 091
326 | * Upload canceled: External code page has not been specified. *
327 | 132
328 |
329 | -
330 | I
331 | 092
332 | * Upload canceled: Unable to lock SAPUI5 repository *
333 | 132
334 |
335 | -
336 | I
337 | 093
338 | * Upload canceled: A BAdI error has occurred. *
339 | 132
340 |
341 | -
342 | I
343 | 100
344 | The name of the SAPUI5 Application
345 | 132
346 |
347 | -
348 | I
349 | 101
350 | The description of the SAPUI5 Application
351 | 132
352 |
353 | -
354 | I
355 | 102
356 | Warning : Authorization may be missing for
357 | 132
358 |
359 | -
360 | I
361 | 103
362 | The package of the SAPUI5 Application
363 | 132
364 |
365 | -
366 | I
367 | 104
368 | Workbench Request
369 | 132
370 |
371 | -
372 | I
373 | 105
374 | The external Code Page Name
375 | 132
376 |
377 | -
378 | I
379 | 106
380 | The acceptance of Unix style end of line markers in text files
381 | 132
382 |
383 | -
384 | I
385 | 107
386 | Warning : Authorizations may be missing.
387 | 132
388 |
389 | -
390 | I
391 | 108
392 | and
393 | 132
394 |
395 | -
396 | I
397 | 109
398 | . HTTP status was %1 / %2
399 | 132
400 |
401 | -
402 | I
403 | 110
404 | Application log message :
405 | 132
406 |
407 | -
408 | I
409 | 111
410 | * Updating the Application Index *
411 | 132
412 |
413 | -
414 | I
415 | 112
416 | . For details see the application log (SLG1) in client 000 for object /UI5/APPIDX .
417 | 132
418 |
419 |
420 |
421 |
422 |
423 |
--------------------------------------------------------------------------------
/src/ycl_github_webhook_handler.clas.abap:
--------------------------------------------------------------------------------
1 | class YCL_GITHUB_WEBHOOK_HANDLER definition
2 | public
3 | create public .
4 |
5 | public section.
6 |
7 | interfaces IF_HTTP_EXTENSION .
8 | protected section.
9 |
10 | types:
11 | BEGIN OF user_profile_plan_type,
12 | name TYPE string,
13 | space TYPE string,
14 | collaborators TYPE string,
15 | private_repos TYPE string,
16 | END OF user_profile_plan_type .
17 | types:
18 | BEGIN OF user_profile_type,
19 | login TYPE string,
20 | id TYPE string,
21 | avatar_url TYPE string,
22 | gravatar_id TYPE string,
23 | url TYPE string,
24 | html_url TYPE string,
25 | followers_url TYPE string,
26 | following_url TYPE string,
27 | gists_url TYPE string,
28 | starred_url TYPE string,
29 | subscriptions_url TYPE string,
30 | organizations_url TYPE string,
31 | repos_url TYPE string,
32 | events_url TYPE string,
33 | received_events_url TYPE string,
34 | type TYPE string,
35 | site_admin TYPE string,
36 | name TYPE string,
37 | company TYPE string,
38 | blog TYPE string,
39 | location TYPE string,
40 | email TYPE string,
41 | hireable TYPE string,
42 | bio TYPE string,
43 | public_repos TYPE string,
44 | public_gists TYPE string,
45 | followers TYPE string,
46 | following TYPE string,
47 | created_at TYPE string,
48 | updated_at TYPE string,
49 | private_gists TYPE string,
50 | total_private_repos TYPE string,
51 | owned_private_repos TYPE string,
52 | disk_usage TYPE string,
53 | collaborators TYPE string,
54 | plan TYPE user_profile_plan_type,
55 | END OF user_profile_type .
56 | types:
57 | BEGIN OF github_permissions_type,
58 | admin TYPE boolean,
59 | push TYPE boolean,
60 | pull TYPE boolean,
61 | END OF github_permissions_type .
62 | types:
63 | BEGIN OF github_owner_type,
64 | login TYPE string,
65 | id TYPE i,
66 | avatar_url TYPE string,
67 | gravatar_id TYPE string,
68 | url TYPE string,
69 | html_url TYPE string,
70 | followers_url TYPE string,
71 | following_url TYPE string,
72 | gists_url TYPE string,
73 | starred_url TYPE string,
74 | subscriptions_url TYPE string,
75 | organizations_url TYPE string,
76 | repos_url TYPE string,
77 | events_url TYPE string,
78 | received_events_url TYPE string,
79 | type TYPE string,
80 | site_admin TYPE boolean,
81 | name type string,
82 | email type string,
83 | username type string,
84 | END OF github_owner_type .
85 | types:
86 | BEGIN OF github_organization_type,
87 | login TYPE string,
88 | id TYPE i,
89 | description type string,
90 | avatar_url TYPE string,
91 | url TYPE string,
92 | html_url TYPE string,
93 | members_url type string,
94 | followers_url TYPE string,
95 | following_url TYPE string,
96 | public_members_url type string,
97 | gists_url TYPE string,
98 | starred_url TYPE string,
99 | subscriptions_url TYPE string,
100 | organizations_url TYPE string,
101 | repos_url TYPE string,
102 | events_url TYPE string,
103 | received_events_url TYPE string,
104 | type TYPE string,
105 | site_admin TYPE boolean,
106 | END OF github_organization_type .
107 | types:
108 | BEGIN OF github_repository_type,
109 | id TYPE i,
110 | name TYPE string,
111 | full_name TYPE string,
112 | owner TYPE github_owner_type,
113 | private TYPE boolean,
114 | html_url TYPE string,
115 | description TYPE string,
116 | fork TYPE boolean,
117 | url TYPE string,
118 | forks_url TYPE string,
119 | keys_url TYPE string,
120 | collaborators_url TYPE string,
121 | teams_url TYPE string,
122 | hooks_url TYPE string,
123 | issue_events_url TYPE string,
124 | events_url TYPE string,
125 | assignees_url TYPE string,
126 | branches_url TYPE string,
127 | tags_url TYPE string,
128 | blobs_url TYPE string,
129 | git_tags_url TYPE string,
130 | git_refs_url TYPE string,
131 | trees_url TYPE string,
132 | statuses_url TYPE string,
133 | languages_url TYPE string,
134 | stargazers_url TYPE string,
135 | contributors_url TYPE string,
136 | subscribers_url TYPE string,
137 | subscription_url TYPE string,
138 | commits_url TYPE string,
139 | git_commits_url TYPE string,
140 | comments_url TYPE string,
141 | issue_comment_url TYPE string,
142 | contents_url TYPE string,
143 | compare_url TYPE string,
144 | merges_url TYPE string,
145 | archive_url TYPE string,
146 | downloads_url TYPE string,
147 | issues_url TYPE string,
148 | pulls_url TYPE string,
149 | milestones_url TYPE string,
150 | notifications_url TYPE string,
151 | labels_url TYPE string,
152 | releases_url TYPE string,
153 | created_at TYPE string,
154 | updated_at TYPE string,
155 | pushed_at TYPE string,
156 | git_url TYPE string,
157 | ssh_url TYPE string,
158 | clone_url TYPE string,
159 | svn_url TYPE string,
160 | homepage TYPE string,
161 | size TYPE i,
162 | stargazers_count TYPE i,
163 | watchers_count TYPE i,
164 | language TYPE string,
165 | has_issues TYPE boolean,
166 | has_downloads TYPE boolean,
167 | has_wiki TYPE boolean,
168 | has_pages TYPE boolean,
169 | forks_count TYPE i,
170 | mirror_url TYPE string,
171 | open_issues_count TYPE i,
172 | forks TYPE i,
173 | open_issues TYPE i,
174 | watchers TYPE i,
175 | startgazers type i,
176 | default_branch TYPE string,
177 | master_branch type string,
178 | permissions TYPE github_permissions_type,
179 | organization TYPE github_organization_type,
180 | network_count TYPE i,
181 | subscribers_count TYPE i,
182 | END OF github_repository_type .
183 | types:
184 | github_repository_ttype TYPE TABLE OF github_repository_type .
185 | types:
186 | begin of github_commit_type,
187 | id type string,
188 | distinct type boolean,
189 | message type string,
190 | timestamp type string,
191 | url type string,
192 | author type github_owner_type,
193 | committer type github_owner_type,
194 | added type stringtab,
195 | removed type stringtab,
196 | modified type stringtab,
197 | end of github_commit_type .
198 | types:
199 | github_commit_ttype type table of github_commit_type .
200 | types:
201 | begin of github_push_type,
202 | ref type string,
203 | before type string,
204 | after type string,
205 | created type boolean,
206 | deleted type boolean,
207 | forced type boolean,
208 | base_ref type string,
209 | compare type string,
210 | "commits type table of github_commit_type,
211 | head_commit type github_commit_type,
212 | repository type github_repository_type,
213 | pusher type github_owner_type,
214 | organization type github_organization_type,
215 | sender type github_owner_type,
216 | end of github_push_type .
217 |
218 | data MT_GITHUB_FIELDS type TIHTTPNVP .
219 |
220 | methods READ_GITHUB_FIELDS
221 | importing
222 | !SERVER type ref to IF_HTTP_SERVER .
223 | methods GET_COMMIT_DETAILS
224 | importing
225 | !SERVER type ref to IF_HTTP_SERVER
226 | returning
227 | value(PUSH) type GITHUB_PUSH_TYPE .
228 | private section.
229 | ENDCLASS.
230 |
231 |
232 |
233 | CLASS YCL_GITHUB_WEBHOOK_HANDLER IMPLEMENTATION.
234 |
235 |
236 | METHOD get_commit_details.
237 | DATA(payload) = server->request->get_cdata( ).
238 | "SPLIT payload AT 'payload=' INTO DATA(junk) payload.
239 |
240 | /ui2/cl_json=>deserialize(
241 | EXPORTING json = cl_http_utility=>unescape_url( payload )
242 | pretty_name = /ui2/cl_json=>pretty_mode-camel_case
243 | CHANGING
244 | data = push ).
245 |
246 | ENDMETHOD.
247 |
248 |
249 | METHOD if_http_extension~handle_request.
250 |
251 | DATA: ls_push TYPE github_push_type,
252 | lt_stringtab TYPE stringtab,
253 | lv_jobnumber TYPE tbtcjob-jobcount,
254 | lv_jobname TYPE tbtcjob-jobname,
255 | lt_params TYPE TABLE OF rsparams,
256 | lr_param TYPE REF TO rsparams.
257 |
258 | ls_push = get_commit_details( server ).
259 |
260 | CHECK ls_push IS NOT INITIAL.
261 |
262 | * We are only interested in deploying the master branch
263 | SPLIT ls_push-ref AT '/' INTO TABLE lt_stringtab.
264 | CHECK lt_stringtab[ lines( lt_stringtab ) ] EQ ls_push-repository-master_branch.
265 |
266 | * Check this is a repo we want to deploy here
267 | CASE ls_push-repository-full_name.
268 | WHEN 'grahamrobbo/demojam'. "Most repos take a while to deploy - so submit a batch job to do the work
269 |
270 | APPEND INITIAL LINE TO lt_params REFERENCE INTO lr_param.
271 | lr_param->selname = 'GIT_REPO'.
272 | lr_param->kind = 'S'.
273 | lr_param->sign = 'I'.
274 | lr_param->option = 'EQ'.
275 | lr_param->low = ls_push-repository-full_name.
276 |
277 | IF ls_push-repository-master_branch IS NOT INITIAL.
278 | APPEND INITIAL LINE TO lt_params REFERENCE INTO lr_param.
279 | lr_param->selname = 'BRANCH'.
280 | lr_param->kind = 'S'.
281 | lr_param->sign = 'I'.
282 | lr_param->option = 'EQ'.
283 | lr_param->low = ls_push-repository-master_branch.
284 | ENDIF.
285 |
286 | * " Note GitHub credentials only required for private repos
287 | * IF github_user IS NOT INITIAL.
288 | * APPEND INITIAL LINE TO lt_params REFERENCE INTO lr_param.
289 | * lr_param->selname = 'USERNAME'.
290 | * lr_param->kind = 'S'.
291 | * lr_param->sign = 'I'.
292 | * lr_param->option = 'EQ'.
293 | * lr_param->low = github_user.
294 | *
295 | * IF password IS NOT INITIAL.
296 | * APPEND INITIAL LINE TO lt_params REFERENCE INTO lr_param.
297 | * lr_param->selname = 'PASSWORD'.
298 | * lr_param->kind = 'S'.
299 | * lr_param->sign = 'I'.
300 | * lr_param->option = 'EQ'.
301 | * lr_param->low = github_password.
302 | * ENDIF.
303 | * ENDIF.
304 | *
305 | * " Note workbench request can be specified in the .Ui5RepositoryUploadParameters file
306 | * IF transport IS NOT INITIAL.
307 | * APPEND INITIAL LINE TO lt_params REFERENCE INTO lr_param.
308 | * lr_param->selname = 'TRANSPORT'.
309 | * lr_param->kind = 'S'.
310 | * lr_param->sign = 'I'.
311 | * lr_param->option = 'EQ'.
312 | * lr_param->low = transport.
313 | * ENDIF.
314 |
315 | APPEND INITIAL LINE TO lt_params REFERENCE INTO lr_param.
316 | lr_param->selname = 'TEST'.
317 | lr_param->kind = 'S'.
318 | lr_param->sign = 'I'.
319 | lr_param->option = 'EQ'.
320 | lr_param->low = abap_false.
321 |
322 | lv_jobname = |Deploy { ls_push-repository-full_name }|.
323 | CALL FUNCTION 'JOB_OPEN'
324 | EXPORTING
325 | jobname = lv_jobname
326 | IMPORTING
327 | jobcount = lv_jobnumber
328 | EXCEPTIONS
329 | cant_create_job = 1
330 | invalid_job_data = 2
331 | jobname_missing = 3
332 | OTHERS = 4.
333 | CHECK sy-subrc = 0.
334 |
335 | SUBMIT ygithub_deploy_ui5_repository
336 | WITH SELECTION-TABLE lt_params
337 | VIA JOB lv_jobname NUMBER lv_jobnumber AND RETURN.
338 | CHECK sy-subrc = 0.
339 |
340 | CALL FUNCTION 'JOB_CLOSE'
341 | EXPORTING
342 | jobcount = lv_jobnumber
343 | jobname = lv_jobname
344 | strtimmed = 'X'
345 | EXCEPTIONS
346 | cant_start_immediate = 1
347 | invalid_startdate = 2
348 | jobname_missing = 3
349 | job_close_failed = 4
350 | job_nosteps = 5
351 | job_notex = 6
352 | lock_failed = 7
353 | OTHERS = 8.
354 |
355 | WHEN OTHERS.
356 | server->response->set_status( code = 404 reason = |Not found| ).
357 | ENDCASE.
358 |
359 | ENDMETHOD.
360 |
361 |
362 | METHOD read_github_fields.
363 |
364 | DATA: lt_fields TYPE tihttpnvp,
365 | ls_fields LIKE LINE OF lt_fields,
366 | lv_json TYPE xstring,
367 | lr_conv TYPE REF TO cl_abap_conv_out_ce.
368 |
369 | * Json Processing variables.
370 | DATA: lr_reader TYPE REF TO if_sxml_reader,
371 | lr_node TYPE REF TO if_sxml_node,
372 | lr_value_node TYPE REF TO if_sxml_value_node,
373 | lr_open_elem TYPE REF TO if_sxml_open_element,
374 | lt_attribs TYPE if_sxml_attribute=>attributes,
375 | ls_attrib LIKE LINE OF lt_attribs.
376 |
377 | DATA: parse_error TYPE REF TO cx_sxml_parse_error.
378 |
379 | server->request->get_form_fields_cs(
380 | * EXPORTING
381 | * formfield_encoding = 0 " CO_FORMFIELD_ENCODING_RAW / _ENCODED
382 | * search_option = 3 " CO_BODY_BEFORE_QUERY_STRING or others
383 | CHANGING
384 | fields = lt_fields ). " Form fields
385 |
386 | READ TABLE lt_fields INTO ls_fields INDEX 1.
387 | * convert to xstring
388 | lr_conv = cl_abap_conv_out_ce=>create( ).
389 | lr_conv->convert(
390 | EXPORTING
391 | data = ls_fields-value " Field to Be Converted
392 | * n = - 1 " Number of Units to Be Converted
393 | IMPORTING
394 | buffer = lv_json " Converted Data
395 | * len = " Number of Converted Units
396 | ).
397 | * CATCH cx_sy_codepage_converter_init. "
398 | * CATCH cx_sy_conversion_codepage. "
399 | * CATCH cx_parameter_invalid_type. "
400 | CLEAR me->mt_github_fields.
401 |
402 | IF lv_json IS INITIAL.
403 | lv_json = server->request->get_data( ).
404 | ENDIF.
405 | * get the reader
406 | lr_reader = cl_sxml_string_reader=>create( lv_json ).
407 | * Parse in a do loop.
408 | TRY.
409 | DO.
410 | CLEAR lr_node.
411 | lr_node = lr_reader->read_next_node( ).
412 | IF lr_node IS INITIAL.
413 | EXIT.
414 | ENDIF.
415 | CASE lr_node->type.
416 | WHEN if_sxml_node=>co_nt_element_open.
417 | CLEAR ls_fields.
418 | lr_open_elem ?= lr_node.
419 | ls_fields-name = lr_open_elem->qname-name.
420 | IF ls_fields-name EQ 'str'.
421 | " read the name attribute for getting the name of the json value
422 | lt_attribs = lr_open_elem->get_attributes( ).
423 | LOOP AT lt_attribs INTO ls_attrib.
424 | IF ls_attrib->qname-name = 'name'.
425 | ls_fields-name = ls_attrib->get_value( ).
426 | ENDIF.
427 | ENDLOOP.
428 | ELSE.
429 | CLEAR ls_fields.
430 | ENDIF.
431 | WHEN if_sxml_node=>co_nt_value.
432 | * node value.
433 | IF ls_fields IS INITIAL.
434 | CONTINUE.
435 | ENDIF.
436 | lr_value_node ?= lr_node.
437 | ls_fields-value = lr_value_node->get_value( ).
438 | APPEND ls_fields TO me->mt_github_fields.
439 | WHEN OTHERS.
440 | ENDCASE.
441 | ENDDO.
442 | CATCH cx_sxml_parse_error INTO parse_error.
443 | ENDTRY.
444 | ENDMETHOD.
445 | ENDCLASS.
446 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.lyui5_repository_loadd01.abap:
--------------------------------------------------------------------------------
1 | *&---------------------------------------------------------------------*
2 | *& Include /UI5/LUI5_REPOSITORY_LOADD01
3 | *&---------------------------------------------------------------------*
4 | ************************************************************************
5 | ************************************************************************
6 | * *
7 | * Local Classes Definition *
8 | * *
9 | ************************************************************************
10 | ************************************************************************
11 |
12 |
13 | ************************************************************************
14 | * Class LCL_FUNCTION
15 | *
16 | * provides some helper functions.
17 | ************************************************************************
18 | CLASS lcl_function DEFINITION.
19 | PUBLIC SECTION.
20 |
21 | TYPES: x255_table TYPE STANDARD TABLE OF raw255.
22 | CLASS-METHODS: conv_unix_style_line_endings IMPORTING iv_string TYPE string
23 | RETURNING VALUE(rv_string) TYPE string,
24 | get_md5_hash_for_string IMPORTING iv_string TYPE string
25 | RETURNING VALUE(rv_md5_hash) TYPE md5_fields-hash,
26 | get_hash_for_xstring IMPORTING iv_xstring TYPE xstring
27 | RETURNING VALUE(rv_hash) TYPE string,
28 | max IMPORTING a TYPE i DEFAULT -999999
29 | b TYPE i DEFAULT -999999
30 | c TYPE i DEFAULT -999999
31 | d TYPE i DEFAULT -999999
32 | e TYPE i DEFAULT -999999
33 | f TYPE i DEFAULT -999999
34 | RETURNING VALUE(rv_max) TYPE i,
35 | set_return_msg IMPORTING iv_success TYPE char1
36 | iv_test_mode TYPE abap_bool
37 | CHANGING cv_msg_id LIKE sy-msgid
38 | cv_msg_no LIKE sy-msgno,
39 | string_to_file IMPORTING iv_file_content TYPE string
40 | iv_code_page TYPE string
41 | iv_file_path TYPE string
42 | RETURNING VALUE(rv_success) TYPE abap_bool,
43 | text_matches_pattern IMPORTING iv_text TYPE string
44 | iv_pattern_list TYPE string_table
45 | RETURNING VALUE(rv_text_matches_pattern) TYPE abap_bool,
46 | text_to_abap_bool IMPORTING iv_text TYPE string
47 | RETURNING VALUE(rv_abap_bool) TYPE abap_bool,
48 | xstring_to_file IMPORTING iv_file_content TYPE xstring
49 | iv_file_path TYPE string
50 | RETURNING VALUE(rv_success) TYPE abap_bool,
51 | xstring2xtable IMPORTING iv_xstring TYPE xstring
52 | EXPORTING ev_xtable TYPE x255_table
53 | ev_size TYPE int4.
54 |
55 | ENDCLASS. "lcl_function DEFINITION
56 |
57 |
58 | ************************************************************************
59 | * Class LCL_OPERATION
60 | *
61 | * represents an upload operation to be performed.
62 | ************************************************************************
63 | CLASS lcl_operation DEFINITION.
64 |
65 | PUBLIC SECTION.
66 |
67 | DATA: full_path TYPE string,
68 | message TYPE string,
69 | object_type TYPE string,
70 | object_name TYPE string,
71 | operation TYPE string,
72 | relative_path TYPE string,
73 | hash_value TYPE md5_fields-hash,
74 | code_page TYPE string,
75 | eol_conversion TYPE abap_bool,
76 | to_update TYPE abap_bool.
77 | METHODS: create_log_message RETURNING VALUE(rv_message) TYPE string,
78 | get_file_extension RETURNING VALUE(rv_file_extension) TYPE string,
79 | is_binary RETURNING VALUE(rv_is_binary) TYPE abap_bool.
80 | CLASS-DATA: create_folder TYPE string VALUE 'CREATE FOLDER',
81 | delete_folder TYPE string VALUE 'DELETE FOLDER',
82 | delete_file TYPE string VALUE 'DELETE FILE',
83 | ignore_file TYPE string VALUE 'IGNORE_FILE',
84 | ignore_folder TYPE string VALUE 'IGNORE_FOLDER',
85 | upload_file TYPE string VALUE 'UPLOAD FILE',
86 | object_type_none TYPE string VALUE '',
87 | object_type_binary_file TYPE string VALUE 'BINARY_FILE',
88 | object_type_file TYPE string VALUE 'FILE',
89 | object_type_text_file TYPE string VALUE 'TEXT_FILE',
90 | object_type_folder TYPE string VALUE 'FOLDER'.
91 |
92 | ENDCLASS. "LCL_OPERATION
93 |
94 | ************************************************************************
95 | * Class LCL_BADI
96 | *
97 | ************************************************************************
98 | CLASS lcl_badi DEFINITION.
99 |
100 | PUBLIC SECTION.
101 | DATA:
102 | implementation TYPE REF TO /ui5/badi_prevent_deletion,
103 | never_delete_mime_resources TYPE abap_bool,
104 | application_name TYPE string,
105 | workbench_request TYPE trkorr,
106 | test_mode TYPE abap_bool,
107 | error_occurred TYPE abap_bool,
108 | error_text TYPE string.
109 |
110 | METHODS: constructor IMPORTING iv_test_mode TYPE abap_bool
111 | iv_sapui5_application_name TYPE string
112 | iv_workbench_request TYPE trkorr,
113 | disable_deletion_for IMPORTING iv_operation TYPE REF TO lcl_operation
114 | RETURNING VALUE(rv_result) TYPE abap_bool.
115 |
116 | ENDCLASS.
117 |
118 | ************************************************************************
119 | * Class LCL_SAPUI5_ZIP_ARCHIVE
120 | *
121 | * represents a zip file containing a SAPUI5 application
122 | *
123 | * Remarks:
124 | * - Access to log messages is passed as reference to constructor:
125 | * 1) Changing and table parameters are not allowed here;
126 | * 2) Using a field symbol as an input parameter does not work either:
127 | * Write operation is not supported then.
128 | *
129 | ************************************************************************
130 | CLASS lcl_sapui5_zip_archive DEFINITION FINAL.
131 |
132 | PUBLIC SECTION.
133 |
134 | TYPES: operations TYPE TABLE OF REF TO lcl_operation.
135 | METHODS: constructor IMPORTING iv_url TYPE string
136 | iv_zip_file TYPE xstring OPTIONAL
137 | ir_log_messages TYPE REF TO string_table,
138 | determine_upload_operations IMPORTING iv_delta_mode TYPE abap_bool
139 | iv_accept_unix_style_eol TYPE abap_bool
140 | iv_code_page TYPE string
141 | CHANGING cv_load_operations TYPE operations
142 | cv_success TYPE char1,
143 | is_ok RETURNING VALUE(rv_is_ok) TYPE boolean,
144 | is_binary_file IMPORTING iv_file_path TYPE string
145 | RETURNING VALUE(rv_is_binary_file) TYPE abap_bool,
146 | is_file_to_be_ignored IMPORTING iv_file_path TYPE string
147 | RETURNING VALUE(rv_ignore) TYPE abap_bool,
148 | is_text_file IMPORTING iv_file_path TYPE string
149 | RETURNING VALUE(rv_is_text_file) TYPE abap_bool,
150 | read_file_to_table IMPORTING iv_path TYPE string
151 | iv_code_page TYPE string
152 | RETURNING VALUE(rt_lines) TYPE string_table,
153 | read_file IMPORTING iv_path TYPE string
154 | RETURNING VALUE(rv_content) TYPE xstring,
155 | get_upload_parameter IMPORTING iv_key TYPE string
156 | iv_return_if_not_specified TYPE string DEFAULT ''
157 | RETURNING VALUE(rv_value) TYPE string.
158 | DATA: binary_file_patterns TYPE string_table,
159 | text_file_patterns TYPE string_table,
160 | upload_ignores TYPE string_table,
161 | upload_parameters TYPE slin_key_value_hash.
162 |
163 | PRIVATE SECTION.
164 |
165 | METHODS: add_default_bin_file_patterns CHANGING cv_file_patterns TYPE string_table,
166 | add_default_ignore_patterns CHANGING cv_file_patterns TYPE string_table,
167 | add_default_text_file_patterns CHANGING cv_file_patterns TYPE string_table,
168 | add_import_upload_parameters CHANGING cv_file_patterns TYPE slin_key_value_hash,
169 | create_folders_for_path IMPORTING iv_path TYPE string
170 | CHANGING cv_folders_created TYPE string
171 | cv_load_operations TYPE operations,
172 | determine_binary_file_patterns IMPORTING iv_code_page TYPE string,
173 | determine_text_file_patterns IMPORTING iv_code_page TYPE string,
174 | determine_upload_ignores IMPORTING iv_code_page TYPE string,
175 | determine_upload_parameters IMPORTING iv_code_page TYPE string.
176 | DATA: error_message TYPE string,
177 | http_client TYPE REF TO if_http_client,
178 | log_messages_ref TYPE REF TO string_table,
179 | ok TYPE boolean,
180 | upload_operations TYPE TABLE OF REF TO lcl_operation,
181 | url TYPE string,
182 | zip_archive TYPE REF TO cl_abap_zip.
183 |
184 | ENDCLASS. "lcl_sapui5_zip_archive
185 |
186 |
187 | ************************************************************************
188 | * Class LCL_EXCEPTION
189 | *
190 | * is the exception to handle errors in this report.
191 | ************************************************************************
192 | CLASS lcx_exception DEFINITION INHERITING FROM cx_static_check.
193 | ENDCLASS. "lcx_exception DEFINITION
194 |
195 |
196 | ************************************************************************
197 | * Class LCL_CANCELED
198 | *
199 | * indicates processing has been canceled by the user.
200 | ************************************************************************
201 | CLASS lcx_canceled DEFINITION INHERITING FROM cx_dynamic_check.
202 | ENDCLASS. "lcx_canceled DEFINITION
203 |
204 |
205 |
206 | ************************************************************************
207 | * Class lcl_external_code_page
208 | *
209 | * supports conversion of external code page into abap code page.
210 | ************************************************************************
211 | CLASS lcl_external_code_page DEFINITION.
212 |
213 | PUBLIC SECTION.
214 |
215 | TYPE-POOLS abap.
216 | CLASS-DATA: no_code_page TYPE cpcodepage VALUE '0'.
217 | CLASS-METHODS: create IMPORTING iv_code_page_name TYPE string
218 | RETURNING VALUE(rv_external_code_page) TYPE REF TO lcl_external_code_page
219 | RAISING lcx_exception,
220 | for_sapgui_installation RETURNING VALUE(rv_external_code_page) TYPE REF TO lcl_external_code_page
221 | RAISING lcx_exception.
222 | METHODS: get_abap_encoding RETURNING VALUE(rv_abap_encoding) TYPE cpcodepage
223 | RAISING lcx_exception,
224 | get_java_encoding RETURNING VALUE(rv_java_encoding) TYPE string
225 | RAISING lcx_exception.
226 | DATA: name TYPE string READ-ONLY,
227 | kind TYPE cpattrkind READ-ONLY.
228 |
229 | ENDCLASS. "lcl_external_code_page DEFINITION
230 |
231 |
232 | ************************************************************************
233 | * Class LCL_UI5_REPOSITORY
234 | *
235 | * represents a UI5 Repository and the UI5 application it contains.
236 | ************************************************************************
237 | CLASS lcl_ui5_repository DEFINITION FINAL CREATE PRIVATE.
238 |
239 | PUBLIC SECTION.
240 | CLASS-DATA: message TYPE string,
241 | debug_conversions_for_file TYPE string VALUE ''.
242 | TYPES: BEGIN OF upload_parameters,
243 | description TYPE string,
244 | package TYPE devclass,
245 | transport_request TYPE trkorr,
246 | code_page_ui TYPE string,
247 | code_page_abap TYPE cpcodepage,
248 | code_page_java TYPE string,
249 | END OF upload_parameters,
250 | upload_operations TYPE TABLE OF REF TO lcl_operation.
251 | DATA: already_exists TYPE abap_bool,
252 | api TYPE REF TO /ui5/if_ui5_rep_dt,
253 | binary_file_identification_msg TYPE string,
254 | binary_file_patterns TYPE TABLE OF string,
255 | name TYPE string,
256 | text_file_identification_msg TYPE string,
257 | text_file_patterns TYPE TABLE OF string,
258 | ignores TYPE TABLE OF string,
259 | ignores_identification_msg TYPE string.
260 | CLASS-METHODS: class_constructor,
261 | get_instance IMPORTING ir_log_messages TYPE REF TO string_table
262 | RETURNING VALUE(rv_self) TYPE REF TO lcl_ui5_repository,
263 | evaluate_authorization RETURNING VALUE(rv_message) TYPE string.
264 | METHODS: conciliate_upload_operations IMPORTING iv_path TYPE string DEFAULT ''
265 | iv_delta_mode TYPE abap_bool
266 | iv_badi TYPE REF TO lcl_badi
267 | iv_archive TYPE REF TO lcl_sapui5_zip_archive
268 | CHANGING cv_upload_operations TYPE upload_operations,
269 | get_mime_type_for_upload IMPORTING iv_operation TYPE REF TO lcl_operation
270 | RETURNING VALUE(rv_mime_type) TYPE string,
271 | set_name IMPORTING iv_name TYPE string.
272 |
273 | PRIVATE SECTION.
274 | * METHODS:
275 | * is_binary_file IMPORTING iv_file_path TYPE string
276 | * RETURNING value(rv_is_binary_file) TYPE abap_bool,
277 | * is_file_to_be_ignored IMPORTING iv_file_path TYPE string
278 | * RETURNING value(rv_ignore) TYPE abap_bool,
279 | * is_text_file IMPORTING iv_file_path TYPE string
280 | * RETURNING value(rv_is_text_file) TYPE abap_bool.
281 | CLASS-DATA: self TYPE REF TO lcl_ui5_repository.
282 | DATA: log_messages_ref TYPE REF TO string_table.
283 |
284 | ENDCLASS. "lcl_ui5_repository DEFINITION
285 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.yui5_repository_load_http.abap:
--------------------------------------------------------------------------------
1 | FUNCTION yui5_repository_load_http.
2 | *"----------------------------------------------------------------------
3 | *"*"Local Interface:
4 | *" IMPORTING
5 | *" VALUE(IV_URL) TYPE STRING
6 | *" VALUE(IV_SAPUI5_APPLICATION_NAME) TYPE STRING DEFAULT ''
7 | *" VALUE(IV_SAPUI5_APPLICATION_DESC) TYPE STRING DEFAULT ''
8 | *" VALUE(IV_PACKAGE) TYPE DEVCLASS DEFAULT ''
9 | *" VALUE(IV_WORKBENCH_REQUEST) TYPE TRKORR DEFAULT ''
10 | *" VALUE(IV_EXTERNAL_CODE_PAGE) TYPE STRING DEFAULT ''
11 | *" VALUE(IV_ACCEPT_UNIX_STYLE_EOL) TYPE BOOLEAN DEFAULT '-'
12 | *" VALUE(IV_DELTA_MODE) TYPE BOOLEAN DEFAULT '-'
13 | *" VALUE(IV_TEST_MODE) TYPE BOOLEAN DEFAULT ''
14 | *" VALUE(IV_ZIP_FILE) TYPE XSTRING OPTIONAL
15 | *" EXPORTING
16 | *" VALUE(EV_SUCCESS) TYPE CHAR1
17 | *" VALUE(EV_LOG_MESSAGES) TYPE STRING_TABLE
18 | *" VALUE(EV_MSG_ID) TYPE SY-MSGID
19 | *" VALUE(EV_MSG_NO) TYPE SY-MSGNO
20 | *"----------------------------------------------------------------------
21 | ************************************************************************
22 | *--------------------------------------------------------------------*
23 | * This function module is pretty much a copy of SAP provided function
24 | * module /UI5/UI5_REPOSITORY_LOAD_HTTP with minor changes to support
25 | * input of a .zip file as an alternative to a URL.
26 | *
27 | * The doco for /UI5/UI5_REPOSITORY_LOAD_HTTP follows which describes
28 | * the standard input parameters and how this function module works
29 | * and how to use the .Ui5 parameter files to influence the behaviour.
30 | *
31 | *--------------------------------------------------------------------*
32 | *
33 | * The function module /UI5/UI5_REPOSITORY_LOAD_HTTP loads a SAPUI5
34 | * application accessible at IV_URL into a SAPUI5 ABAP repository.
35 | *
36 | * Remarks:
37 | *
38 | * > As a mandatory input parameter the source url (IV_URL) has to be
39 | * passed. It points to a ZIP archive containing the SAPUI5 application
40 | * to be loaded into the SAPUI5 ABAP repository.
41 | *
42 | * > The parameter IV_TEST mode triggers a test run in which no upload
43 | * takes place. The export parameter EV_LOG_MESSAGES holds a detailed
44 | * log then.
45 | *
46 | * Use the test mode to investigate behavior of the function module
47 | * you did not expect.
48 | *
49 | * > Further parameters are taken preferably from the function module's
50 | * import parameters or from the file .Ui5RepositoryUploadParameters
51 | * located in the archive.
52 | *
53 | * As an advantage the function module can be started easily with a
54 | * set of documented standard parameters
55 | * e.g. automatically in the context of a Maven build process.
56 | *
57 | * > If you specify a parameter in the parameter file, you need
58 | * to place ist value in a line having the form
59 | * =
60 | *
61 | * Examples: SAPUI5ApplicationName=UI5_HCM_LR_APV
62 | * AcceptUnixStyleEol=True or X or Yes or 1
63 | *
64 | * > Overview of input parameters:
65 | *
66 | * ---------------------------------------------------------------------------------------------------------------------
67 | * Parameter Name Name Mandatory Default Remark
68 | * for use in in signature
69 | * parameter file of function module
70 | * ---------------------------------------------------------------------------------------------------------------------
71 | * % IV_URL Yes % Url needs to point to valid
72 | * zip archive.
73 | * SAPUI5ApplicationName IV_SAPUI5_APPLICATION_NAME Yes % App may be created or updated
74 | * SAPUI5ApplicationDescription IV_SAPUI5_APPLICATION_DESC No Used when app is to be created
75 | * in the SAPUI5 ABAP repository.
76 | * SAPUI5ApplicationPackage IV_PACKAGE No '$TMP'
77 | * WorkbenchRequest IV_WORKBENCH_REQUEST Depends Needed in case package is not $TMP.
78 | * ExternalCodePage IV_EXTERNAL_CODE_PAGE Depends Codepage Needed in case SAPGUI not installed.
79 | * of SAPGUI E.g. "Cp1252" for Windows Standard
80 | * AcceptUnixStyleEol IV_ACCEPT_UNIX_STYLE_EOL No ABAP_TRUE Triggers automatic conversion
81 | * of unix style text files to the
82 | * Windows format expected by the
83 | * repository.
84 | * DeltaMode IV_DELTA_MODE No ABAP_FALSE Only changes to current state in
85 | * the repository get registered
86 | * in workbench request.
87 | * % IV_TEST_MODE No ABAP_FALSE Upload operation is skipped then.
88 | * ---------------------------------------------------------------------------------------------------------------------
89 | * Legend: '%' means 'None"
90 | * ---------------------------------------------------------------------------------------------------------------------
91 | *
92 | * > Use the export variable EV_SUCCESS to check if the operation
93 | * was successful ('S'), a warning was indicated ('W') or an error
94 | * happened ('E').
95 | *
96 | * In addition EV_MSG_ID and EV_MSG_NO give access to a message
97 | * with the outcome of the function call.
98 | *
99 | * Have a look into the output EV_LOG_MESSAGES for the details.
100 | *
101 | * > In order to further control the upload operation you may place the
102 | * text files '.Ui5RepositoryIgnore', '.Ui5RepositoryTextFiles' or
103 | * '.Ui5RepositoryTextFiles' in the archive.
104 | *
105 | * Each line in '.Ui5RepositoryIgnore' describes a file pattern
106 | * indicating which files should be ignored during upload. The line
107 | * may contain a substring of the file path or a regular expression
108 | * starting with '^' and ending with '$'. This setting overwrites
109 | * the built-in default.
110 | *
111 | * Create or change the files '.Ui5RepositoryTextFiles' or
112 | * '.Ui5RepositoryTextFiles' used to identify text and binary content
113 | * in addition to the built-in default.
114 | *
115 | * > You may use the reports /UI5/UI5_REPOSITORY_LOAD_HTTP and
116 | * /UI5/UI5_REPOSITORY_LOAD_HTTPN to operate this function module
117 | * interactivly or to schedule its operation.
118 | *
119 | * /UI5/UI5_REPOSITORY_LOAD_HTTP is for the upload of a single app.
120 | * /UI5/UI5_REPOSITORY_LOAD_HTTPN may handle more than one app.
121 | *
122 | * A jenkins plugin which allows integration in a Maven build
123 | * process is being developed.
124 | *
125 | * > In order to up- and download SAPUI5 applications to and from the
126 | * file system you may use the report /UI5/UI5_REPOSITORY_LOAD.
127 | *
128 | * > Find SAP internal information here:
129 | * http://vesapui5.dhcp.wdf.sap.corp:1080/trac/sapui5.tools/wiki/SAPUI5Tools/UI5RepositoryLoadFaq
130 |
131 | ************************************************************************
132 | * Check inputs
133 | ************************************************************************
134 |
135 | * Initialize
136 | ev_success = status_success.
137 | *
138 | DATA: message TYPE string,
139 | empty_line TYPE string,
140 | parameter TYPE string.
141 | empty_line = '.'.
142 | APPEND TEXT-001 TO ev_log_messages. "***** Upload of SAPUI5 Application from ZIP-Archive into SAPUI5 ABAP Repository *****
143 | APPEND empty_line TO ev_log_messages.
144 |
145 | * Debugging conversions for a specific file
146 | * ... In case you would like to debug:
147 | * Specify resource name here - e.g. 'utils.js'
148 | lcl_ui5_repository=>debug_conversions_for_file = ''.
149 | "lcl_ui5_repository=>debug_conversions_for_file = 'utils.js'.
150 |
151 | * Indicate test mode
152 | IF iv_test_mode = abap_true.
153 | APPEND TEXT-002 TO ev_log_messages. "* Running in test mode: Upload operations are skipped, Detailed Log *
154 | APPEND empty_line TO ev_log_messages.
155 | ELSE.
156 | APPEND TEXT-003 TO ev_log_messages. "* Running in regular mode: Brief Log *
157 | APPEND empty_line TO ev_log_messages.
158 | ENDIF.
159 |
160 | * Check Url to SAPUI5 application
161 |
162 | * ... Is not empty
163 | IF iv_url IS INITIAL AND iv_zip_file IS INITIAL.
164 | ev_success = status_error.
165 | APPEND TEXT-010 TO ev_log_messages. "* Upload canceled: Url to Zip File containing SAPUI5 App is missing. *
166 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
167 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
168 | EXIT.
169 | ENDIF.
170 |
171 | * ... Refers to zip file
172 | " IF iv_url NS '.zip'.
173 | " ev_success = abap_false.
174 | " message = text-010. APPEND message TO ev_log_messages.
175 | " EXIT.
176 | " ENDIF.
177 |
178 | * ... Points to valid archive
179 | DATA: sapui5_archive TYPE REF TO lcl_sapui5_zip_archive,
180 | log_messages_ref TYPE REF TO string_table.
181 | GET REFERENCE OF ev_log_messages INTO log_messages_ref.
182 | CREATE OBJECT sapui5_archive
183 | EXPORTING
184 | iv_url = iv_url
185 | iv_zip_file = iv_zip_file
186 | ir_log_messages = log_messages_ref.
187 | IF ( sapui5_archive->is_ok( ) = abap_false ).
188 | ev_success = status_error.
189 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
190 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
191 | EXIT.
192 | ENDIF.
193 |
194 | * Determine and check upload parameters
195 |
196 | * ... Name of SAPUI5 Repositiory
197 | * Take from import parameter or from zip archive file .Ui5RepositoryUploadParameters
198 | * Exit if no name given
199 | DATA: sapui5_application_name TYPE string,
200 | sapui5_application_desc TYPE string.
201 | sapui5_application_name = iv_sapui5_application_name.
202 | IF sapui5_application_name IS INITIAL.
203 | sapui5_application_name = sapui5_archive->get_upload_parameter('SAPUI5ApplicationName').
204 | message = TEXT-026. ". %1 "%2" has been determined from the '.Ui5RepositoryUploadParameters' file
205 | ELSE.
206 | message = TEXT-027. ". %1 "%2" has been determined from the corresponding import parameter
207 | ENDIF.
208 | REPLACE '%1' IN message WITH TEXT-100. "Name of SAPUI5 Application
209 | REPLACE '%2' IN message WITH sapui5_application_name.
210 |
211 | IF sapui5_application_name IS NOT INITIAL.
212 | APPEND message TO ev_log_messages.
213 | ELSE.
214 | ev_success = status_error.
215 | APPEND TEXT-015 TO ev_log_messages. "Specify SAPUI5 Application Name
216 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
217 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
218 | EXIT.
219 | ENDIF.
220 |
221 | * ... Access SAPUI5 ABAP Repository
222 | DATA: ui5_repository TYPE REF TO lcl_ui5_repository.
223 | ui5_repository = lcl_ui5_repository=>get_instance( ir_log_messages = log_messages_ref ).
224 | ui5_repository->set_name( sapui5_application_name ).
225 | IF ui5_repository->name IS INITIAL. "this indicates an invalid name
226 | ev_success = status_error.
227 | APPEND TEXT-090 TO ev_log_messages. "* Name of SAPUI5 Application appears to be invalid: Same rules as for BSP applications apply
228 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
229 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
230 | EXIT.
231 | ENDIF.
232 |
233 | * ... Description of SAPUI5 repository
234 | * is used if repository does not yet exist.
235 | IF ui5_repository->already_exists = abap_false.
236 | sapui5_application_desc = iv_sapui5_application_desc.
237 | IF sapui5_application_desc IS NOT INITIAL.
238 | message = TEXT-027.
239 | ENDIF.
240 | IF sapui5_application_desc IS INITIAL.
241 | sapui5_application_desc = sapui5_archive->get_upload_parameter('SAPUI5ApplicationDescription').
242 | IF sapui5_application_desc IS NOT INITIAL.
243 | message = TEXT-026.
244 | ENDIF.
245 | ENDIF.
246 | IF sapui5_application_desc IS NOT INITIAL.
247 | REPLACE '%1' IN message WITH TEXT-101. "Description of SAPUI5 Application
248 | REPLACE '"%2" ' IN message WITH ''.
249 | CONDENSE message. "Remove double spaces
250 | APPEND message TO ev_log_messages.
251 | ENDIF.
252 | ENDIF.
253 |
254 | * ... Package for SAPUI5 application
255 | * is defaulted to $TMP if not specified elsewhere
256 | DATA: application_package TYPE string.
257 | application_package = iv_package.
258 | IF application_package IS NOT INITIAL.
259 | message = TEXT-027. ". %1 "%2" has been determined from the corresponding import parameter.
260 | ENDIF.
261 | IF application_package IS INITIAL.
262 | application_package = sapui5_archive->get_upload_parameter('SAPUI5ApplicationPackage').
263 | IF application_package IS NOT INITIAL.
264 | message = TEXT-026. ". %1 "%2" has been determined from the '.Ui5RepositoryUploadParameters' file.
265 | ENDIF.
266 | ENDIF.
267 | IF application_package IS NOT INITIAL.
268 | REPLACE '%1' IN message WITH TEXT-103. "Package of SAPUI5 Application
269 | REPLACE '%2' IN message WITH application_package.
270 | APPEND message TO ev_log_messages.
271 | ENDIF.
272 | IF application_package IS INITIAL.
273 | application_package = '$TMP'.
274 | message = TEXT-036.
275 | APPEND message TO ev_log_messages.
276 | ENDIF.
277 |
278 | * Package needs to be specified if repository already exists.
279 | * ... should not happen as package is defaulted
280 | IF ui5_repository->already_exists = abap_false
281 | AND application_package IS INITIAL.
282 | ev_success = status_error.
283 | message = TEXT-017. APPEND message TO ev_log_messages. "* Repository Package is not definded *
284 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
285 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
286 | EXIT.
287 | ENDIF.
288 |
289 | * Workbench request
290 | * ... may be empty if package is $TMP (local)
291 | DATA: repository_workbench_request TYPE string.
292 | repository_workbench_request = iv_workbench_request.
293 | IF repository_workbench_request IS NOT INITIAL.
294 | message = TEXT-027.
295 | ENDIF.
296 | IF repository_workbench_request IS INITIAL.
297 | repository_workbench_request = sapui5_archive->get_upload_parameter('WorkbenchRequest').
298 | IF repository_workbench_request IS NOT INITIAL.
299 | message = TEXT-026.
300 | ENDIF.
301 | ENDIF.
302 | IF repository_workbench_request IS NOT INITIAL.
303 | REPLACE '%1' IN message WITH TEXT-104. "Workbench Request
304 | REPLACE '%2' IN message WITH repository_workbench_request.
305 | APPEND message TO ev_log_messages.
306 | ELSE.
307 | IF application_package NE '$TMP'.
308 | ev_success = status_error.
309 | message = TEXT-016. "* Upload canceled: ABAP workbench request for SAPUI5 ABAP Repository not specified. *
310 | APPEND message TO ev_log_messages.
311 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
312 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
313 | EXIT.
314 | ENDIF.
315 | ENDIF.
316 |
317 | * External code page of text files in archive
318 | DATA: external_code_page_name TYPE string.
319 | external_code_page_name = iv_external_code_page.
320 | IF external_code_page_name IS NOT INITIAL.
321 | message = TEXT-027.
322 | ENDIF.
323 | IF external_code_page_name IS INITIAL.
324 | external_code_page_name = sapui5_archive->get_upload_parameter('ExternalCodePage').
325 | IF external_code_page_name IS NOT INITIAL.
326 | message = TEXT-026.
327 | ENDIF.
328 | ENDIF.
329 | IF external_code_page_name IS NOT INITIAL.
330 | REPLACE '%1' IN message WITH TEXT-105. "External Code Page
331 | REPLACE '%2' IN message WITH external_code_page_name.
332 | APPEND message TO ev_log_messages.
333 | ELSE.
334 | DATA: lv_ex TYPE REF TO cx_root.
335 | TRY.
336 | DATA: ecp TYPE REF TO lcl_external_code_page.
337 | ecp = lcl_external_code_page=>for_sapgui_installation( ).
338 | external_code_page_name = ecp->get_java_encoding( ).
339 | message = TEXT-018. "* Code page has been set to % *
340 | REPLACE '%' IN message WITH external_code_page_name.
341 | APPEND message TO ev_log_messages.
342 | CATCH lcx_exception INTO lv_ex.
343 | ev_success = status_error.
344 | message = TEXT-091. "* Upload canceled: External code page has not been specified. *
345 | APPEND message TO ev_log_messages.
346 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
347 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
348 | EXIT.
349 | ENDTRY.
350 | ENDIF.
351 |
352 | * Accept unix style line endings
353 | * ... default to ABAP_TRUE
354 | DATA: accept_unix_style_line_endings TYPE abap_bool.
355 | accept_unix_style_line_endings = iv_accept_unix_style_eol.
356 | IF accept_unix_style_line_endings NE abap_undefined.
357 | message = TEXT-027. ". %1 "%2" has been determined from the corresponding import parameter.
358 | ELSE.
359 | parameter =
360 | sapui5_archive->get_upload_parameter( iv_key = 'AcceptUnixStyleEol'
361 | iv_return_if_not_specified = '-' ).
362 | accept_unix_style_line_endings = lcl_function=>text_to_abap_bool( parameter ).
363 | IF accept_unix_style_line_endings NE abap_undefined.
364 | message = TEXT-026. ". %1 "%2" has been determined from the '.Ui5RepositoryUploadParameters' file.
365 | ENDIF.
366 | ENDIF.
367 | IF accept_unix_style_line_endings NE abap_undefined.
368 | REPLACE '%1' IN message WITH TEXT-106. "Acceptance of Unix style line delimeters in text files
369 | REPLACE '"%2" ' IN message WITH ''. CONDENSE message.
370 | APPEND message TO ev_log_messages.
371 | ELSE.
372 | accept_unix_style_line_endings = abap_true.
373 | ENDIF.
374 | * ... Indicate
375 | IF accept_unix_style_line_endings = abap_true.
376 | message = TEXT-037. "Unix style end of line markers in text files get accepted.
377 | ELSE.
378 | message = TEXT-038. "Unix style end of line markers in text files get rejected.
379 | ENDIF.
380 | APPEND message TO ev_log_messages.
381 |
382 | * Delta mode
383 | DATA: delta_mode TYPE abap_bool.
384 | * ... Determine from function parameter or upload parameter file
385 | delta_mode = iv_delta_mode.
386 | IF delta_mode = abap_undefined.
387 | parameter =
388 | sapui5_archive->get_upload_parameter( iv_key = 'DeltaMode'
389 | iv_return_if_not_specified = '-' ).
390 | delta_mode = lcl_function=>text_to_abap_bool( parameter ).
391 | ENDIF.
392 | * ... Delta-mode off if not specified.
393 | IF delta_mode = abap_undefined.
394 | delta_mode = abap_false.
395 | ENDIF.
396 | * ... Indicate Delta Mode
397 | IF delta_mode = abap_true.
398 | message = TEXT-034. ". The delta mode has been turned on.
399 | ELSE.
400 | message = TEXT-035. ". The delta mode has been turned off.
401 | ENDIF.
402 | APPEND message TO ev_log_messages.
403 |
404 | * ... Indicate if BAdI /UI5/BADI_PREVENT_DELETION to prevent the deletion of mime objects
405 | * has been implemented: This SAP internal BAdI may cause inconsistencies between
406 | * the app beeing uploaded and the SAPUI5 ABAP repository
407 | DATA: badi_to_prevent_deletion TYPE REF TO lcl_badi,
408 | workbench_request TYPE trkorr.
409 | workbench_request = repository_workbench_request.
410 | CREATE OBJECT badi_to_prevent_deletion
411 | EXPORTING
412 | iv_test_mode = iv_test_mode
413 | iv_sapui5_application_name = sapui5_application_name
414 | iv_workbench_request = workbench_request.
415 | IF badi_to_prevent_deletion->implementation IS NOT INITIAL.
416 | APPEND TEXT-039 TO ev_log_messages. ". Attention: A BAdI implementation for /UI5/BADI_PREVENT_DELETION is active
417 | ENDIF.
418 |
419 | *
420 | APPEND empty_line TO ev_log_messages.
421 |
422 |
423 | ************************************************************************
424 | * Determine upload operations
425 | ************************************************************************
426 |
427 | "message = text-041. "* Analyzing Archive *
428 | "append message to ev_log_messages.
429 |
430 | TYPES: operations TYPE TABLE OF REF TO lcl_operation.
431 | DATA: load_operations TYPE operations.
432 | sapui5_archive->determine_upload_operations( EXPORTING iv_delta_mode = delta_mode
433 | iv_code_page = external_code_page_name
434 | iv_accept_unix_style_eol = accept_unix_style_line_endings
435 | CHANGING cv_load_operations = load_operations
436 | cv_success = ev_success ).
437 |
438 | ************************************************************************
439 | * Explore SAPUI5 application to upload and conciliate operations
440 | ************************************************************************
441 |
442 | * Conciliate
443 | workbench_request = repository_workbench_request.
444 | ui5_repository->conciliate_upload_operations( EXPORTING iv_delta_mode = delta_mode
445 | iv_badi = badi_to_prevent_deletion
446 | iv_archive = sapui5_archive
447 | CHANGING cv_upload_operations = load_operations ).
448 |
449 | * Estimate authorization
450 | DATA: authorization_warning TYPE string.
451 | authorization_warning = ui5_repository->evaluate_authorization( ).
452 | IF authorization_warning IS NOT INITIAL.
453 | APPEND authorization_warning TO ev_log_messages.
454 | APPEND empty_line TO ev_log_messages.
455 | ENDIF.
456 |
457 | * Return if in test mode or in case an error occurred
458 | DATA: upload_operation TYPE REF TO lcl_operation.
459 | IF iv_test_mode = abap_true OR badi_to_prevent_deletion->error_occurred = abap_true.
460 |
461 | * List operations
462 | message = TEXT-040. "* Operations % *
463 | APPEND message TO ev_log_messages.
464 | LOOP AT load_operations INTO upload_operation.
465 | message = upload_operation->create_log_message( ).
466 | IF message IS INITIAL. CONTINUE. ENDIF.
467 | CONCATENATE '. ' message INTO message RESPECTING BLANKS.
468 | APPEND message TO ev_log_messages.
469 | ENDLOOP.
470 |
471 | * Inidicate BAdI error if occurred
472 | IF badi_to_prevent_deletion->error_occurred = abap_true.
473 | ev_success = status_error.
474 | APPEND empty_line TO ev_log_messages.
475 | APPEND TEXT-093 TO ev_log_messages. "* Upload canceled: A BAdI error has occurred. *
476 | CONCATENATE '. ' badi_to_prevent_deletion->error_text INTO message RESPECTING BLANKS.
477 | APPEND message TO ev_log_messages.
478 | ENDIF.
479 |
480 | * Return message
481 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
482 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
483 | EXIT.
484 | ENDIF.
485 |
486 |
487 | ************************************************************************
488 | * Upload application
489 | ************************************************************************
490 |
491 | ***** Prepare upload parameters ****************************************
492 |
493 | * Description
494 | DATA: upload_parameters TYPE lcl_ui5_repository=>upload_parameters.
495 | upload_parameters-description = sapui5_application_desc.
496 |
497 | * Package
498 | upload_parameters-package = application_package.
499 |
500 | * Transport_request
501 | upload_parameters-transport_request = repository_workbench_request.
502 |
503 | * Code page
504 | upload_parameters-code_page_ui = external_code_page_name.
505 | TRY.
506 | ecp = lcl_external_code_page=>create( upload_parameters-code_page_ui ).
507 | upload_parameters-code_page_abap = ecp->get_abap_encoding( ).
508 | upload_parameters-code_page_java = ecp->get_java_encoding( ).
509 |
510 | * Confirm valid code page has been entered.
511 | IF upload_parameters-code_page_abap IS INITIAL.
512 | ev_success = status_error.
513 | APPEND TEXT-032 TO ev_log_messages. "* Upload canceled: External Code Page is invalid. You may use e.g. 'Cp1252' *
514 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
515 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
516 | EXIT.
517 | ENDIF.
518 |
519 | CATCH cx_root.
520 |
521 | * General code page problem
522 | ev_success = status_error.
523 | APPEND TEXT-033 TO ev_log_messages. "* Upload canceled: Code Page is invalid. *
524 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
525 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
526 | EXIT.
527 |
528 | ENDTRY.
529 |
530 | ***** Create SAPUI5 ABAP repository if neccessary *********************
531 |
532 | IF ui5_repository->already_exists = abap_false.
533 |
534 | * Message
535 | message = TEXT-028. "* Creating new SAPUI5 application % *
536 | REPLACE '%' IN message WITH ui5_repository->name.
537 | APPEND message TO ev_log_messages.
538 |
539 | * Delegate ...
540 | DATA: lv_ex_rep_dt TYPE REF TO /ui5/cx_ui5_rep_dt.
541 | TRY.
542 | ui5_repository->api =
543 | /ui5/cl_ui5_rep_dt=>/ui5/if_ui5_rep_dt~create_repository(
544 | iv_name = ui5_repository->name
545 | iv_description = upload_parameters-description
546 | iv_devclass = upload_parameters-package
547 | iv_transport_request = upload_parameters-transport_request
548 | iv_dialog_mode = space ).
549 |
550 | CATCH /ui5/cx_ui5_rep_dt INTO lv_ex_rep_dt.
551 | * Cleanup
552 | IF ui5_repository->api IS NOT INITIAL. CLEAR ui5_repository->api. ENDIF.
553 |
554 | * If any: write error text on log
555 | ev_success = status_error.
556 | DATA: text TYPE string.
557 | text = lv_ex_rep_dt->get_text( ).
558 | IF text IS NOT INITIAL.
559 | CONCATENATE '* ' text ' *' INTO text RESPECTING BLANKS.
560 | APPEND text TO ev_log_messages.
561 | ENDIF.
562 | APPEND TEXT-030 TO ev_log_messages. "* SAPUI5 application has not been created (successfully) *
563 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
564 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
565 | EXIT.
566 | ENDTRY.
567 | ENDIF.
568 |
569 | * Update message if repository does already exist
570 | IF ui5_repository->already_exists = abap_true.
571 | message = TEXT-029. "* Updating existing SAPUI5 application % *
572 | REPLACE '%' IN message WITH ui5_repository->name.
573 | APPEND message TO ev_log_messages.
574 | ENDIF.
575 |
576 | ***** Perform upload ***************************************************
577 |
578 | * Perform upload operation and write log entry
579 | TRY.
580 | ui5_repository->api->lock( ).
581 | CATCH /ui5/cx_ui5_rep_dt.
582 | ev_success = status_error.
583 | APPEND TEXT-092 TO ev_log_messages. "* Upload canceled: Unable to lock SAPUI5 repository *
584 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
585 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
586 | EXIT.
587 | ENDTRY.
588 |
589 | ***** Loop at each operation *****
590 | * and if requested ...
591 | DATA: lv_message TYPE string.
592 | LOOP AT load_operations INTO upload_operation.
593 |
594 | * Continue if nothing to do
595 | IF delta_mode EQ abap_true
596 | AND upload_operation->to_update NE abap_true.
597 | CONTINUE.
598 | ENDIF.
599 |
600 | CASE upload_operation->operation.
601 |
602 | ***** Create folder *****
603 |
604 | WHEN lcl_operation=>create_folder.
605 |
606 | TRY.
607 | ui5_repository->api->create_folder( iv_path = upload_operation->relative_path
608 | iv_transport_request = upload_parameters-transport_request ).
609 | CATCH /ui5/cx_ui5_rep_dt.
610 | lv_message = '* Warning: Folder % has not been created *'(054).
611 | REPLACE '%' IN lv_message WITH upload_operation->relative_path.
612 | APPEND lv_message TO ev_log_messages.
613 | ENDTRY.
614 |
615 | ***** Upload text or binary file ****
616 |
617 | WHEN lcl_operation=>upload_file.
618 | IF ( upload_operation->object_type = lcl_operation=>object_type_text_file
619 | OR upload_operation->object_type = lcl_operation=>object_type_binary_file ).
620 | TRY.
621 |
622 | * Read file from archive
623 | DATA: file_content TYPE xstring.
624 | DATA: upload_operation_is_binary TYPE abap_bool.
625 | upload_operation_is_binary = upload_operation->is_binary( ).
626 | file_content = sapui5_archive->read_file( iv_path = upload_operation->full_path ).
627 | "file_content = file_system->read_file( iv_file_path = upload_operation->full_path
628 | " iv_file_is_binary = upload_operation_is_binary
629 | " iv_code_page_abap = upload_parameters-code_page_abap ).
630 |
631 | * Convert line endings of text files from unix to windows format
632 | * ... if needed and requested
633 | IF upload_operation->object_type = lcl_operation=>object_type_text_file
634 | AND upload_operation->eol_conversion = abap_true
635 | AND accept_unix_style_line_endings = abap_true.
636 | DATA: file_content_as_is TYPE string,
637 | file_content_as_string TYPE string,
638 | file_content_as_string_windows TYPE string.
639 | TRY.
640 | file_content_as_is = file_content.
641 | file_content_as_string =
642 | /ui5/cl_ui5_rep_utility=>convert_xstring_2_string( iv_xstring = file_content
643 | iv_code_page = upload_operation->code_page ).
644 | file_content_as_string_windows =
645 | lcl_function=>conv_unix_style_line_endings( iv_string = file_content_as_string ).
646 | file_content =
647 | /ui5/cl_ui5_rep_utility=>convert_string_2_xstring( iv_string = file_content_as_string_windows
648 | iv_code_page = upload_operation->code_page ).
649 | CATCH /ui5/cx_ui5_rep_dt.
650 | CATCH cx_sy_conversion_error.
651 | ev_success = status_error.
652 | file_content = file_content_as_is.
653 | lv_message = '* Error: Unable to convert Unix style text file % *'(057).
654 | REPLACE '%' IN lv_message WITH upload_operation->relative_path.
655 | APPEND lv_message TO ev_log_messages.
656 | ENDTRY.
657 | ENDIF.
658 |
659 | * Upload content into ui5 repository
660 | DATA: mime_type TYPE string.
661 | mime_type = ui5_repository->get_mime_type_for_upload( upload_operation ).
662 | upload_operation_is_binary = upload_operation->is_binary( ).
663 | TRY.
664 | CALL METHOD ui5_repository->api->put_file
665 | EXPORTING
666 | iv_path = upload_operation->relative_path
667 | iv_transport_request = upload_parameters-transport_request
668 | iv_file_content = file_content
669 | iv_mime_type = mime_type "ui5_repository->get_mime_type_for_upload( upload_operation )
670 | iv_code_page = upload_parameters-code_page_java
671 | iv_is_binary = upload_operation_is_binary. "upload_operation->is_binary( ).
672 | lv_message = upload_operation->create_log_message( ).
673 | APPEND lv_message TO ev_log_messages.
674 |
675 | * Put content of version.json as log message:
676 | * No more than 15 lines with a maximum length of 120 characters
677 | IF upload_operation->full_path CS 'version.json'
678 | AND upload_operation_is_binary = abap_false. "#EC NOTEXT
679 | TRY.
680 | * Convert to windows format
681 | file_content_as_is = file_content.
682 | file_content_as_string =
683 | /ui5/cl_ui5_rep_utility=>convert_xstring_2_string( iv_xstring = file_content
684 | iv_code_page = upload_operation->code_page ).
685 | file_content_as_string_windows =
686 | lcl_function=>conv_unix_style_line_endings( iv_string = file_content_as_string ).
687 | * Retrieve lines
688 | DATA: lines TYPE o2pageline_table.
689 | lines = /ui5/cl_ui5_rep_utility=>code_string_2_code_tab( iv_src_string = file_content_as_string_windows ).
690 | * Prepare and write lines
691 | IF lines( lines ) < 15.
692 | LOOP AT lines INTO lv_message.
693 | "Mini escaping and beautification
694 | REPLACE ALL OCCURRENCES OF '<' IN lv_message WITH '<'. "#EC NOTEXT
695 | REPLACE ALL OCCURRENCES OF '>' IN lv_message WITH '>'. "#EC NOTEXT
696 | REPLACE ALL OCCURRENCES OF '"' IN lv_message WITH ''. "#EC NOTEXT
697 | REPLACE ALL OCCURRENCES OF '"' IN lv_message WITH ''. "#EC NOTEXT
698 | IF strlen( lv_message ) > 120.
699 | lv_message = lv_message(120).
700 | CONCATENATE lv_message ' ...' INTO lv_message RESPECTING BLANKS. "#EC NOTEXT
701 | ENDIF.
702 | CONCATENATE '. ' lv_message INTO lv_message RESPECTING BLANKS. "#EC NOTEXT
703 | APPEND lv_message TO ev_log_messages.
704 | ENDLOOP.
705 | ENDIF.
706 | CATCH cx_root .
707 | ENDTRY.
708 | ENDIF.
709 |
710 | CATCH /ui5/cx_ui5_rep_dt INTO lv_ex_rep_dt.
711 | * Write error message for UI5 repository problems
712 | text = lv_ex_rep_dt->get_text( ).
713 | CONCATENATE '* ' text ' *' INTO lv_message RESPECTING BLANKS.
714 | APPEND lv_message TO ev_log_messages.
715 | RAISE EXCEPTION TYPE lcx_exception.
716 | ENDTRY.
717 |
718 | CATCH lcx_exception.
719 | * Write error message for UI5 repository problems
720 | IF upload_operation->is_binary( ) = abap_true.
721 | lv_message = '* Warning: Text file % has not been uploaded *'(055).
722 | ELSEIF upload_operation->is_binary( ) = abap_false.
723 | lv_message = '* Warning: Binary file % has not been uploaded *'(064).
724 | ENDIF.
725 | REPLACE '%' IN lv_message WITH upload_operation->relative_path.
726 | APPEND lv_message TO ev_log_messages.
727 | IF ev_success = status_success. "Keep status error
728 | ev_success = status_warning.
729 | ENDIF.
730 | ENDTRY.
731 | ENDIF.
732 |
733 | * Delete file/folder in UI5 repository
734 | WHEN lcl_operation=>delete_file OR
735 | lcl_operation=>delete_folder.
736 | TRY.
737 | ui5_repository->api->delete( iv_path = upload_operation->relative_path
738 | iv_transport_request = upload_parameters-transport_request ).
739 | lv_message = upload_operation->create_log_message( ). "
740 | APPEND lv_message TO ev_log_messages. "
741 | CATCH /ui5/cx_ui5_rep_dt INTO lv_ex_rep_dt.
742 | * Write error message for UI5 repository problems
743 | text = lv_ex_rep_dt->get_text( ).
744 | CONCATENATE '* ' text ' *' INTO lv_message RESPECTING BLANKS.
745 | APPEND lv_message TO ev_log_messages.
746 | ENDTRY.
747 |
748 | ***** Indicate files and folders being ignored *****
749 |
750 | * Ignore file
751 | * Ignore folder
752 | WHEN lcl_operation=>ignore_file OR
753 | lcl_operation=>ignore_folder.
754 | lv_message = upload_operation->create_log_message( ).
755 | APPEND lv_message TO ev_log_messages.
756 |
757 | ENDCASE.
758 | ENDLOOP.
759 |
760 | * Unlock SAPUI5 repository
761 | TRY.
762 | ui5_repository->api->unlock( ).
763 | CATCH /ui5/cx_ui5_rep_dt.
764 | ENDTRY.
765 |
766 | ************* Recalculate application index and write log messages*********************************
767 |
768 | IF iv_test_mode NE abap_true.
769 |
770 | DATA: lr_app_index TYPE REF TO /ui5/cl_ui5_app_index.
771 | DATA: lv_application TYPE o2applname.
772 | DATA: lt_messages TYPE bapiret2_t.
773 | DATA: lv_log_msg TYPE string.
774 |
775 | FIELD-SYMBOLS: TYPE bapiret2.
776 |
777 | lr_app_index = /ui5/cl_ui5_app_index=>get_instance( ).
778 |
779 | lv_application = sapui5_application_name.
780 |
781 | CALL METHOD lr_app_index->recalculate_app
782 | EXPORTING
783 | iv_application = lv_application
784 | IMPORTING
785 | * es_result =
786 | et_messages = lt_messages.
787 |
788 | *
789 | APPEND empty_line TO ev_log_messages.
790 | APPEND TEXT-111 TO ev_log_messages.
791 |
792 | LOOP AT lt_messages ASSIGNING .
793 | CONCATENATE TEXT-110 -message INTO lv_log_msg SEPARATED BY space.
794 | APPEND lv_log_msg TO ev_log_messages.
795 | ENDLOOP.
796 |
797 | IF lt_messages IS NOT INITIAL.
798 | APPEND TEXT-112 TO ev_log_messages.
799 | ENDIF.
800 |
801 | ENDIF.
802 | *******************************************************************************************
803 |
804 |
805 | * Upload done
806 | APPEND empty_line TO ev_log_messages.
807 | APPEND TEXT-043 TO ev_log_messages. "* Done *
808 |
809 | * Set return message
810 | lcl_function=>set_return_msg( EXPORTING iv_success = ev_success iv_test_mode = iv_test_mode
811 | CHANGING cv_msg_id = ev_msg_id cv_msg_no = ev_msg_no ).
812 |
813 |
814 | ENDFUNCTION.
815 |
--------------------------------------------------------------------------------
/src/ycl_github_deployer.clas.abap:
--------------------------------------------------------------------------------
1 | *----------------------------------------------------------------------*
2 | * CLASS YCL_GITHUB_DEPLOYER DEFINITION
3 | *----------------------------------------------------------------------*
4 | * Documentation is at http://yelcho.github.io/sapui5-deployer/
5 | *----------------------------------------------------------------------*
6 | CLASS ycl_github_deployer DEFINITION
7 | PUBLIC
8 | FINAL
9 | CREATE PRIVATE .
10 |
11 | PUBLIC SECTION.
12 |
13 | CLASS-METHODS deploy
14 | IMPORTING
15 | !repository TYPE string
16 | !branch TYPE string
17 | !github_user TYPE string OPTIONAL
18 | !password TYPE string OPTIONAL
19 | !transport TYPE trkorr OPTIONAL
20 | !test_only TYPE boolean OPTIONAL .
21 | PROTECTED SECTION.
22 | private section.
23 |
24 | types:
25 | BEGIN OF submodule_info_type,
26 | folder TYPE string,
27 | repository TYPE string,
28 | branch TYPE string,
29 | END OF submodule_info_type .
30 | types:
31 | submodule_info_ttype TYPE STANDARD TABLE OF submodule_info_type .
32 |
33 | data REPOSITORY type STRING .
34 | data BRANCH type STRING .
35 | data TRANSPORT type TRKORR .
36 | data TEST_ONLY type BOOLEAN .
37 | data GITHUB_USER type STRING .
38 | data PASSWORD type STRING .
39 | data MINIFY_FILE_COUNT type I .
40 | data MINIFY_BYTE_COUNT type I .
41 | data ENABLE_MINIFY type BOOLEAN value ABAP_TRUE ##NO_TEXT.
42 | data JS_MINIFY_PARAMS type TIHTTPNVP .
43 | data CSS_MINIFY_PARAMS type TIHTTPNVP .
44 |
45 | methods CONSTRUCTOR
46 | importing
47 | !REPOSITORY type STRING
48 | !BRANCH type STRING
49 | !GITHUB_USER type STRING optional
50 | !PASSWORD type STRING optional
51 | !TRANSPORT type TRKORR optional
52 | !TEST_ONLY type BOOLEAN optional
53 | raising
54 | CX_SY_CREATE_DATA_ERROR .
55 | methods ADD_MODULE_TO_ARCHIVE
56 | importing
57 | !INFO type SUBMODULE_INFO_TYPE
58 | value(ARCHIVE) type ref to CL_ABAP_ZIP .
59 | methods CLEANUP_STRINGDATA
60 | importing
61 | !DATA_IN type STRING
62 | !NOGAPS type BOOLEAN optional
63 | returning
64 | value(DATA_OUT) type STRING .
65 | methods CLEANUP_XMLDATA
66 | importing
67 | !DATA_IN type STRING
68 | returning
69 | value(DATA_OUT) type STRING .
70 | methods GET_FILE_TYPE
71 | importing
72 | !IV_FILENAME type STRING
73 | returning
74 | value(RV_FILETYPE) type STRING .
75 | methods GET_CSS_MINIFY_PARAMS
76 | returning
77 | value(RT_PARAMS) type TIHTTPNVP .
78 | methods GET_JS_MINIFY_PARAMS
79 | returning
80 | value(RT_PARAMS) type TIHTTPNVP .
81 | methods GET_MODULE_ARCHIVE
82 | importing
83 | !URL type STRING
84 | returning
85 | value(ARCHIVE) type ref to CL_ABAP_ZIP .
86 | methods GET_SUBMODULE_INFO
87 | importing
88 | !IV_SUBMODULE_DATA type XSTRING
89 | exporting
90 | value(ET_SUBMODULE_INFO) type SUBMODULE_INFO_TTYPE .
91 | methods MINIFY
92 | importing
93 | !DATA_IN type XSTRING
94 | !FILE_TYPE type STRING
95 | returning
96 | value(DATA_OUT) type XSTRING .
97 | methods MINIFY_JS
98 | importing
99 | !DATA_IN type XSTRING
100 | returning
101 | value(DATA_OUT) type XSTRING .
102 | methods MINIFY_CSS
103 | importing
104 | !DATA_IN type XSTRING
105 | returning
106 | value(DATA_OUT) type XSTRING .
107 | methods REMOVE_COVER_FOLDER
108 | importing
109 | !ARCHIVE type ref to CL_ABAP_ZIP
110 | returning
111 | value(NEW_ARCHIVE) type ref to CL_ABAP_ZIP .
112 | methods SAVE_ARCHIVE_FILE
113 | importing
114 | !ARCHIVE type ref to CL_ABAP_ZIP .
115 | methods UPDATE_CACHEBUSTER .
116 | methods UPLOAD_ARCHIVE_INTO_ICF
117 | importing
118 | value(ARCHIVE) type ref to CL_ABAP_ZIP
119 | raising
120 | CX_SY_CREATE_DATA_ERROR .
121 | methods XSTRING_TO_STRING
122 | importing
123 | !IN type XSTRING
124 | returning
125 | value(OUT) type STRING .
126 | methods STRING_TO_XSTRING
127 | importing
128 | !IN type STRING
129 | returning
130 | value(OUT) type XSTRING .
131 | ENDCLASS.
132 |
133 |
134 |
135 | CLASS YCL_GITHUB_DEPLOYER IMPLEMENTATION.
136 |
137 |
138 | METHOD add_module_to_archive.
139 |
140 | DATA: lo_archive TYPE REF TO cl_abap_zip,
141 | ls_file LIKE LINE OF archive->files,
142 | lv_content TYPE xstring,
143 | lv_cdata TYPE string,
144 | lv_preload_namespace TYPE string,
145 | lt_preload_modules TYPE tihttpnvp,
146 | lr_preload_module TYPE REF TO ihttpnvp,
147 | lv_component TYPE string,
148 | lv_junk TYPE string ##needed.
149 |
150 | WRITE:/, `Adding module`, info-repository, info-branch, 'to archive'.
151 |
152 | lo_archive = remove_cover_folder( get_module_archive( |https://github.com/{ info-repository }/zipball/{ info-branch }| ) ).
153 |
154 | IF lo_archive IS NOT BOUND.
155 | WRITE:/, `Error with module`, info-repository, info-branch COLOR COL_NEGATIVE.
156 | RETURN.
157 | ENDIF.
158 |
159 | * Get Component-preload namespace
160 | READ TABLE lo_archive->files INTO ls_file WITH KEY name = 'Component.js'.
161 | IF sy-subrc = 0.
162 | lo_archive->get(
163 | EXPORTING
164 | name = ls_file-name
165 | IMPORTING
166 | content = lv_content
167 | EXCEPTIONS
168 | zip_index_error = 1
169 | zip_decompression_error = 2
170 | OTHERS = 3 ).
171 | IF sy-subrc = 0.
172 | lv_component = xstring_to_string( lv_content ).
173 | SPLIT lv_component AT `.extend(` INTO lv_junk lv_component.
174 | IF sy-subrc = 0.
175 | SHIFT lv_component LEFT DELETING LEADING: `'`, `"`.
176 | SPLIT lv_component AT `.Component` INTO lv_preload_namespace lv_junk.
177 | REPLACE ALL OCCURRENCES OF `.` IN lv_preload_namespace WITH `/`.
178 | WRITE: /, 'Preload component namespace is', lv_preload_namespace.
179 | ENDIF.
180 | ENDIF.
181 | ENDIF.
182 |
183 | LOOP AT lo_archive->files INTO ls_file.
184 | CLEAR lv_content.
185 | lo_archive->get(
186 | EXPORTING
187 | name = ls_file-name
188 | IMPORTING
189 | content = lv_content
190 | EXCEPTIONS
191 | zip_index_error = 1
192 | zip_decompression_error = 2
193 | OTHERS = 3 ).
194 |
195 | IF sy-subrc <> 0.
196 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
197 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
198 | RETURN.
199 | ENDIF.
200 |
201 | * Minification
202 | IF enable_minify = abap_true.
203 |
204 | lv_content = minify(
205 | data_in = lv_content
206 | file_type = get_file_type( ls_file-name ) ).
207 |
208 | * Collect details for Component.preload - not much point doing this unless minification works
209 | IF lv_preload_namespace IS NOT INITIAL.
210 | CASE get_file_type( ls_file-name ).
211 | WHEN 'JS'.
212 | APPEND INITIAL LINE TO lt_preload_modules REFERENCE INTO lr_preload_module.
213 | lr_preload_module->name = |{ lv_preload_namespace }/{ ls_file-name }|.
214 | lr_preload_module->value = xstring_to_string( lv_content ).
215 | WHEN 'XML'.
216 | IF ls_file-name CS '.view.xml'.
217 | APPEND INITIAL LINE TO lt_preload_modules REFERENCE INTO lr_preload_module.
218 | lr_preload_module->name = |{ lv_preload_namespace }/{ ls_file-name }|.
219 | lr_preload_module->value = me->cleanup_xmldata( xstring_to_string( lv_content ) ).
220 | ENDIF.
221 | WHEN 'PROPERTIES'.
222 | APPEND INITIAL LINE TO lt_preload_modules REFERENCE INTO lr_preload_module.
223 | lr_preload_module->name = |{ lv_preload_namespace }/{ ls_file-name }|.
224 | lr_preload_module->value = me->cleanup_xmldata( xstring_to_string( lv_content ) ).
225 | WHEN OTHERS.
226 | ENDCASE.
227 | ENDIF.
228 | ENDIF.
229 |
230 | IF info-folder IS NOT INITIAL.
231 | ls_file-name = |{ info-folder }/{ ls_file-name }|.
232 | ENDIF.
233 |
234 | * Process any Git submodules
235 | DATA: lt_submodule_info TYPE submodule_info_ttype,
236 | lr_submodule_info TYPE REF TO submodule_info_type.
237 | IF ls_file-name = '.gitmodules'.
238 | get_submodule_info(
239 | EXPORTING
240 | iv_submodule_data = lv_content
241 | IMPORTING
242 | et_submodule_info = lt_submodule_info ).
243 |
244 | LOOP AT lt_submodule_info REFERENCE INTO lr_submodule_info.
245 | add_module_to_archive(
246 | info = lr_submodule_info->*
247 | archive = archive ).
248 | ENDLOOP.
249 | ENDIF.
250 |
251 | archive->add(
252 | EXPORTING
253 | name = ls_file-name
254 | content = lv_content ).
255 | ENDLOOP.
256 |
257 | * Build Component.preload and add to archive
258 | IF lv_preload_namespace IS NOT INITIAL AND enable_minify = abap_true.
259 | LOOP AT lt_preload_modules REFERENCE INTO lr_preload_module.
260 | REPLACE ALL OCCURRENCES OF `"` IN lr_preload_module->value WITH `\"`.
261 | IF lv_cdata IS INITIAL.
262 | lv_cdata = |"{ lr_preload_module->name }":"{ lr_preload_module->value }"|.
263 | ELSE.
264 | lv_cdata = |{ lv_cdata },"{ lr_preload_module->name }":"{ lr_preload_module->value }"|.
265 | ENDIF.
266 | ENDLOOP.
267 | lv_cdata =
268 | |jQuery.sap.registerPreloadedModules(\{| &&
269 | |"version": "2.0",| &&
270 | |"name": "{ lv_preload_namespace }/Component-preload",| &&
271 | |"modules": \{| &&
272 | lv_cdata &&
273 | |\}| &&
274 | |\});|.
275 | archive->add(
276 | EXPORTING
277 | name = 'Component-preload.js'
278 | content = string_to_xstring( lv_cdata ) ).
279 | ENDIF.
280 |
281 | ENDMETHOD. "add_module_to_archive
282 |
283 |
284 | METHOD cleanup_stringdata.
285 |
286 | CONSTANTS: lf TYPE x LENGTH 4 VALUE '0A',
287 | cr TYPE x LENGTH 4 VALUE '0D',
288 | tab TYPE x LENGTH 4 VALUE '09',
289 | spc TYPE x LENGTH 4 VALUE '20'.
290 |
291 | FIELD-SYMBOLS: TYPE char1,
292 | TYPE char1,
293 | TYPE char1,
294 | TYPE char1.
295 |
296 | ASSIGN lf TO CASTING.
297 | ASSIGN cr TO CASTING.
298 | ASSIGN tab TO CASTING.
299 | ASSIGN spc TO CASTING.
300 |
301 | data_out = data_in.
302 |
303 | * Remove line feeds
304 | REPLACE ALL OCCURRENCES OF IN data_out WITH ''.
305 | * Remove carriage returns
306 | REPLACE ALL OCCURRENCES OF IN data_out WITH ''.
307 | * Replace tabs with space
308 | REPLACE ALL OCCURRENCES OF IN data_out WITH .
309 |
310 | IF nogaps = abap_true.
311 | CONDENSE data_out NO-GAPS.
312 | ELSE.
313 | CONDENSE data_out.
314 | ENDIF.
315 |
316 | ENDMETHOD. "minify
317 |
318 |
319 | METHOD cleanup_xmldata.
320 |
321 | CONSTANTS: lf TYPE x LENGTH 4 VALUE '0A',
322 | cr TYPE x LENGTH 4 VALUE '0D',
323 | tab TYPE x LENGTH 4 VALUE '09',
324 | spc TYPE x LENGTH 4 VALUE '20'.
325 |
326 | FIELD-SYMBOLS: TYPE char1,
327 | TYPE char1,
328 | TYPE char1,
329 | TYPE char1.
330 |
331 | ASSIGN lf TO CASTING.
332 | ASSIGN cr TO CASTING.
333 | ASSIGN tab TO CASTING.
334 | ASSIGN spc TO CASTING.
335 |
336 | data_out = data_in.
337 |
338 | * Replace tabs with \t
339 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>horizontal_tab IN data_out WITH '\t'.
340 | * Replace newlines with \n
341 | REPLACE ALL OCCURRENCES OF cl_abap_char_utilities=>newline IN data_out WITH '\n'.
342 | * Remove all spaces that immediately follow a new line - hope there are none inside XML data ;)
343 | DO.
344 | REPLACE ALL OCCURRENCES OF `\n ` IN data_out WITH `\n`.
345 | IF sy-subrc NE 0 OR sy-index > 500. EXIT. ENDIF.
346 | ENDDO.
347 |
348 | * Remove line feeds - should be none left
349 | REPLACE ALL OCCURRENCES OF IN data_out WITH ''.
350 | * Remove carriage returns
351 | REPLACE ALL OCCURRENCES OF IN data_out WITH ''.
352 |
353 | ENDMETHOD. "minify
354 |
355 |
356 | METHOD constructor.
357 |
358 | me->repository = repository.
359 | me->branch = branch.
360 | me->github_user = github_user.
361 | me->password = password.
362 | me->transport = transport.
363 | me->test_only = test_only.
364 |
365 | DATA: lo_archive TYPE REF TO cl_abap_zip,
366 | ls_module TYPE submodule_info_type.
367 |
368 | ls_module-repository = me->repository.
369 | ls_module-branch = me->branch.
370 |
371 | CREATE OBJECT lo_archive.
372 |
373 | add_module_to_archive(
374 | info = ls_module
375 | archive = lo_archive ).
376 |
377 | save_archive_file( lo_archive ).
378 |
379 | upload_archive_into_icf( lo_archive ).
380 |
381 | update_cachebuster( ).
382 |
383 | ENDMETHOD. "constructor
384 |
385 |
386 | METHOD deploy.
387 | DATA: deployer TYPE REF TO ycl_github_deployer.
388 |
389 | CREATE OBJECT deployer
390 | EXPORTING
391 | repository = repository
392 | branch = branch
393 | github_user = github_user
394 | password = password
395 | transport = transport
396 | test_only = test_only.
397 |
398 | ENDMETHOD. "deploy
399 |
400 |
401 | METHOD get_css_minify_params.
402 |
403 | IF css_minify_params IS INITIAL.
404 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO DATA(lr_param).
405 | lr_param->name = 'type'.
406 | lr_param->value = 'css'.
407 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
408 | lr_param->name = 'options[advanced]'.
409 | lr_param->value = 'true'.
410 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
411 | lr_param->name = 'options[aggressiveMerging]'.
412 | lr_param->value = 'true'.
413 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
414 | lr_param->name = 'options[rebase]'.
415 | lr_param->value = 'true'.
416 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
417 | lr_param->name = 'options[processImport]'.
418 | lr_param->value = 'true'.
419 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
420 | lr_param->name = 'options[benchmark]'.
421 | lr_param->value = 'false'.
422 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
423 | lr_param->name = 'options[compatibility]'.
424 | lr_param->value = 'false'.
425 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
426 | lr_param->name = 'options[keepBreaks]'.
427 | lr_param->value = 'false'.
428 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
429 | lr_param->name = 'options[debug]'.
430 | lr_param->value = 'false'.
431 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
432 | lr_param->name = 'options[inliner]'.
433 | lr_param->value = ''.
434 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
435 | lr_param->name = 'options[relativeTo]'.
436 | lr_param->value = ''.
437 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
438 | lr_param->name = 'options[root]'.
439 | lr_param->value = ''.
440 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
441 | lr_param->name = 'options[target]'.
442 | lr_param->value = ''.
443 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
444 | lr_param->name = 'options[keepSpecialComments]'.
445 | lr_param->value = '*'.
446 | APPEND INITIAL LINE TO css_minify_params REFERENCE INTO lr_param.
447 | lr_param->name = 'options[roundingPrecision]'.
448 | lr_param->value = '2'.
449 | ENDIF.
450 |
451 | rt_params = css_minify_params.
452 |
453 | ENDMETHOD. "get_css_minify_params
454 |
455 |
456 | METHOD get_file_type.
457 | DATA: lt_strings TYPE stringtab,
458 | lr_extension TYPE REF TO string.
459 |
460 | SPLIT iv_filename AT '.' INTO TABLE lt_strings.
461 |
462 | LOOP AT lt_strings REFERENCE INTO lr_extension. ENDLOOP.
463 | CHECK sy-subrc = 0.
464 |
465 | TRANSLATE lr_extension->* TO UPPER CASE.
466 |
467 | rv_filetype = lr_extension->*.
468 |
469 | ENDMETHOD. "GET_FILE_TYPE
470 |
471 |
472 | METHOD get_js_minify_params.
473 |
474 | IF js_minify_params IS INITIAL.
475 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO DATA(lr_param).
476 | lr_param->name = 'type'.
477 | lr_param->value = 'javascript'.
478 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
479 | lr_param->name = 'options[sequences]'.
480 | lr_param->value = 'true'.
481 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
482 | lr_param->name = 'options[properties]'.
483 | lr_param->value = 'true'.
484 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
485 | lr_param->name = 'options[dead_code]'.
486 | lr_param->value = 'true'.
487 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
488 | lr_param->name = 'options[drop_debugger]'.
489 | lr_param->value = 'true'.
490 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
491 | lr_param->name = 'options[conditionals]'.
492 | lr_param->value = 'true'.
493 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
494 | lr_param->name = 'options[comparisons]'.
495 | lr_param->value = 'true'.
496 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
497 | lr_param->name = 'options[evaluate]'.
498 | lr_param->value = 'true'.
499 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
500 | lr_param->name = 'options[booleans]'.
501 | lr_param->value = 'true'.
502 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
503 | lr_param->name = 'options[loops]'.
504 | lr_param->value = 'true'.
505 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
506 | lr_param->name = 'options[unused]'.
507 | lr_param->value = 'true'.
508 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
509 | lr_param->name = 'options[hoist_funs]'.
510 | lr_param->value = 'true'.
511 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
512 | lr_param->name = 'options[if_return]'.
513 | lr_param->value = 'true'.
514 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
515 | lr_param->name = 'options[join_vars]'.
516 | lr_param->value = 'true'.
517 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
518 | lr_param->name = 'options[cascade]'.
519 | lr_param->value = 'true'.
520 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
521 | lr_param->name = 'options[warnings]'.
522 | lr_param->value = 'true'.
523 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
524 | lr_param->name = 'options[negate_iife]'.
525 | lr_param->value = 'true'.
526 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
527 | lr_param->name = 'options[unsafe]'.
528 | lr_param->value = 'false'.
529 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
530 | lr_param->name = 'options[hoist_vars]'.
531 | lr_param->value = 'false'.
532 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
533 | lr_param->name = 'options[pure_getters]'.
534 | lr_param->value = 'false'.
535 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
536 | lr_param->name = 'options[drop_console]'.
537 | lr_param->value = 'false'.
538 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
539 | lr_param->name = 'options[keep_fargs]'.
540 | lr_param->value = 'false'.
541 | APPEND INITIAL LINE TO js_minify_params REFERENCE INTO lr_param.
542 | lr_param->name = 'options[pure_funcs]'.
543 | lr_param->value = ''.
544 | ENDIF.
545 |
546 | rt_params = js_minify_params.
547 |
548 | ENDMETHOD. "GET_JS_MINIFY_PARAMS
549 |
550 |
551 | METHOD get_module_archive.
552 |
553 | DATA: lr_client TYPE REF TO if_http_client,
554 | lv_code TYPE i,
555 | lv_message TYPE string.
556 |
557 | WRITE:/, `Retrieving archive from`, url.
558 |
559 | cl_http_client=>create_by_url(
560 | EXPORTING
561 | url = url
562 | ssl_id = 'ANONYM'
563 | IMPORTING
564 | client = lr_client
565 | EXCEPTIONS
566 | OTHERS = 1 ).
567 |
568 | IF sy-subrc <> 0.
569 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
570 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
571 | RETURN.
572 | ENDIF.
573 |
574 | IF me->github_user IS NOT INITIAL.
575 | lr_client->authenticate( username = me->github_user password = me->password ).
576 | lr_client->propertytype_accept_cookie = if_http_client=>co_enabled.
577 | ENDIF.
578 |
579 | lr_client->send( EXCEPTIONS OTHERS = 1 ).
580 | IF sy-subrc <> 0.
581 | lv_message = |http send error|.
582 | WRITE:/, lv_message COLOR COL_NEGATIVE.
583 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
584 | RETURN.
585 | ENDIF.
586 | lr_client->receive(
587 | EXCEPTIONS
588 | http_communication_failure = 1
589 | http_invalid_state = 2
590 | http_processing_failed = 3
591 | OTHERS = 4 ).
592 | IF sy-subrc <> 0.
593 | CASE sy-subrc.
594 | WHEN 1.
595 | " make sure:
596 | " a) SSL is setup properly in STRUST
597 | " b) no firewalls
598 | " check trace file in transaction SMICM
599 | lv_message = 'HTTP Communication Failure'. "#EC NOTEXT
600 | WHEN 2.
601 | lv_message = 'HTTP Invalid State'. "#EC NOTEXT
602 | WHEN 3.
603 | lv_message = 'HTTP Processing failed'. "#EC NOTEXT
604 | WHEN OTHERS.
605 | lv_message = 'Another error occured'. "#EC NOTEXT
606 | ENDCASE.
607 | WRITE:/, lv_message COLOR COL_NEGATIVE.
608 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
609 | RETURN.
610 | ENDIF.
611 |
612 | lr_client->response->get_status( IMPORTING code = lv_code ).
613 |
614 | IF lv_code NE 200.
615 | IF lv_message IS INITIAL.
616 | lv_message = |HTTP Return Code is { lv_code }|.
617 | ENDIF.
618 | MESSAGE lv_message TYPE 'E' DISPLAY LIKE 'I'.
619 | RETURN.
620 | ENDIF.
621 |
622 | CREATE OBJECT archive.
623 |
624 | archive->load(
625 | EXPORTING
626 | zip = lr_client->response->get_data( )
627 | EXCEPTIONS
628 | zip_parse_error = 1
629 | OTHERS = 2 ).
630 |
631 | IF sy-subrc <> 0.
632 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
633 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
634 | RETURN.
635 | ENDIF.
636 |
637 | ENDMETHOD. "get_archive
638 |
639 |
640 | METHOD get_submodule_info.
641 |
642 | DATA: lv_gitmodules TYPE string,
643 | lt_gitmodules TYPE stringtab,
644 | lr_string TYPE REF TO string,
645 | lv_junk1 TYPE string ##needed,
646 | lv_junk2 TYPE string ##needed,
647 | lr_url TYPE REF TO string,
648 | lr_path TYPE REF TO string ##needed,
649 | ls_submodule TYPE submodule_info_type.
650 |
651 | CONSTANTS: lf TYPE x LENGTH 4 VALUE '0A00'.
652 | FIELD-SYMBOLS: TYPE char1.
653 | ASSIGN lf TO CASTING.
654 |
655 | lv_gitmodules = xstring_to_string( iv_submodule_data ).
656 |
657 | SPLIT lv_gitmodules AT INTO TABLE lt_gitmodules.
658 |
659 | LOOP AT lt_gitmodules REFERENCE INTO lr_string.
660 | lr_string->* = cleanup_stringdata( data_in = lr_string->* nogaps = abap_true ).
661 | CHECK lr_string->* CS 'submodule'.
662 | CLEAR ls_submodule.
663 | SPLIT lr_string->* AT '"' INTO lv_junk1 ls_submodule-folder lv_junk2.
664 | READ TABLE lt_gitmodules REFERENCE INTO lr_path INDEX ( sy-tabix + 1 ).
665 | CHECK sy-subrc = 0.
666 | ls_submodule-branch = 'master'. "For submodules we always grab master branch
667 | READ TABLE lt_gitmodules REFERENCE INTO lr_url INDEX ( sy-tabix + 1 ).
668 | CHECK sy-subrc = 0.
669 | SPLIT lr_url->* AT `url = https://github.com/` INTO lv_junk1 ls_submodule-repository.
670 | APPEND ls_submodule TO et_submodule_info.
671 | ENDLOOP.
672 |
673 | ENDMETHOD. "GET_SUBMODULE_INFO
674 |
675 |
676 | METHOD minify.
677 |
678 | CASE file_type.
679 | WHEN 'JS'.
680 | data_out = minify_js( data_in ).
681 | WHEN 'CSS'.
682 | data_out = minify_css( data_in ).
683 | WHEN OTHERS.
684 | ENDCASE.
685 |
686 | IF data_out IS INITIAL. "If minification failed just return unchanged data
687 | data_out = data_in.
688 | ENDIF.
689 |
690 | * Increment counters
691 | ADD 1 TO minify_file_count.
692 | minify_byte_count = minify_byte_count + xstrlen( data_in ) - xstrlen( data_out ).
693 |
694 | ENDMETHOD. "minify
695 |
696 |
697 | METHOD minify_css.
698 |
699 | DATA: lr_client TYPE REF TO if_http_client,
700 | lv_code TYPE i,
701 | lt_ffields TYPE tihttpnvp,
702 | lr_ffield TYPE REF TO ihttpnvp.
703 |
704 | DATA: BEGIN OF json_response,
705 | code TYPE string,
706 | map TYPE string,
707 | END OF json_response.
708 |
709 | cl_http_client=>create_by_url(
710 | EXPORTING
711 | url = 'http://refresh-sf.herokuapp.com/css/' "See http://refresh-sf.com/ for details
712 | ssl_id = 'ANONYM'
713 | IMPORTING
714 | client = lr_client
715 | EXCEPTIONS
716 | argument_not_found = 1
717 | plugin_not_active = 2
718 | internal_error = 3
719 | OTHERS = 4 ).
720 |
721 | IF sy-subrc = 0.
722 | lt_ffields = get_css_minify_params( ).
723 |
724 | APPEND INITIAL LINE TO lt_ffields REFERENCE INTO lr_ffield.
725 | lr_ffield->name = 'code'.
726 | lr_ffield->value = xstring_to_string( data_in ).
727 |
728 | lr_client->request->set_form_fields( lt_ffields ).
729 | lr_client->request->set_method( if_http_request=>co_request_method_post ).
730 |
731 | lr_client->send(
732 | EXCEPTIONS
733 | http_communication_failure = 1
734 | http_invalid_state = 2
735 | http_processing_failed = 3
736 | http_invalid_timeout = 4
737 | OTHERS = 5 ).
738 | IF sy-subrc <> 0.
739 | enable_minify = abap_false.
740 | ELSE.
741 | lr_client->receive(
742 | EXCEPTIONS
743 | http_communication_failure = 1
744 | http_invalid_state = 2
745 | http_processing_failed = 3
746 | OTHERS = 4 ).
747 | IF sy-subrc <> 0.
748 | enable_minify = abap_false.
749 | ELSE.
750 | lr_client->response->get_status( IMPORTING code = lv_code ).
751 | ENDIF.
752 | ENDIF.
753 |
754 | IF lv_code EQ 200.
755 | /ui2/cl_json=>deserialize(
756 | EXPORTING json = lr_client->response->get_cdata( )
757 | pretty_name = /ui2/cl_json=>pretty_mode-camel_case
758 | CHANGING
759 | data = json_response ).
760 | data_out = string_to_xstring( json_response-code ).
761 | ENDIF.
762 | ENDIF.
763 |
764 | ENDMETHOD. "minify
765 |
766 |
767 | METHOD minify_js.
768 |
769 | DATA: lr_client TYPE REF TO if_http_client,
770 | lv_code TYPE i,
771 | lt_ffields TYPE tihttpnvp,
772 | lr_ffield TYPE REF TO ihttpnvp.
773 |
774 | DATA:
775 | BEGIN OF json_response,
776 | code TYPE string,
777 | map TYPE string,
778 | END OF json_response.
779 |
780 | cl_http_client=>create_by_url(
781 | EXPORTING
782 | url = 'http://refresh-sf.herokuapp.com/javascript/' "See http://refresh-sf.com/ for details
783 | ssl_id = 'ANONYM'
784 | IMPORTING
785 | client = lr_client
786 | EXCEPTIONS
787 | argument_not_found = 1
788 | plugin_not_active = 2
789 | internal_error = 3
790 | OTHERS = 4 ).
791 |
792 | IF sy-subrc = 0.
793 | lt_ffields = get_js_minify_params( ).
794 |
795 | APPEND INITIAL LINE TO lt_ffields REFERENCE INTO lr_ffield.
796 | lr_ffield->name = 'code'.
797 | lr_ffield->value = xstring_to_string( data_in ).
798 |
799 | lr_client->request->set_form_fields( lt_ffields ).
800 | lr_client->request->set_method( if_http_request=>co_request_method_post ).
801 |
802 | lr_client->send(
803 | EXCEPTIONS
804 | http_communication_failure = 1
805 | http_invalid_state = 2
806 | http_processing_failed = 3
807 | http_invalid_timeout = 4
808 | OTHERS = 5 ).
809 | IF sy-subrc <> 0.
810 | enable_minify = abap_false.
811 | ELSE.
812 | lr_client->receive(
813 | EXCEPTIONS
814 | http_communication_failure = 1
815 | http_invalid_state = 2
816 | http_processing_failed = 3
817 | OTHERS = 4 ).
818 | IF sy-subrc <> 0.
819 | enable_minify = abap_false.
820 | ELSE.
821 | lr_client->response->get_status( IMPORTING code = lv_code ).
822 | ENDIF.
823 | ENDIF.
824 |
825 | IF lv_code EQ 200.
826 | /ui2/cl_json=>deserialize(
827 | EXPORTING json = lr_client->response->get_cdata( )
828 | pretty_name = /ui2/cl_json=>pretty_mode-camel_case
829 | CHANGING
830 | data = json_response ).
831 | data_out = string_to_xstring( json_response-code ).
832 | ENDIF.
833 | ENDIF.
834 |
835 | ENDMETHOD. "minify
836 |
837 |
838 | METHOD remove_cover_folder.
839 |
840 | DATA: ls_file LIKE LINE OF archive->files,
841 | lv_content TYPE xstring,
842 | lv_dummy TYPE string ##needed.
843 |
844 | CHECK archive IS BOUND.
845 |
846 | IF lines( archive->files ) = 0.
847 | WRITE:/, 'No files in archive'.
848 | RETURN.
849 | ENDIF.
850 |
851 | CREATE OBJECT new_archive.
852 |
853 | LOOP AT archive->files INTO ls_file.
854 | CLEAR lv_content.
855 | archive->get(
856 | EXPORTING
857 | name = ls_file-name
858 | IMPORTING
859 | content = lv_content
860 | EXCEPTIONS
861 | zip_index_error = 1
862 | zip_decompression_error = 2
863 | OTHERS = 3 ).
864 |
865 | IF sy-subrc <> 0.
866 | MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
867 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
868 | RETURN.
869 | ENDIF.
870 |
871 | IF ls_file-name CA '/'.
872 | SPLIT ls_file-name AT '/' INTO lv_dummy ls_file-name.
873 | ELSE.
874 | SPLIT ls_file-name AT '\' INTO lv_dummy ls_file-name.
875 | ENDIF.
876 | IF ls_file-name IS INITIAL.
877 | CONTINUE.
878 | ENDIF.
879 | new_archive->add(
880 | EXPORTING
881 | name = ls_file-name
882 | content = lv_content ).
883 | ENDLOOP.
884 |
885 | ENDMETHOD. "remove_cover_folder
886 |
887 |
888 | METHOD save_archive_file.
889 |
890 | DATA: lv_content TYPE xstring,
891 | fullpath TYPE string,
892 | filename TYPE string,
893 | path TYPE string,
894 | user_action TYPE i,
895 | encoding TYPE abap_encoding,
896 | length TYPE i ##needed.
897 |
898 | DATA: BEGIN OF line_bin,
899 | data(1024) TYPE x,
900 | END OF line_bin.
901 | DATA: data_tab_bin LIKE STANDARD TABLE OF line_bin.
902 |
903 | CHECK test_only = abap_true.
904 |
905 | lv_content = archive->save( ).
906 |
907 | * Binary download table
908 | WHILE xstrlen( lv_content ) > 0.
909 | line_bin-data = lv_content.
910 | APPEND line_bin TO data_tab_bin.
911 | SHIFT lv_content LEFT BY 1024 PLACES IN BYTE MODE.
912 | ENDWHILE.
913 |
914 | * Get filename
915 | CALL METHOD cl_gui_frontend_services=>file_save_dialog
916 | EXPORTING
917 | window_title = 'Download Archive'
918 | with_encoding = 'X'
919 | initial_directory = 'C:\'
920 | CHANGING
921 | filename = filename
922 | path = path
923 | fullpath = fullpath
924 | user_action = user_action
925 | file_encoding = encoding
926 | EXCEPTIONS
927 | cntl_error = 1
928 | error_no_gui = 2
929 | not_supported_by_gui = 3
930 | OTHERS = 4.
931 | IF sy-subrc <> 0.
932 | RETURN.
933 | ENDIF.
934 |
935 | IF user_action <> cl_gui_frontend_services=>action_ok.
936 | RETURN.
937 | ENDIF.
938 |
939 | * Binary download
940 | CALL FUNCTION 'GUI_DOWNLOAD'
941 | EXPORTING
942 | filename = fullpath
943 | filetype = 'BIN'
944 | IMPORTING
945 | filelength = length
946 | TABLES
947 | data_tab = data_tab_bin
948 | EXCEPTIONS
949 | file_write_error = 1
950 | no_batch = 2
951 | gui_refuse_filetransfer = 3
952 | invalid_type = 4
953 | no_authority = 5
954 | unknown_error = 6
955 | header_not_allowed = 7
956 | separator_not_allowed = 8
957 | filesize_not_allowed = 9
958 | header_too_long = 10
959 | dp_error_create = 11
960 | dp_error_send = 12
961 | dp_error_write = 13
962 | unknown_dp_error = 14
963 | access_denied = 15
964 | dp_out_of_memory = 16
965 | disk_full = 17
966 | dp_timeout = 18
967 | file_not_found = 19
968 | dataprovider_exception = 20
969 | control_flush_error = 21
970 | OTHERS = 22 ##FM_SUBRC_OK.
971 |
972 | ENDMETHOD. "save_zip_file
973 |
974 |
975 | METHOD string_to_xstring.
976 |
977 | DATA(lv_conv) = cl_abap_conv_out_ce=>create( ).
978 |
979 | CALL METHOD lv_conv->write
980 | EXPORTING
981 | n = -1
982 | data = in
983 | IMPORTING
984 | len = DATA(lv_length).
985 |
986 |
987 | CALL METHOD lv_conv->get_buffer
988 | RECEIVING
989 | buffer = out.
990 |
991 | ENDMETHOD. "STRING_TO_XSTRING
992 |
993 |
994 | METHOD update_cachebuster.
995 |
996 | DATA: lv_jobnumber TYPE tbtcjob-jobcount,
997 | lv_jobname TYPE tbtcjob-jobname VALUE 'UI5_CACHEBUSTER'.
998 |
999 | CHECK test_only NE abap_true.
1000 |
1001 | CALL FUNCTION 'JOB_OPEN'
1002 | EXPORTING
1003 | jobname = lv_jobname
1004 | IMPORTING
1005 | jobcount = lv_jobnumber
1006 | EXCEPTIONS
1007 | cant_create_job = 1
1008 | invalid_job_data = 2
1009 | jobname_missing = 3
1010 | OTHERS = 4.
1011 |
1012 | CHECK sy-subrc = 0.
1013 |
1014 | SUBMIT /ui5/app_index_calculate "/ui5/update_cachebuster
1015 | VIA JOB lv_jobname NUMBER lv_jobnumber AND RETURN.
1016 |
1017 | CHECK sy-subrc = 0.
1018 |
1019 | CALL FUNCTION 'JOB_CLOSE'
1020 | EXPORTING
1021 | jobcount = lv_jobnumber
1022 | jobname = lv_jobname
1023 | strtimmed = 'X'
1024 | EXCEPTIONS
1025 | cant_start_immediate = 1
1026 | invalid_startdate = 2
1027 | jobname_missing = 3
1028 | job_close_failed = 4
1029 | job_nosteps = 5
1030 | job_notex = 6
1031 | lock_failed = 7
1032 | OTHERS = 8 ##FM_SUBRC_OK.
1033 |
1034 |
1035 | ENDMETHOD.
1036 |
1037 |
1038 | METHOD upload_archive_into_icf.
1039 |
1040 | DATA: lv_zip_file TYPE xstring.
1041 | * Messages
1042 | DATA: lv_success TYPE char1,
1043 | lt_log_messages TYPE string_table,
1044 | lv_message TYPE string,
1045 | lv_msg_id TYPE sy-msgid,
1046 | lv_msg_no TYPE sy-msgno.
1047 |
1048 | CHECK archive->files IS NOT INITIAL.
1049 |
1050 | lv_message = |Archive contains { lines( archive->files ) } folders & files|.
1051 | WRITE:/, lv_message.
1052 | IF minify_file_count > 0.
1053 | lv_message = |{ minify_file_count } files minified - { minify_byte_count } bytes removed|.
1054 | WRITE:/, lv_message.
1055 | ENDIF.
1056 |
1057 | WRITE:/, `Loading archive.....`.
1058 |
1059 | lv_zip_file = archive->save( ).
1060 |
1061 | CALL FUNCTION 'YUI5_REPOSITORY_LOAD_HTTP'
1062 | EXPORTING
1063 | iv_url = ''
1064 | * IV_SAPUI5_APPLICATION_NAME = ''
1065 | * IV_SAPUI5_APPLICATION_DESC = ''
1066 | * IV_PACKAGE = ''
1067 | iv_workbench_request = me->transport
1068 | * IV_EXTERNAL_CODE_PAGE = ''
1069 | * IV_ACCEPT_UNIX_STYLE_EOL = 'X'
1070 | * IV_DELTA_MODE = '-'
1071 | iv_test_mode = me->test_only
1072 | iv_zip_file = lv_zip_file
1073 | IMPORTING
1074 | ev_success = lv_success
1075 | ev_log_messages = lt_log_messages
1076 | ev_msg_id = lv_msg_id
1077 | ev_msg_no = lv_msg_no.
1078 |
1079 | MESSAGE ID lv_msg_id TYPE lv_success NUMBER lv_msg_no INTO lv_message.
1080 | LOOP AT lt_log_messages INTO lv_message.
1081 | WRITE:/, lv_message.
1082 | ENDLOOP.
1083 | CASE lv_success.
1084 | WHEN 'S'.
1085 | WRITE:/, 'Success' COLOR COL_POSITIVE, lv_message COLOR COL_POSITIVE.
1086 | WHEN 'W'.
1087 | WRITE:/, 'Warning' COLOR COL_GROUP, lv_message COLOR COL_GROUP.
1088 | WHEN OTHERS.
1089 | WRITE:/, 'Error' COLOR COL_NEGATIVE, lv_message COLOR COL_NEGATIVE.
1090 | RAISE EXCEPTION TYPE cx_sy_create_data_error "Just any old exception to signal failure
1091 | EXPORTING
1092 | textid = cx_sy_create_data_error=>generic_type
1093 | * previous = previous
1094 | * typename = typename
1095 | .
1096 | ENDCASE.
1097 |
1098 | ENDMETHOD. "load_archive
1099 |
1100 |
1101 | METHOD xstring_to_string.
1102 |
1103 | DATA(conv) = cl_abap_conv_in_ce=>create(
1104 | encoding = 'UTF-8'
1105 | endian = 'L'
1106 | ignore_cerr = 'X'
1107 | replacement = '#'
1108 | input = in
1109 | ).
1110 |
1111 | CALL METHOD conv->read
1112 | IMPORTING
1113 | data = out.
1114 |
1115 | ENDMETHOD. "XSTRING_TO_STRING
1116 | ENDCLASS.
1117 |
--------------------------------------------------------------------------------
/src/yui5_repository_load.fugr.lyui5_repository_loadp01.abap:
--------------------------------------------------------------------------------
1 | *&---------------------------------------------------------------------*
2 | *& Include /UI5/LUI5_REPOSITORY_LOADP01
3 | *&---------------------------------------------------------------------*
4 | ************************************************************************
5 | ************************************************************************
6 | * *
7 | * Local Classes Implementation *
8 | * *
9 | ************************************************************************
10 | ************************************************************************
11 |
12 |
13 | ************************************************************************
14 | * Class LCL_FUNCTION
15 | *
16 | * provides some helper functions.
17 | ************************************************************************
18 | CLASS lcl_function IMPLEMENTATION.
19 |
20 | METHOD max.
21 | DATA: max TYPE i.
22 | max = a.
23 | IF ( b > a ). max = b . ENDIF.
24 | IF ( c > max ). max = c . ENDIF.
25 | IF ( d > max ). max = d . ENDIF.
26 | IF ( e > max ). max = e . ENDIF.
27 | IF ( f > max ). max = f . ENDIF.
28 | rv_max = max.
29 | ENDMETHOD. "max
30 |
31 | METHOD set_return_msg.
32 |
33 | cv_msg_id = '/UI5/UI5_REP_LOAD'.
34 |
35 | * Test mode off
36 | IF iv_test_mode = abap_false.
37 | IF iv_success = status_success.
38 | cv_msg_no = '001'.
39 | ELSEIF iv_success = status_warning.
40 | cv_msg_no = '002'.
41 | ELSEIF iv_success = status_error.
42 | cv_msg_no = '003'.
43 | ENDIF.
44 | ENDIF.
45 |
46 | * Test mode on
47 | IF iv_test_mode = abap_true.
48 | IF iv_success = status_success.
49 | cv_msg_no = '004'.
50 | ELSEIF iv_success = status_warning.
51 | cv_msg_no = '005'.
52 | ELSEIF iv_success = status_error.
53 | cv_msg_no = '006'.
54 | ENDIF.
55 | ENDIF.
56 |
57 | ENDMETHOD. "set_return_msg
58 |
59 | METHOD text_matches_pattern.
60 |
61 | * Initialize
62 | rv_text_matches_pattern = abap_false.
63 |
64 | * Check if string matches a pattern of the list passed on entry
65 | DATA: pattern TYPE string,
66 | regular_expression_check TYPE abap_bool,
67 | match_count TYPE i.
68 | LOOP AT iv_pattern_list INTO pattern.
69 |
70 | * Skip empty lines
71 | IF strlen( pattern ) = 0. CONTINUE. ENDIF.
72 |
73 | * Determine if pattern to be treated as a regular expression or a substring
74 | DATA: first_char TYPE c, last_char TYPE c, last_char_offset TYPE i.
75 | last_char_offset = strlen( pattern ) - 1.
76 | first_char = pattern(1).
77 | last_char = pattern+last_char_offset(1).
78 | DATA: is_regular_expression TYPE abap_bool. is_regular_expression = abap_false.
79 | IF first_char = '^' AND last_char = '$'. is_regular_expression = abap_true. ENDIF.
80 |
81 | * Check
82 | IF is_regular_expression = abap_true.
83 | TRY.
84 | FIND REGEX pattern IN iv_text IGNORING CASE MATCH COUNT match_count.
85 | CATCH cx_root.
86 | ENDTRY.
87 | ELSE.
88 | FIND pattern IN iv_text IGNORING CASE MATCH COUNT match_count.
89 | ENDIF.
90 | IF match_count > 0. rv_text_matches_pattern = abap_true. RETURN. ENDIF.
91 | ENDLOOP.
92 |
93 | ENDMETHOD. "text_matches_pattern
94 |
95 | * Converts a text into an abap_bool expression
96 | METHOD text_to_abap_bool.
97 |
98 | * Initialize
99 | rv_abap_bool = abap_true.
100 | DATA: text TYPE string. text = iv_text.
101 | CONDENSE text. TRANSLATE text TO LOWER CASE.
102 |
103 | * ABAP_FALSE
104 | IF text IS INITIAL. rv_abap_bool = abap_false. RETURN. ENDIF.
105 | IF text = 'false'. rv_abap_bool = abap_false. RETURN. ENDIF. "#EC NOTEXT
106 | IF text = 'no'. rv_abap_bool = abap_false. RETURN. ENDIF. "#EC NOTEXT
107 | IF text = '0'. rv_abap_bool = abap_false. RETURN. ENDIF. "#EC NOTEXT
108 |
109 | * ABAP_TRUE
110 | IF text = 'x'. rv_abap_bool = abap_true. RETURN. ENDIF. "#EC NOTEXT
111 | IF text = 'true'. rv_abap_bool = abap_true. RETURN. ENDIF. "#EC NOTEXT
112 | IF text = 'yes'. rv_abap_bool = abap_false. RETURN. ENDIF. "#EC NOTEXT
113 | IF text = '1'. rv_abap_bool = abap_true. RETURN. ENDIF. "#EC NOTEXT
114 |
115 | * ABAP_UNDEFINED
116 | IF text = 'undefined'. rv_abap_bool = abap_undefined. RETURN. ENDIF. "#EC NOTEXT
117 | IF text = '-'. rv_abap_bool = abap_undefined. RETURN. ENDIF. "#EC NOTEXT
118 | IF text = '?'. rv_abap_bool = abap_undefined. RETURN. ENDIF. "#EC NOTEXT
119 |
120 | ENDMETHOD. "text_to_abap_bool
121 |
122 | * Converts xstring into table of xstrings
123 | METHOD xstring2xtable.
124 |
125 | * Calculate size
126 | IF ev_size IS SUPPLIED.
127 | ev_size = xstrlen( iv_xstring ).
128 | ENDIF.
129 |
130 | * Split xstring into lines
131 | DATA: xline TYPE x255,
132 | xstring TYPE xstring.
133 | FREE ev_xtable.
134 | xstring = iv_xstring.
135 | WHILE xstring IS NOT INITIAL.
136 | xline = xstring.
137 | APPEND xline TO ev_xtable.
138 | SHIFT xstring LEFT BY 255 PLACES IN BYTE MODE.
139 | ENDWHILE.
140 |
141 | * Clean up
142 | CLEAR xstring.
143 |
144 | ENDMETHOD. "xstring2table
145 |
146 |
147 | * Converts unix style line endings (LF) to windows style (CR LF)
148 | METHOD conv_unix_style_line_endings.
149 |
150 | DATA: string TYPE string,
151 | regular_expression TYPE string,
152 | replace_with TYPE string.
153 | string = iv_string.
154 | regular_expression = '\r\n|\n\r|\n|\r'.
155 | replace_with = '\r\n'.
156 | REPLACE ALL OCCURRENCES OF REGEX regular_expression IN string WITH replace_with.
157 |
158 | rv_string = string.
159 |
160 | ENDMETHOD. "conv_unix_style_line_endings
161 |
162 | * Outputs a sstring to a file
163 | METHOD string_to_file.
164 |
165 | * Initialize
166 | rv_success = abap_true.
167 |
168 | *
169 | DATA: file_content_as_xstring TYPE xstring.
170 | TRY.
171 | file_content_as_xstring =
172 | /ui5/cl_ui5_rep_utility=>convert_string_2_xstring( iv_string = iv_file_content iv_code_page = iv_code_page ).
173 | xstring_to_file( iv_file_content = file_content_as_xstring iv_file_path = iv_file_path ).
174 | CATCH cx_root.
175 | rv_success = abap_false.
176 | ENDTRY.
177 |
178 | ENDMETHOD. "string_to_file
179 |
180 | * Outputs an xstring to a file
181 | METHOD xstring_to_file.
182 |
183 | * Initialize
184 | rv_success = abap_true.
185 |
186 | * Prepare binary data for file download
187 | * ... Content of text files is passed in binary form as well
188 | DATA: file_size TYPE int4,
189 | file_content_lines_bin TYPE lcl_function=>x255_table,
190 | file_length TYPE int4.
191 | lcl_function=>xstring2xtable( EXPORTING iv_xstring = iv_file_content
192 | IMPORTING ev_size = file_size
193 | ev_xtable = file_content_lines_bin ).
194 | * Delegate
195 | CALL METHOD cl_gui_frontend_services=>gui_download
196 | EXPORTING
197 | bin_filesize = file_size
198 | filename = iv_file_path
199 | filetype = 'BIN'
200 | IMPORTING
201 | filelength = file_length "virus_scan_profile = '/SCET/GUI_DOWNLOAD'
202 | CHANGING
203 | data_tab = file_content_lines_bin
204 | EXCEPTIONS
205 | file_write_error = 1
206 | no_batch = 2
207 | gui_refuse_filetransfer = 3
208 | invalid_type = 4
209 | no_authority = 5
210 | unknown_error = 6
211 | header_not_allowed = 7
212 | separator_not_allowed = 8
213 | filesize_not_allowed = 9
214 | header_too_long = 10
215 | dp_error_create = 11
216 | dp_error_send = 12
217 | dp_error_write = 13
218 | unknown_dp_error = 14
219 | access_denied = 15
220 | dp_out_of_memory = 16
221 | disk_full = 17
222 | dp_timeout = 18
223 | file_not_found = 19
224 | dataprovider_exception = 20
225 | control_flush_error = 21
226 | not_supported_by_gui = 22
227 | error_no_gui = 23
228 | OTHERS = 24.
229 | IF sy-subrc <> 0.
230 | rv_success = abap_false.
231 | ENDIF.
232 |
233 | ENDMETHOD. "xstring_to_file
234 |
235 | * Calculates md5 hash value for string
236 | * ... returns intial value in case of error
237 | METHOD get_md5_hash_for_string.
238 |
239 | DATA: string_length TYPE i. string_length = strlen( iv_string ).
240 | CALL FUNCTION 'MD5_CALCULATE_HASH_FOR_CHAR'
241 | EXPORTING
242 | data = iv_string
243 | length = string_length
244 | IMPORTING
245 | hash = rv_md5_hash
246 | EXCEPTIONS
247 | no_data = 1
248 | internal_error = 2
249 | OTHERS = 3.
250 | IF sy-subrc > 0.
251 | CLEAR rv_md5_hash.
252 | ENDIF.
253 |
254 | ENDMETHOD. "get_md5_hash_for_string
255 |
256 | * Calculates md5 hash value for string
257 | * ... returns intial value in case of error
258 | METHOD get_hash_for_xstring.
259 |
260 | DATA: hash TYPE hash160.
261 | CALL FUNCTION 'CALCULATE_HASH_FOR_RAW'
262 | EXPORTING
263 | * ALG = 'SHA1'
264 | data = iv_xstring
265 | * LENGTH = 0
266 | IMPORTING
267 | hash = hash
268 | * HASHLEN =
269 | * HASHX = l_hashx
270 | * HASHXLEN =
271 | * EXCEPTIONS
272 | * UNKNOWN_ALG = 1
273 | * PARAM_ERROR = 2
274 | * INTERNAL_ERROR = 3
275 | * OTHERS = 4
276 | .
277 |
278 | rv_hash = hash.
279 |
280 | IF sy-subrc > 0.
281 | CLEAR rv_hash.
282 | ENDIF.
283 |
284 | ENDMETHOD. "get_md5_hash_for_xstring
285 |
286 | ENDCLASS. "lcl_function IMPLEMENTATION
287 |
288 |
289 | ************************************************************************
290 | * Class LCL_OPERATION
291 | *
292 | * represents an upload operation to be performed.
293 | ************************************************************************
294 | CLASS lcl_operation IMPLEMENTATION.
295 |
296 | *****************************************
297 | METHOD create_log_message.
298 | *****************************************
299 |
300 | * Operation
301 | DATA: message TYPE string,
302 | operation_(13) TYPE c.
303 | operation_ = me->operation.
304 | IF me->to_update = abap_false
305 | AND me->operation <> me->ignore_file
306 | AND me->operation <> me->ignore_folder.
307 | operation_ = 'NONE'.
308 | ENDIF.
309 |
310 | CONCATENATE operation_ ' : ' INTO message RESPECTING BLANKS.
311 |
312 | * Path
313 | IF me->operation = lcl_operation=>delete_folder
314 | OR me->operation = lcl_operation=>delete_file.
315 | CONCATENATE message me->relative_path INTO message.
316 | ELSE.
317 | CONCATENATE message me->full_path INTO message.
318 | ENDIF.
319 |
320 | * File type
321 | IF me->operation = lcl_operation=>upload_file.
322 | DATA: text_binary TYPE string.
323 | IF me->object_type = lcl_operation=>object_type_text_file.
324 | text_binary = TEXT-070.
325 | CONCATENATE message ' (' text_binary ')' INTO message RESPECTING BLANKS.
326 | ELSEIF me->object_type = lcl_operation=>object_type_binary_file.
327 | text_binary = TEXT-071.
328 | CONCATENATE message ' (' text_binary ')' INTO message RESPECTING BLANKS.
329 | ENDIF.
330 | ENDIF.
331 | IF me->message IS NOT INITIAL.
332 | CONCATENATE message ' (' me->message ')' INTO message RESPECTING BLANKS.
333 | ENDIF.
334 |
335 | rv_message = message.
336 |
337 | ENDMETHOD. "create_log_message
338 |
339 | *****************************************
340 | METHOD get_file_extension.
341 | *****************************************
342 |
343 | * Initialize
344 | CLEAR rv_file_extension.
345 |
346 | * Return empty string if object behind is a folder
347 | IF object_type = lcl_operation=>object_type_folder. RETURN. ENDIF.
348 |
349 | * Split path
350 | DATA: parts TYPE TABLE OF string,
351 | part TYPE string,
352 | i TYPE int4,
353 | extension TYPE string.
354 | SPLIT me->relative_path AT '/' INTO TABLE parts.
355 | i = lines( parts ).
356 | READ TABLE parts INTO part INDEX i.
357 | * Get file extension
358 | SPLIT part AT '.' INTO TABLE parts.
359 | i = lines( parts ).
360 | IF i > 1.
361 | READ TABLE parts INTO extension INDEX i.
362 | TRANSLATE extension TO UPPER CASE. "#EC TRANSLANG
363 | ENDIF.
364 | * Return
365 | IF extension IS INITIAL. RETURN. ENDIF.
366 | CONCATENATE '.' extension INTO extension.
367 | rv_file_extension = extension.
368 |
369 | ENDMETHOD. "get_file_extension
370 |
371 | *****************************************
372 | METHOD is_binary.
373 | *****************************************
374 |
375 | * Check file type
376 | rv_is_binary = abap_undefined.
377 | IF me->object_type = lcl_operation=>object_type_binary_file.
378 | rv_is_binary = abap_true.
379 | ELSEIF me->object_type = lcl_operation=>object_type_text_file.
380 | rv_is_binary = abap_false.
381 | ENDIF.
382 |
383 | ENDMETHOD. "is_binary
384 |
385 | ENDCLASS. "lcl_operation
386 |
387 | ************************************************************************
388 | * Class LCL_BADI
389 | *
390 | * represents the Business Add-In /UI5/BADI_PREVENT_DELETION
391 | ************************************************************************
392 | CLASS lcl_badi IMPLEMENTATION.
393 |
394 | *****************************************
395 | METHOD constructor.
396 | *****************************************
397 |
398 | * Access business add-in
399 | TRY.
400 |
401 | * Retrieve BAdI implementation
402 | GET BADI me->implementation.
403 | IF me->implementation IS NOT INITIAL.
404 | IF cl_badi_query=>number_of_implementations( me->implementation ) = 0.
405 | CLEAR me->implementation.
406 | ENDIF.
407 | ENDIF.
408 |
409 | * Check if the deletion of any mime object is to be ommited
410 | me->never_delete_mime_resources = abap_false.
411 | IF me->implementation IS NOT INITIAL.
412 | CALL BADI me->implementation->disable_deletion_for_all
413 | EXPORTING
414 | iv_caller = '/UI5/UI5_REPOSITORY_LOAD_HTTP'
415 | RECEIVING
416 | rv_prevent_deletion = me->never_delete_mime_resources.
417 | ENDIF.
418 |
419 | * Remember
420 | me->application_name = iv_sapui5_application_name.
421 | me->workbench_request = iv_workbench_request.
422 | me->test_mode = iv_test_mode.
423 |
424 | CATCH cx_badi_not_implemented.
425 |
426 | CLEAR me->implementation.
427 |
428 | ENDTRY.
429 |
430 | ENDMETHOD. "constructor
431 |
432 | *****************************************
433 | METHOD disable_deletion_for.
434 | *****************************************
435 |
436 | * Initialize
437 | rv_result = abap_false.
438 |
439 | * Return if no operation given
440 | * or if there's no BAdI
441 | IF iv_operation IS INITIAL
442 | OR me->implementation IS INITIAL.
443 | EXIT.
444 | ENDIF.
445 |
446 | * Return if text file or no delete operation
447 | * ... Note: The BAdI may hinder deletion if the file type is unknown
448 | IF iv_operation->object_type = lcl_operation=>object_type_text_file
449 | OR iv_operation->operation <> lcl_operation=>delete_file.
450 | EXIT.
451 | ENDIF.
452 |
453 | * Disable this deletion in case BAdI disables all
454 | IF me->never_delete_mime_resources = abap_true.
455 | rv_result = abap_true.
456 | EXIT.
457 | ENDIF.
458 |
459 | * Build path expression
460 | DATA: path TYPE string.
461 | CONCATENATE me->application_name '/' iv_operation->full_path INTO path.
462 |
463 | * Delegate to BAdI
464 | DATA: _error_occured TYPE abap_bool,
465 | _error_text TYPE string.
466 | _error_occured = abap_false. _error_text = ''.
467 | CALL BADI me->implementation->disable_deletion_for_one
468 | EXPORTING
469 | iv_url = path
470 | iv_rename = abap_undefined
471 | iv_request = me->workbench_request
472 | iv_test = me->test_mode
473 | iv_caller = '/UI5/CL_UI5_UPLOAD_TO_MIME'
474 | IMPORTING
475 | ev_prevent_deletion = rv_result
476 | ev_error = _error_occured
477 | ev_text = _error_text.
478 |
479 | * Remember last error
480 | IF _error_occured = abap_true.
481 | me->error_occurred = abap_true.
482 | me->error_text = _error_text.
483 | ENDIF.
484 |
485 | ENDMETHOD. "disable_deletion_for
486 |
487 | ENDCLASS. "lcl_operation IMPLEMENTATION
488 |
489 |
490 | ************************************************************************
491 | * Class LCL_SAPUI5_ZIP_ARCHIVE
492 | *
493 | * represents a zip file containing a SAPUI5 application
494 | *
495 | * Remarks:
496 | * - Access to log messages is passed as reference to constructor:
497 | * 1) Changing and table parameters are not allowed here;
498 | * 2) Using a field symbol as an input parameter does not work either:
499 | * Write operation is not supported then.
500 | *
501 | ************************************************************************
502 | CLASS lcl_sapui5_zip_archive IMPLEMENTATION.
503 |
504 | *****************************************
505 | METHOD constructor.
506 | *****************************************
507 |
508 | * Initialize
509 | me->ok = abap_true.
510 | CLEAR me->error_message.
511 |
512 | * Remember
513 | me->url = iv_url.
514 | me->log_messages_ref = ir_log_messages.
515 |
516 | IF iv_zip_file IS NOT SUPPLIED.
517 | * Access zip file via http
518 |
519 | * ... Confirm Url
520 | cl_http_client=>create_by_url( EXPORTING url = me->url
521 | IMPORTING client = me->http_client
522 | EXCEPTIONS argument_not_found = 1
523 | plugin_not_active = 2
524 | internal_error = 3
525 | OTHERS = 4 ).
526 | IF sy-subrc <> 0.
527 | me->ok = abap_false. me->error_message = TEXT-011.
528 | REPLACE '%' IN me->error_message WITH me->url.
529 | APPEND me->error_message TO log_messages_ref->*.
530 | EXIT.
531 | ELSE.
532 | DATA: message TYPE string.
533 | message = TEXT-012. APPEND message TO me->log_messages_ref->*.
534 | CONCATENATE '. ' iv_url INTO message RESPECTING BLANKS.
535 | APPEND message TO log_messages_ref->*.
536 | ENDIF.
537 |
538 | * ... Grep binary content of archive
539 | DATA: return_code TYPE sysubrc.
540 | http_client->send( EXCEPTIONS OTHERS = 1 ).
541 | http_client->receive( EXCEPTIONS OTHERS = 1 ).
542 |
543 | http_client->get_last_error(
544 | IMPORTING
545 | code = return_code
546 | message = message
547 | ).
548 | IF return_code IS NOT INITIAL.
549 | me->ok = abap_false. me->error_message = TEXT-011.
550 | REPLACE '%' IN me->error_message WITH me->url.
551 | APPEND me->error_message TO me->log_messages_ref->*.
552 | EXIT.
553 | ENDIF.
554 |
555 | DATA: xstring TYPE xstring.
556 | xstring = http_client->response->get_data( ).
557 |
558 | ELSE.
559 | xstring = iv_zip_file.
560 | ENDIF.
561 |
562 | * ... Initialize zip access
563 | CREATE OBJECT zip_archive.
564 | zip_archive->load( EXPORTING zip = xstring
565 | EXCEPTIONS OTHERS = 1 ).
566 | * Indicate if archive is empty or http status is not 200
567 | IF sy-subrc IS NOT INITIAL OR zip_archive->files[] IS INITIAL.
568 |
569 | me->ok = abap_false. me->error_message = TEXT-013.
570 | APPEND me->error_message TO me->log_messages_ref->*.
571 |
572 | DATA: http_status_code_response TYPE i, http_status_code_response_ TYPE string, http_status_text_response TYPE string.
573 | http_client->response->get_status( IMPORTING code = http_status_code_response reason = http_status_text_response ).
574 | IF ( http_status_code_response <> 200 ).
575 | me->ok = abap_false. me->error_message = TEXT-109.
576 | http_status_code_response_ = http_status_code_response. CONDENSE http_status_code_response_ NO-GAPS.
577 | REPLACE '%1' IN me->error_message WITH http_status_code_response_.
578 | REPLACE '%2' IN me->error_message WITH http_status_text_response.
579 | APPEND me->error_message TO me->log_messages_ref->*.
580 | ENDIF.
581 |
582 | EXIT.
583 |
584 | ELSE.
585 |
586 | * Calculate number of files in archive
587 | " describe table zip_archive->files[] lines number -> Does not work as files[] is inconsistent
588 | DATA: count TYPE i, number_of_files TYPE string, file LIKE LINE OF zip_archive->files[].
589 | CLEAR count.
590 | LOOP AT zip_archive->files[] INTO file.
591 | DATA: last_char_offset TYPE i, last_char TYPE c.
592 | last_char_offset = strlen( file-name ) - 1.
593 | last_char = file-name+last_char_offset(1).
594 | IF last_char NE '/'. count = count + 1. ENDIF.
595 | ENDLOOP.
596 | IF count = 0.
597 | me->ok = abap_false. me->error_message = TEXT-013.
598 | APPEND me->error_message TO me->log_messages_ref->*.
599 | EXIT.
600 | ENDIF.
601 |
602 | * Indicate
603 | number_of_files = count. CONDENSE number_of_files NO-GAPS.
604 | message = TEXT-014. ". % Files and Folders found in Archive.
605 | REPLACE '%' IN message WITH number_of_files.
606 | APPEND message TO log_messages_ref->*.
607 | APPEND '.' TO log_messages_ref->*. "Empty line
608 |
609 | ENDIF.
610 |
611 | * Header for Parameter section in log
612 | APPEND TEXT-019 TO log_messages_ref->*. "* Parameters *
613 |
614 |
615 | * Determine text and binary file patterns
616 | * ... encoding is expected to be UTF-8 compatible
617 | DATA: code_page_utf8 TYPE string VALUE 'UTF-8'.
618 | me->determine_text_file_patterns( code_page_utf8 ).
619 | me->determine_binary_file_patterns( code_page_utf8 ).
620 | me->determine_upload_ignores( code_page_utf8 ).
621 |
622 | * Determine upload parameters from file
623 | * ... encoding is expected to be UTF-8 compatible
624 | me->determine_upload_parameters( code_page_utf8 ).
625 |
626 | ENDMETHOD. "constructor
627 |
628 | *****************************************
629 | METHOD is_ok.
630 | *****************************************
631 | rv_is_ok = me->ok.
632 | ENDMETHOD. "is_ok
633 |
634 |
635 | *****************************************
636 | METHOD determine_upload_operations.
637 | *****************************************
638 | *
639 | * This method determines the operations needed to upload
640 | * the archive content into a the SAPUI5 ABAP repository
641 | * not yet containing the SAPUI5 application.
642 |
643 | * Initialize
644 | CLEAR cv_load_operations.
645 |
646 | * Access files in archive
647 | TYPES: BEGIN OF t_file,
648 | name TYPE string,
649 | date TYPE d,
650 | time TYPE t,
651 | size TYPE i,
652 | END OF t_file .
653 | TYPES: t_files TYPE TABLE OF t_file .
654 | DATA: files TYPE t_files.
655 | files = me->zip_archive->files[].
656 | SORT files BY name AS TEXT.
657 |
658 | * For each file or folder in archive
659 | DATA: load_operation TYPE REF TO lcl_operation,
660 | archive_entry LIKE LINE OF me->zip_archive->files[],
661 | message TYPE string,
662 | folders_created TYPE string.
663 | LOOP AT files INTO archive_entry.
664 |
665 | * Create load operation
666 | CREATE OBJECT load_operation.
667 |
668 | load_operation->full_path = archive_entry-name.
669 | load_operation->relative_path = load_operation->full_path.
670 |
671 | "if load_operation->full_path cs '.meta/i18n/'. break wegmann. endif.
672 |
673 | * Determine name of file or folder
674 | DATA: path_components TYPE string_table.
675 | SPLIT load_operation->full_path AT '/' INTO TABLE path_components.
676 | DATA: max_index TYPE i.
677 | DESCRIBE TABLE path_components LINES max_index.
678 | READ TABLE path_components INDEX max_index INTO load_operation->object_name.
679 |
680 | * Folder is to be created
681 | FIND REGEX '^.*/$' IN archive_entry-name.
682 | IF sy-subrc = 0.
683 |
684 | * Initialize
685 | load_operation->to_update = abap_true.
686 |
687 | * Set operation and object type
688 | load_operation->operation = lcl_operation=>create_folder.
689 | load_operation->object_type = lcl_operation=>object_type_folder.
690 |
691 | * Decide if folder is to be ignored
692 | DATA: is_folder_to_be_ignored TYPE abap_bool.
693 | is_folder_to_be_ignored = me->is_file_to_be_ignored( load_operation->full_path ).
694 | IF is_folder_to_be_ignored = abap_true.
695 | load_operation->operation = lcl_operation=>ignore_folder.
696 | ENDIF.
697 |
698 | * Build relative path
699 | DATA: first_char TYPE c, last_char TYPE c, last_char_offset TYPE i.
700 | last_char_offset = strlen( load_operation->relative_path ) - 1.
701 | last_char = load_operation->relative_path+last_char_offset(1).
702 | IF last_char EQ '/'.
703 | REPLACE SECTION OFFSET last_char_offset OF load_operation->relative_path WITH ''.
704 | ENDIF.
705 |
706 | * Register folder
707 | CONCATENATE folders_created load_operation->full_path '; ' INTO folders_created RESPECTING BLANKS.
708 |
709 | * File is to be uploaded
710 | ELSE.
711 |
712 | * Initialize
713 | load_operation->to_update = abap_true.
714 |
715 | * Trigger operations to create folders for file
716 | * ... as me->zip_archive->files[] appears to be incomplete
717 | DATA: path TYPE string.
718 | path = load_operation->full_path.
719 | REPLACE load_operation->object_name IN path WITH ''.
720 | create_folders_for_path( EXPORTING iv_path = path
721 | CHANGING cv_folders_created = folders_created
722 | cv_load_operations = cv_load_operations ).
723 |
724 | * Set operation
725 | load_operation->operation = lcl_operation=>upload_file.
726 |
727 | * Check if entry is to be ignored
728 | DATA: is_file_to_be_ignored TYPE abap_bool.
729 | is_file_to_be_ignored = me->is_file_to_be_ignored( load_operation->full_path ).
730 | IF is_file_to_be_ignored = abap_true.
731 | load_operation->operation = lcl_operation=>ignore_file.
732 | ENDIF.
733 |
734 | * Check if binary or text file
735 | load_operation->object_type = lcl_operation=>object_type_file.
736 | IF me->is_text_file( load_operation->full_path ) = abap_true.
737 | load_operation->object_type = lcl_operation=>object_type_text_file.
738 | load_operation->code_page = iv_code_page.
739 | ENDIF.
740 | IF me->is_binary_file( load_operation->full_path ) = abap_true.
741 | load_operation->object_type = lcl_operation=>object_type_binary_file.
742 | CLEAR load_operation->code_page.
743 | ENDIF.
744 |
745 | ENDIF.
746 |
747 | * ... Try to determine from mime type if not clear from previous check
748 | IF load_operation->object_type = lcl_operation=>object_type_file.
749 | DATA: extension TYPE string,
750 | ext TYPE char20,
751 | mimetype TYPE mimetypes-type.
752 | extension = load_operation->get_file_extension( ). ext = extension.
753 | CALL FUNCTION 'SDOK_MIMETYPE_GET'
754 | EXPORTING
755 | extension = ext
756 | IMPORTING
757 | mimetype = mimetype.
758 | IF mimetype = 'image'.
759 | load_operation->object_type = lcl_operation=>object_type_binary_file.
760 | ELSE.
761 | load_operation->operation = lcl_operation=>ignore_file.
762 | load_operation->message = TEXT-072. "File type unknown
763 | cv_success = status_warning.
764 | ENDIF.
765 | ENDIF.
766 |
767 | * Read file and for text files check if end of line line markers are CR+LF (Windows)
768 | IF load_operation->object_type = lcl_operation=>object_type_text_file
769 | OR load_operation->object_type = lcl_operation=>object_type_binary_file.
770 |
771 | TRY.
772 | DATA: file_content TYPE xstring,
773 | file_content_as_string TYPE string.
774 | file_content = me->read_file( iv_path = archive_entry-name ).
775 | file_content_as_string =
776 | /ui5/cl_ui5_rep_utility=>convert_xstring_2_string( iv_xstring = file_content
777 | iv_code_page = iv_code_page ).
778 | load_operation->eol_conversion = abap_false.
779 |
780 | DATA: eol_conversion_needed TYPE abap_bool. eol_conversion_needed = abap_false.
781 | IF load_operation->object_type = lcl_operation=>object_type_text_file.
782 | DATA: file_content_as_string_windows TYPE string.
783 | file_content_as_string_windows =
784 | lcl_function=>conv_unix_style_line_endings( iv_string = file_content_as_string ).
785 |
786 | ***** Debug conversion of Unix style files *****
787 | IF lcl_ui5_repository=>debug_conversions_for_file IS NOT INITIAL
788 | AND load_operation->object_name EQ lcl_ui5_repository=>debug_conversions_for_file.
789 |
790 | DATA: file_path TYPE string.
791 | CONCATENATE lcl_ui5_repository=>debug_conversions_for_file
792 | '.upload' INTO file_path. "#EC NOTEXT
793 | lcl_function=>xstring_to_file( iv_file_content = file_content
794 | iv_file_path = file_path ).
795 | CONCATENATE lcl_ui5_repository=>debug_conversions_for_file
796 | '.upload.as_string' INTO file_path. "#EC NOTEXT
797 | lcl_function=>string_to_file( iv_file_content = file_content_as_string
798 | iv_code_page = iv_code_page
799 | iv_file_path = file_path ).
800 | CONCATENATE lcl_ui5_repository=>debug_conversions_for_file
801 | '.upload.as_string_windows' INTO file_path. "#EC NOTEXT
802 | lcl_function=>string_to_file( iv_file_content = file_content_as_string_windows
803 | iv_code_page = iv_code_page
804 | iv_file_path = file_path ).
805 | ENDIF.
806 | ************************************************
807 |
808 | IF file_content_as_string = file_content_as_string_windows.
809 | eol_conversion_needed = abap_false.
810 | load_operation->eol_conversion = abap_false.
811 | ELSE.
812 | eol_conversion_needed = abap_true.
813 | IF iv_accept_unix_style_eol = abap_true.
814 | load_operation->eol_conversion = abap_true.
815 | ELSE.
816 | "message = text-056. "* Warning: Text file % has unix style line delimeter. It is not uploaded *
817 | "replace '%' in message with archive_entry-name.
818 | "append message to me->log_messages_ref->*.
819 | load_operation->operation = lcl_operation=>ignore_file.
820 | load_operation->message = TEXT-076. "Warning: Unix style text file
821 | load_operation->to_update = abap_false.
822 | load_operation->eol_conversion = abap_false.
823 | cv_success = status_warning.
824 | ENDIF.
825 | ENDIF.
826 | ENDIF.
827 |
828 | * Calculate md5 hash for file to compare with that in SAPUI5 ABAP repository
829 | * ... Needed only in delta mode
830 | IF iv_delta_mode EQ abap_true.
831 | TRY.
832 | IF load_operation->eol_conversion = abap_true.
833 | load_operation->hash_value = lcl_function=>get_md5_hash_for_string( file_content_as_string_windows ).
834 | ELSE.
835 | load_operation->hash_value = lcl_function=>get_md5_hash_for_string( file_content_as_string ).
836 | ENDIF.
837 | load_operation->code_page = iv_code_page.
838 | CATCH /ui5/cx_ui5_rep_dt.
839 | message = TEXT-051. "* Warning: Unable to determine MD5 hash for file % *
840 | REPLACE '%' IN message WITH load_operation->full_path .
841 | APPEND message TO me->log_messages_ref->*.
842 | cv_success = status_warning.
843 | ENDTRY.
844 | ENDIF.
845 |
846 | CATCH /ui5/cx_ui5_rep_dt.
847 | message = TEXT-050. "* Warning: Content of file % could not be read *
848 | REPLACE '%' IN message WITH load_operation->full_path .
849 | APPEND message TO me->log_messages_ref->*.
850 | cv_success = status_warning.
851 |
852 | ENDTRY.
853 |
854 | ENDIF.
855 |
856 |
857 | * Register operation
858 | APPEND load_operation TO cv_load_operations.
859 |
860 | ENDLOOP.
861 |
862 | ENDMETHOD. "determine_upload_operations
863 |
864 | *****************************************
865 | METHOD read_file.
866 | *****************************************
867 |
868 | * Return if no path given
869 | IF iv_path IS INITIAL. RETURN. ENDIF.
870 |
871 | * Find file in archive
872 | DATA: index TYPE i.
873 | READ TABLE me->zip_archive->files TRANSPORTING NO FIELDS
874 | WITH KEY name = iv_path.
875 | IF sy-subrc <> 0. RETURN. ENDIF.
876 | index = sy-tabix.
877 |
878 | me->zip_archive->get( EXPORTING index = index IMPORTING content = rv_content ).
879 |
880 | ENDMETHOD. "read_file
881 |
882 | *****************************************
883 | METHOD read_file_to_table.
884 | *****************************************
885 | * Read as binary and convert to text
886 | DATA: file_content TYPE xstring,
887 | file_content_as_string TYPE string,
888 | lines TYPE string_table.
889 | TRY.
890 | file_content = me->read_file( iv_path = iv_path ).
891 | file_content_as_string =
892 | /ui5/cl_ui5_rep_utility=>convert_xstring_2_string( iv_xstring = file_content
893 | iv_code_page = iv_code_page ).
894 | file_content_as_string =
895 | lcl_function=>conv_unix_style_line_endings( iv_string = file_content_as_string ).
896 | lines = /ui5/cl_ui5_rep_utility=>code_string_2_code_tab( file_content_as_string ).
897 | CATCH /ui5/cx_ui5_rep_dt.
898 | ENDTRY.
899 |
900 | * Prepare response
901 | rt_lines = lines.
902 |
903 | ENDMETHOD. "read_file_to_table
904 |
905 |
906 | *****************************************
907 | METHOD get_upload_parameter.
908 | *****************************************
909 |
910 | * Return if no parameter given
911 | IF iv_key IS INITIAL. RETURN. ENDIF.
912 |
913 | * Find paramenter
914 | DATA: index TYPE i,
915 | upload_parameter TYPE slin_key_value.
916 |
917 | READ TABLE me->upload_parameters INTO upload_parameter
918 | WITH KEY key = iv_key.
919 | IF sy-subrc <> 0.
920 | rv_value = iv_return_if_not_specified. RETURN.
921 | ENDIF.
922 | rv_value = upload_parameter-value.
923 |
924 | ENDMETHOD. "get_upload_paramenter
925 |
926 |
927 | *****************************************
928 | METHOD add_default_bin_file_patterns.
929 | *****************************************
930 |
931 | * ... Add default binary patterns
932 | DATA: binary_file_pattern TYPE string.
933 | binary_file_pattern = '.zip'. APPEND binary_file_pattern TO cv_file_patterns.
934 | binary_file_pattern = '.war'. APPEND binary_file_pattern TO cv_file_patterns.
935 | binary_file_pattern = '.xpi'. APPEND binary_file_pattern TO cv_file_patterns.
936 | binary_file_pattern = '.jpg'. APPEND binary_file_pattern TO cv_file_patterns.
937 | binary_file_pattern = '.gif'. APPEND binary_file_pattern TO cv_file_patterns.
938 | binary_file_pattern = '.png'. APPEND binary_file_pattern TO cv_file_patterns.
939 | binary_file_pattern = '.ico'. APPEND binary_file_pattern TO cv_file_patterns.
940 | binary_file_pattern = '^.*\.class$'. APPEND binary_file_pattern TO cv_file_patterns.
941 |
942 | ENDMETHOD. "add_default_bin_file_patterns
943 |
944 |
945 | *****************************************
946 | METHOD add_default_ignore_patterns.
947 | *****************************************
948 |
949 | * ... Add default binary patterns
950 | DATA: ignore_file_pattern TYPE string.
951 | ignore_file_pattern = '.git'. APPEND ignore_file_pattern TO cv_file_patterns.
952 | ignore_file_pattern = '^.*[/|\\]build([/|\\].*)?$'.
953 | APPEND ignore_file_pattern TO cv_file_patterns.
954 |
955 | ENDMETHOD. "add_default_ignore_patterns
956 |
957 |
958 | *****************************************
959 | METHOD add_import_upload_parameters.
960 | *****************************************
961 | * TODO:check if needed or for better solution
962 | * ... Add import parameter
963 | DATA: import_parameter TYPE slin_key_value.
964 |
965 | " import_parameter-key = 'SAPUI5ApplicationName'.
966 | " import_parameter-value = IV_SAPUI5_REPOSITORY.
967 | " append import_parameter to cv_file_patterns.
968 |
969 | " import_parameter-key = 'TransportRequest'.
970 | " import_parameter-value = IV_WORKBENCH_REQUEST.
971 | " append import_parameter to cv_file_patterns.
972 |
973 | ENDMETHOD. "add_import_upload_parameters
974 |
975 |
976 | *****************************************
977 | METHOD add_default_text_file_patterns.
978 | *****************************************
979 |
980 | * Add default text file patterns
981 | DATA: text_file_pattern TYPE string.
982 | text_file_pattern = '.txt'. APPEND text_file_pattern TO cv_file_patterns.
983 | text_file_pattern = '.html'. APPEND text_file_pattern TO cv_file_patterns.
984 | text_file_pattern = '.js'. APPEND text_file_pattern TO cv_file_patterns.
985 | text_file_pattern = '.json'. APPEND text_file_pattern TO cv_file_patterns.
986 | text_file_pattern = '.less'. APPEND text_file_pattern TO cv_file_patterns.
987 | text_file_pattern = '.css'. APPEND text_file_pattern TO cv_file_patterns.
988 | text_file_pattern = '.htm'. APPEND text_file_pattern TO cv_file_patterns.
989 | text_file_pattern = '.xml'. APPEND text_file_pattern TO cv_file_patterns.
990 | text_file_pattern = 'manifest.mf'. APPEND text_file_pattern TO cv_file_patterns.
991 | text_file_pattern = '.classpath'. APPEND text_file_pattern TO cv_file_patterns.
992 | text_file_pattern = '.properties'. APPEND text_file_pattern TO cv_file_patterns.
993 | text_file_pattern = '.project'. APPEND text_file_pattern TO cv_file_patterns.
994 | text_file_pattern = '.settings/'. APPEND text_file_pattern TO cv_file_patterns.
995 | text_file_pattern = '^.*\.control$'. APPEND text_file_pattern TO cv_file_patterns.
996 | text_file_pattern = '^.*\.json$'. APPEND text_file_pattern TO cv_file_patterns.
997 | text_file_pattern = '^.*\.less$'. APPEND text_file_pattern TO cv_file_patterns.
998 | text_file_pattern = '^.*\.library$'. APPEND text_file_pattern TO cv_file_patterns.
999 | text_file_pattern = '^.*\.theming$'. APPEND text_file_pattern TO cv_file_patterns.
1000 | text_file_pattern = '.Ui5RepositoryAppSetup'. APPEND text_file_pattern TO cv_file_patterns.
1001 | text_file_pattern = '.Ui5RepositoryIgnore'. APPEND text_file_pattern TO cv_file_patterns.
1002 | text_file_pattern = '.Ui5RepositoryBinaryFiles'. APPEND text_file_pattern TO cv_file_patterns.
1003 | text_file_pattern = '.Ui5RepositoryTextFiles'. APPEND text_file_pattern TO cv_file_patterns.
1004 | text_file_pattern = '.Ui5RepositoryUploadParameters'. APPEND text_file_pattern TO cv_file_patterns.
1005 |
1006 | ENDMETHOD. "add_default_text_file_patterns
1007 |
1008 | *****************************************
1009 | METHOD create_folders_for_path.
1010 | *****************************************
1011 |
1012 | * Adds operations to create folders for a path given as input
1013 | * once
1014 |
1015 | * Check inputs
1016 | IF iv_path IS INITIAL. RETURN. ENDIF.
1017 |
1018 | * Return if already done
1019 | DATA: folder TYPE string.
1020 | CONCATENATE iv_path '; ' INTO folder RESPECTING BLANKS.
1021 | IF cv_folders_created CS folder. RETURN. ENDIF.
1022 |
1023 | * Parse path expression
1024 | DATA: path_components TYPE string_table,
1025 | max_index TYPE i.
1026 | SPLIT iv_path AT '/' INTO TABLE path_components.
1027 | DESCRIBE TABLE path_components LINES max_index.
1028 |
1029 | * Create parent folder
1030 | IF max_index > 1.
1031 | DATA: parent_folder TYPE string,
1032 | path_component TYPE string.
1033 | CLEAR parent_folder.
1034 | LOOP AT path_components INTO path_component.
1035 | IF sy-tabix = max_index. CLEAR path_component. ENDIF.
1036 | IF path_component IS NOT INITIAL.
1037 | CONCATENATE parent_folder path_component '/' INTO parent_folder RESPECTING BLANKS.
1038 | ENDIF.
1039 | ENDLOOP.
1040 | create_folders_for_path( EXPORTING iv_path = parent_folder
1041 | CHANGING cv_folders_created = cv_folders_created
1042 | cv_load_operations = cv_load_operations ).
1043 | ENDIF.
1044 |
1045 | * Prepare operation to create folder
1046 | DATA: load_operation_ TYPE REF TO lcl_operation.
1047 | CREATE OBJECT load_operation_.
1048 |
1049 | * ... Determine name of folder
1050 | READ TABLE path_components INDEX max_index INTO load_operation_->object_name.
1051 | load_operation_->full_path = iv_path.
1052 | load_operation_->relative_path = iv_path.
1053 | load_operation_->to_update = abap_true.
1054 |
1055 | * ... Set operation and object type
1056 | load_operation_->operation = lcl_operation=>create_folder.
1057 | load_operation_->object_type = lcl_operation=>object_type_folder.
1058 |
1059 | * ... Decide if folder is to be ignored
1060 | DATA: is_folder_to_be_ignored TYPE abap_bool.
1061 | is_folder_to_be_ignored = me->is_file_to_be_ignored( load_operation_->full_path ).
1062 | IF is_folder_to_be_ignored = abap_true.
1063 | load_operation_->operation = lcl_operation=>ignore_folder.
1064 | ENDIF.
1065 |
1066 | * ... Build relative path
1067 | DATA: last_char_offset TYPE i,
1068 | last_char TYPE c.
1069 | last_char_offset = strlen( load_operation_->relative_path ) - 1.
1070 | last_char = load_operation_->relative_path+last_char_offset(1).
1071 | IF last_char EQ '/'.
1072 | REPLACE SECTION OFFSET last_char_offset OF load_operation_->relative_path WITH ''.
1073 | ENDIF.
1074 |
1075 | * ... Register operation if needed
1076 | CONCATENATE load_operation_->full_path '; ' INTO folder RESPECTING BLANKS.
1077 | IF cv_folders_created NS folder.
1078 | APPEND load_operation_ TO cv_load_operations.
1079 | CONCATENATE cv_folders_created folder INTO cv_folders_created RESPECTING BLANKS.
1080 | ENDIF.
1081 |
1082 | ENDMETHOD. "create_folder_operations
1083 |
1084 | *****************************************
1085 | METHOD determine_binary_file_patterns.
1086 | *****************************************
1087 |
1088 | * Build list of patterns identifying binary files
1089 |
1090 | * ... Standard text file patterns
1091 | me->add_default_bin_file_patterns( CHANGING cv_file_patterns = me->binary_file_patterns ).
1092 |
1093 | * ... Patterns from '.Ui5RepositoryBinaryFiles' file
1094 | DATA: line TYPE string,
1095 | lines TYPE string_table.
1096 | lines = me->read_file_to_table( iv_path = '.Ui5RepositoryBinaryFiles' iv_code_page = iv_code_page ).
1097 | LOOP AT lines INTO line.
1098 | APPEND line TO me->binary_file_patterns.
1099 | ENDLOOP.
1100 |
1101 | * ... Message
1102 | IF lines IS INITIAL.
1103 | APPEND TEXT-022 TO me->log_messages_ref->*. "* Binary files have been identified from standard settings *
1104 | ELSE.
1105 | APPEND TEXT-023 TO me->log_messages_ref->*. "* File '.Ui5RepositoryBinaryFiles' has been considered to identify binary files *
1106 | ENDIF.
1107 |
1108 | ENDMETHOD. "determine_binary_file_patterns
1109 |
1110 |
1111 | *****************************************
1112 | METHOD determine_text_file_patterns.
1113 | *****************************************
1114 |
1115 | * Build list of patterns identifying text files
1116 |
1117 | * ... Standard text file patterns
1118 | me->add_default_text_file_patterns( CHANGING cv_file_patterns = me->text_file_patterns ).
1119 |
1120 | * ... Patterns from '.Ui5RepositoryTextFiles' file
1121 | DATA: line TYPE string,
1122 | lines TYPE string_table.
1123 | lines = me->read_file_to_table( iv_path = '.Ui5RepositoryTextFiles' iv_code_page = iv_code_page ).
1124 | LOOP AT lines INTO line.
1125 | APPEND line TO me->text_file_patterns.
1126 | ENDLOOP.
1127 |
1128 | * ... Message
1129 | IF lines IS INITIAL.
1130 | APPEND TEXT-020 TO me->log_messages_ref->*.
1131 | ELSE.
1132 | APPEND TEXT-021 TO me->log_messages_ref->*.
1133 | ENDIF.
1134 |
1135 | ENDMETHOD. "determine_text_file_patterns
1136 |
1137 | *****************************************
1138 | METHOD determine_upload_ignores.
1139 | *****************************************
1140 |
1141 | * Determines patterns for files to be ignored during the upload of a UI5 application
1142 | *
1143 | * In case a .Ui5RepositoryIgnore file is found in the directory of the UI5 application
1144 | * its content is used to decide if a file is considered in the upload operation.
1145 | *
1146 | * Example content:
1147 | *
1148 | * .c#
1149 | * ^.*\.ttf$
1150 | * ^.*[/|\\]build([/|\\].*)?$
1151 | *
1152 | * In this case all files which contain the sub expression ".c#" in their full path
1153 | * string are ignored by the upload operation. Furthermore files with the extension
1154 | * ".ttf" are ignored as well. In this example "^.*\.ttf$" is detected as a regular
1155 | * expression because it starts with a "^" and ends with a "$".
1156 | * Finally the build directory and everything below gets ignored.
1157 | *
1158 | * If a .Ui5RepIgnore file is not found a standard list of ignore patterns is used:
1159 | * So there's no need for a user to think about this topic in a simple case.
1160 | *
1161 | * Remark: In Eclipse the ignore files are specified by a team provider setting.
1162 |
1163 | * Build list of files to ignore during upload
1164 |
1165 | * ... Either patterns from '.Ui5RepositoryIgnore' file
1166 | me->upload_ignores = me->read_file_to_table( iv_path = '.Ui5RepositoryIgnore' iv_code_page = iv_code_page ).
1167 |
1168 | * ... Or standard ignore file patterns
1169 | IF me->upload_ignores IS INITIAL.
1170 | me->add_default_ignore_patterns( CHANGING cv_file_patterns = me->upload_ignores ).
1171 | APPEND TEXT-024 TO me->log_messages_ref->*.
1172 | ELSE.
1173 | APPEND TEXT-025 TO me->log_messages_ref->*.
1174 | ENDIF.
1175 |
1176 | ENDMETHOD. "determine_upload_ignores
1177 |
1178 | *****************************************
1179 | METHOD determine_upload_parameters.
1180 | *****************************************
1181 |
1182 | * Determines file with parameters to the upload of a UI5 application in ABAP Repository
1183 | *
1184 | * In case a .Ui5RepositoryUploadParameters file is found in the directory of the UI5 application
1185 | * its content is used to decide which settings are used in the upload operation.
1186 | *
1187 | * Parameters:
1188 | *
1189 | * SAPUI5ApplicationName Mandatory
1190 | * SAPUI5RepositoryDescription Mandatory: Used for creation of SAPUI5 ABAP Repository, otherwise is an info
1191 | * SAPUI5RepositoryPackage Mandatory
1192 | * TransportRequest Mandatory: ABAP-Transportrequest
1193 | * ExternalCodePage Mandatory: Codepage for the files
1194 | *
1195 |
1196 | * If a .Ui5RepositoryUploadParameters file is not found an import parameter of this Function Module is used.
1197 |
1198 | * Build list of of upload paramenter
1199 |
1200 | * ... Upload parameters from '.Ui5RepositoryUploadParameters' file
1201 | DATA: line TYPE string,
1202 | lines TYPE string_table,
1203 | upload_parameter TYPE slin_key_value.
1204 |
1205 | lines = me->read_file_to_table( iv_path = '.Ui5RepositoryUploadParameters' iv_code_page = iv_code_page ).
1206 | LOOP AT lines INTO line.
1207 | SPLIT line AT '=' INTO upload_parameter-key upload_parameter-value.
1208 | INSERT upload_parameter INTO TABLE me->upload_parameters.
1209 | ENDLOOP.
1210 |
1211 | * ... Or from import parameters
1212 | IF me->upload_parameters IS INITIAL.
1213 | " APPEND text-027 TO me->log_messages_ref->*.
1214 | ELSE.
1215 | " APPEND text-026 TO me->log_messages_ref->*.
1216 | ENDIF.
1217 |
1218 | ENDMETHOD. "determine_upload_parameters
1219 |
1220 | METHOD is_binary_file.
1221 |
1222 | rv_is_binary_file = abap_undefined.
1223 | IF ( lcl_function=>text_matches_pattern( iv_text = iv_file_path iv_pattern_list = me->binary_file_patterns ) = abap_true ).
1224 | rv_is_binary_file = abap_true.
1225 | ENDIF.
1226 |
1227 | ENDMETHOD. "is_binary_file
1228 |
1229 | METHOD is_file_to_be_ignored.
1230 |
1231 | rv_ignore = abap_false.
1232 | IF ( lcl_function=>text_matches_pattern( iv_text = iv_file_path iv_pattern_list = me->upload_ignores ) = abap_true ).
1233 | rv_ignore = abap_true.
1234 | ENDIF.
1235 |
1236 | ENDMETHOD. "is_file_to_be_ignored
1237 |
1238 | METHOD is_text_file.
1239 |
1240 | rv_is_text_file = abap_undefined.
1241 | IF ( lcl_function=>text_matches_pattern( iv_text = iv_file_path iv_pattern_list = me->text_file_patterns ) = abap_true ).
1242 | rv_is_text_file = abap_true.
1243 | ENDIF.
1244 |
1245 | ENDMETHOD. "is_text_file
1246 |
1247 | ENDCLASS. "LCL_SAPUI5_ZIP_ARCHIVE
1248 |
1249 |
1250 |
1251 |
1252 | ************************************************************************
1253 | * Class lcl_external_code_page
1254 | *
1255 | * supports conversion of external code page into abap code page.
1256 | ************************************************************************
1257 | CLASS lcl_external_code_page IMPLEMENTATION.
1258 |
1259 | METHOD create.
1260 |
1261 | * Exception if no page name given
1262 | IF iv_code_page_name IS INITIAL.
1263 | RAISE EXCEPTION TYPE lcx_exception.
1264 | ENDIF.
1265 |
1266 | * Create external code page instance and take over náme
1267 | CREATE OBJECT rv_external_code_page.
1268 | rv_external_code_page->name = iv_code_page_name.
1269 |
1270 | * Determine code page type from name
1271 | DATA: name(10) TYPE c.
1272 | name = iv_code_page_name.
1273 | TRANSLATE name TO LOWER CASE.
1274 |
1275 | IF name(2) = 'cp'.
1276 | rv_external_code_page->kind = 'J'.
1277 | ELSEIF name(3) = 'iso'.
1278 | rv_external_code_page->kind = 'H'.
1279 | ELSEIF name(8) = 'us-ascii'.
1280 | rv_external_code_page->kind = 'H'.
1281 | ELSEIF name = 'utf-16be' OR
1282 | name = 'utf-16le'.
1283 | rv_external_code_page->kind = 'H'.
1284 | ENDIF.
1285 |
1286 | ENDMETHOD. "create
1287 | METHOD for_sapgui_installation.
1288 |
1289 | * Determine abap code page from sapgui installation
1290 | DATA: code_page_abap TYPE abap_encoding,
1291 | rc TYPE i VALUE 0.
1292 | CALL METHOD cl_gui_frontend_services=>get_saplogon_encoding
1293 | CHANGING
1294 | rc = rc
1295 | file_encoding = code_page_abap
1296 | EXCEPTIONS
1297 | cntl_error = 1
1298 | error_no_gui = 2
1299 | not_supported_by_gui = 3
1300 | cannot_initialize_globalstate = 4
1301 | OTHERS = 5.
1302 | IF sy-subrc <> 0 OR code_page_abap = 0.
1303 | RAISE EXCEPTION TYPE lcx_exception.
1304 | ENDIF.
1305 |
1306 | * Determine corresponding java code page name
1307 | DATA: java_code_page_name TYPE string,
1308 | code_page_abap_ TYPE cpcodepage.
1309 | code_page_abap_ = code_page_abap.
1310 | CALL FUNCTION 'SCP_GET_JAVA_NAME'
1311 | EXPORTING
1312 | sap_codepage = code_page_abap_
1313 | IMPORTING
1314 | name = java_code_page_name
1315 | EXCEPTIONS
1316 | name_unknown = 1
1317 | invalid_codepage = 2
1318 | OTHERS = 3.
1319 | IF sy-subrc <> 0. RAISE EXCEPTION TYPE lcx_exception. ENDIF.
1320 |
1321 | * Delegate for create
1322 | rv_external_code_page = lcl_external_code_page=>create( iv_code_page_name = java_code_page_name ).
1323 |
1324 | ENDMETHOD. "create_for_abap_codepage
1325 |
1326 | METHOD get_abap_encoding.
1327 |
1328 | * Delegate ...
1329 | IF me->kind IS NOT INITIAL.
1330 | DATA: abap_encoding TYPE cpcodepage.
1331 | CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
1332 | EXPORTING
1333 | external_name = me->name
1334 | kind = me->kind
1335 | IMPORTING
1336 | sap_codepage = rv_abap_encoding
1337 | EXCEPTIONS
1338 | not_found = 1.
1339 | ELSE.
1340 | "Default value for kind of code page.
1341 | CALL FUNCTION 'SCP_CODEPAGE_BY_EXTERNAL_NAME'
1342 | EXPORTING
1343 | external_name = me->name
1344 | IMPORTING
1345 | sap_codepage = rv_abap_encoding
1346 | EXCEPTIONS
1347 | not_found = 1.
1348 | ENDIF.
1349 | * ... Raise exception if no abap code page found.
1350 | IF sy-subrc <> 0. RAISE EXCEPTION TYPE lcx_exception. ENDIF.
1351 |
1352 | ENDMETHOD. "get_abap_encoding
1353 |
1354 | METHOD get_java_encoding.
1355 |
1356 | * Get ABAP codepage
1357 | DATA: abap_encoding TYPE cpcodepage.
1358 | abap_encoding = me->get_abap_encoding( ).
1359 |
1360 | * Delegate ...
1361 | CALL FUNCTION 'SCP_GET_JAVA_NAME'
1362 | EXPORTING
1363 | sap_codepage = abap_encoding
1364 | IMPORTING
1365 | name = rv_java_encoding
1366 | EXCEPTIONS
1367 | name_unknown = 1
1368 | invalid_codepage = 2
1369 | OTHERS = 3.
1370 | IF sy-subrc <> 0. RAISE EXCEPTION TYPE lcx_exception. ENDIF.
1371 |
1372 | ENDMETHOD. "get_java_encoding
1373 |
1374 | ENDCLASS. "lcl_external_code_page
1375 |
1376 |
1377 |
1378 | ************************************************************************
1379 | * Class LCL_UI5_REPOSITORY
1380 | *
1381 | * represents a UI5 Repository and the UI5 application it contains.
1382 | ************************************************************************
1383 | CLASS lcl_ui5_repository IMPLEMENTATION.
1384 |
1385 | METHOD class_constructor.
1386 | CREATE OBJECT self.
1387 | ENDMETHOD. "class_constructor
1388 |
1389 | METHOD get_mime_type_for_upload.
1390 |
1391 | * Check input
1392 | CLEAR rv_mime_type.
1393 | IF iv_operation IS INITIAL. RETURN. ENDIF.
1394 |
1395 | * Check if file is known to be text
1396 | IF iv_operation->object_type = lcl_operation=>object_type_text_file.
1397 | rv_mime_type = 'text/plain'.
1398 | RETURN.
1399 | ENDIF.
1400 |
1401 | * Check if file is known to be binary
1402 | IF iv_operation->object_type = lcl_operation=>object_type_binary_file.
1403 | rv_mime_type = 'image'. "Although this is not true neccessarily: This should trigger a binary upload
1404 | RETURN.
1405 | ENDIF.
1406 |
1407 | * Determine file extension
1408 | DATA: extension TYPE string.
1409 | extension = iv_operation->get_file_extension( ).
1410 |
1411 | * Determine mime type using file extension via SDOK_MIMETYPE_GET
1412 | DATA: mimetype TYPE mimetypes-type,
1413 | ext TYPE char20.
1414 | ext = extension.
1415 | CALL FUNCTION 'SDOK_MIMETYPE_GET'
1416 | EXPORTING
1417 | extension = ext
1418 | IMPORTING
1419 | mimetype = mimetype.
1420 | .
1421 | rv_mime_type = mimetype.
1422 |
1423 | ENDMETHOD. "get_mime_type_for_upload
1424 |
1425 | *****************************************
1426 | METHOD conciliate_upload_operations.
1427 | *****************************************
1428 | *
1429 | * The method looks into each upload operation and changes it
1430 | * if needed. This depends on the state of the corresponding
1431 | * file in the repository.
1432 | *
1433 | * Example 1:
1434 | * If a file or folder does exist in the repository but is not
1435 | * to be uploaded, then the object in the repository is to be
1436 | * deleted.
1437 | * There are two situations to be considered:
1438 | * a) The object does not exist in the in the archive.
1439 | * b) The object does exist but it is to be ignored
1440 | * as it is in the ignore-list or it is a unix style text file
1441 | * with no automatic conversion active.
1442 | *
1443 | * Example 2:
1444 | * If a file to be uploaded is identical with the one already
1445 | * in the repository, then it is not to be uploaded if
1446 | * delta mode has been activated.
1447 |
1448 | * Nothing to do if repository does not yet exist
1449 | IF me->already_exists = abap_false. RETURN. ENDIF.
1450 |
1451 | * Walk through content of ui5 repository
1452 | DATA: children TYPE string_table,
1453 | child TYPE string.
1454 | TRY.
1455 | children = me->api->get_folder_children( iv_path ).
1456 | CATCH /ui5/cx_ui5_rep_dt.
1457 | ENDTRY.
1458 | LOOP AT children INTO child.
1459 |
1460 | * Debugging
1461 | "if child cs 'meta.properties'. break wegmann. endif.
1462 |
1463 | * Check if child is intended for upload
1464 | * ... and look for corresponding operation
1465 | DATA: child_is_intended_for_upload TYPE abap_bool. child_is_intended_for_upload = abap_false.
1466 | DATA: operation TYPE REF TO lcl_operation.
1467 | CLEAR operation.
1468 | DATA: operation_found TYPE abap_bool. operation_found = abap_false.
1469 | LOOP AT cv_upload_operations INTO operation.
1470 | IF operation->relative_path EQ child.
1471 | operation_found = abap_true.
1472 | IF NOT ( operation->operation = lcl_operation=>ignore_file
1473 | OR operation->operation = lcl_operation=>ignore_folder ).
1474 | child_is_intended_for_upload = abap_true.
1475 | ENDIF.
1476 | EXIT.
1477 | ENDIF.
1478 | ENDLOOP.
1479 | IF operation_found = abap_false. CLEAR operation. ENDIF.
1480 |
1481 | * Check if it is a folder
1482 | DATA: child_is_folder TYPE abap_bool.
1483 | TRY.
1484 | child_is_folder = me->api->check_is_folder( child ).
1485 | CATCH /ui5/cx_ui5_rep_dt.
1486 | ENDTRY.
1487 |
1488 | * Conciliate sub folder
1489 | IF child_is_folder = abap_true.
1490 | * Content
1491 | conciliate_upload_operations( EXPORTING iv_delta_mode = iv_delta_mode
1492 | iv_path = child
1493 | iv_badi = iv_badi
1494 | iv_archive = iv_archive
1495 | CHANGING cv_upload_operations = cv_upload_operations ).
1496 | * Delete folder in repository not intended for upload
1497 | IF child_is_intended_for_upload = abap_false.
1498 | DATA: is_new_operation TYPE abap_bool.
1499 | is_new_operation = abap_false. " There might be an operation of type IGRNORE_FILE already!
1500 | IF operation IS INITIAL. CREATE OBJECT operation. is_new_operation = abap_true. ENDIF.
1501 | operation->to_update = abap_true.
1502 | operation->operation = lcl_operation=>delete_folder.
1503 | operation->relative_path = child.
1504 | operation->object_type = lcl_operation=>object_type_folder.
1505 | IF is_new_operation = abap_true. APPEND operation TO cv_upload_operations. ENDIF.
1506 | ELSE.
1507 | IF iv_delta_mode = abap_true.
1508 | operation->message = TEXT-075. "Folder already exists
1509 | operation->to_update = abap_false.
1510 | ENDIF.
1511 | ENDIF.
1512 |
1513 | * Conciliate file
1514 | ELSE.
1515 |
1516 | * Delete file not intended for upload
1517 | IF child_is_intended_for_upload = abap_false.
1518 |
1519 | * Create operation if there's none yet
1520 | IF operation IS INITIAL.
1521 | CREATE OBJECT operation.
1522 | is_new_operation = abap_true.
1523 | * Determine object type using .Ui5RepositoryTextFiles
1524 | * and .Ui5RepositoryBinaryFiles in the archive
1525 | operation->object_type = lcl_operation=>object_type_file.
1526 | IF iv_archive->is_binary_file( child ) = abap_true.
1527 | operation->object_type = lcl_operation=>object_type_binary_file.
1528 | ELSEIF iv_archive->is_text_file( child ) = abap_true.
1529 | operation->object_type = lcl_operation=>object_type_text_file.
1530 | ENDIF.
1531 | ENDIF.
1532 | operation->to_update = abap_true.
1533 | operation->operation = lcl_operation=>delete_file.
1534 | operation->relative_path = child.
1535 | operation->full_path = child.
1536 |
1537 | * Omit deletion of mime resource if requested via BAdI /UI5/BADI_PREVENT_DELETION
1538 | IF iv_badi->disable_deletion_for( operation ) = abap_true.
1539 | operation->to_update = abap_false.
1540 | operation->operation = lcl_operation=>ignore_file.
1541 | operation->message = TEXT-065. "* Binary file has NOT been deleted in ABAP repository on BAdI request *
1542 | ENDIF.
1543 | *
1544 | operation->object_type = lcl_operation=>object_type_file.
1545 | IF is_new_operation = abap_true. APPEND operation TO cv_upload_operations. ENDIF.
1546 |
1547 | ELSE.
1548 |
1549 | * Skip if nothing to do
1550 | * ... this e.g. is a unix style text file
1551 | IF operation->to_update = abap_false. CONTINUE. ENDIF.
1552 |
1553 | * Consider delta mode
1554 | IF iv_delta_mode EQ abap_true.
1555 | "Try to get a file content, hash of them and compare with a hash form zip
1556 | DATA: lv_file_content TYPE xstring,
1557 | lv_file_content_as_string TYPE string,
1558 | lv_hash TYPE md5_fields-hash.
1559 | TRY.
1560 | CLEAR lv_hash.
1561 | me->api->get_file( EXPORTING iv_path = child
1562 | iv_code_page = operation->code_page
1563 | IMPORTING ev_file_content = lv_file_content ).
1564 | lv_file_content_as_string =
1565 | /ui5/cl_ui5_rep_utility=>convert_xstring_2_string( iv_xstring = lv_file_content
1566 | iv_code_page = operation->code_page ).
1567 | lv_hash = lcl_function=>get_md5_hash_for_string( lv_file_content_as_string ).
1568 |
1569 | ***** Debug conversion of Unix style files *****
1570 | IF lcl_ui5_repository=>debug_conversions_for_file IS NOT INITIAL
1571 | AND operation->object_name EQ lcl_ui5_repository=>debug_conversions_for_file.
1572 |
1573 | DATA: file_path TYPE string.
1574 | CONCATENATE lcl_ui5_repository=>debug_conversions_for_file
1575 | '.repository' INTO file_path. "#EC NOTEXT
1576 | lcl_function=>xstring_to_file( iv_file_content = lv_file_content
1577 | iv_file_path = file_path ).
1578 | CONCATENATE lcl_ui5_repository=>debug_conversions_for_file
1579 | '.repository.as_string' INTO file_path. "#EC NOTEXT
1580 | lcl_function=>string_to_file( iv_file_content = lv_file_content_as_string
1581 | iv_code_page = operation->code_page
1582 | iv_file_path = file_path ).
1583 | ENDIF.
1584 | ************************************************
1585 |
1586 | CATCH /ui5/cx_ui5_rep_dt.
1587 | "File does not exist: It is to be uploaded
1588 | ENDTRY.
1589 | * Compare hash value from content of repository and to upload files
1590 | IF operation->hash_value EQ lv_hash.
1591 | operation->message = TEXT-074. "Already up-to-date
1592 | operation->to_update = abap_false.
1593 | ELSE.
1594 | operation->to_update = abap_true.
1595 | ENDIF.
1596 | ENDIF.
1597 | ENDIF.
1598 | ENDIF.
1599 |
1600 | ENDLOOP.
1601 |
1602 | ENDMETHOD. "conciliate_upload_operations
1603 |
1604 | METHOD get_instance.
1605 | self->log_messages_ref = ir_log_messages.
1606 | rv_self = self.
1607 | ENDMETHOD. "get_instance
1608 |
1609 | * Evaluate authorization available
1610 | METHOD evaluate_authorization.
1611 |
1612 | rv_message = ''.
1613 | DATA: may_be_insufficient TYPE abap_bool. may_be_insufficient = abap_false.
1614 | DATA: affected TYPE string. affected = ''.
1615 |
1616 | * S_DEVELOP
1617 |
1618 | AUTHORITY-CHECK OBJECT 'S_DEVELOP'
1619 | ID 'DEVCLASS' DUMMY
1620 | ID 'OBJTYPE' FIELD 'WAPA'
1621 | ID 'OBJNAME' DUMMY
1622 | ID 'P_GROUP' DUMMY
1623 | ID 'ACTVT' FIELD '02'.
1624 | IF sy-subrc > 0.
1625 | may_be_insufficient = abap_true.
1626 | IF affected IS NOT INITIAL. CONCATENATE affected ', ' INTO affected RESPECTING BLANKS. ENDIF.
1627 | CONCATENATE affected 'S_DEVELOP' INTO affected.
1628 | ENDIF.
1629 |
1630 | * S_ICF_ADM
1631 |
1632 | AUTHORITY-CHECK OBJECT 'S_ICF_ADM'
1633 | ID 'ICF_TYPE' FIELD 'NODE'
1634 | ID 'ACTVT' FIELD '02'
1635 | ID 'ICF_HOST' DUMMY
1636 | ID 'ICF_NODE' DUMMY
1637 | .
1638 | IF sy-subrc > 0.
1639 | may_be_insufficient = abap_true.
1640 | IF affected IS NOT INITIAL. CONCATENATE affected ', ' INTO affected RESPECTING BLANKS. ENDIF.
1641 | CONCATENATE affected 'S_ICF_ADM' INTO affected.
1642 | ENDIF.
1643 |
1644 | * S_TRANSPRT
1645 |
1646 | AUTHORITY-CHECK OBJECT 'S_TRANSPRT'
1647 | ID 'TTYPE' FIELD 'TASK'
1648 | ID 'ACTVT' FIELD '02'.
1649 |
1650 | IF sy-subrc > 0.
1651 | may_be_insufficient = abap_true.
1652 | IF affected IS NOT INITIAL. CONCATENATE affected ', ' INTO affected RESPECTING BLANKS. ENDIF.
1653 | CONCATENATE affected 'S_TRANSPRT' INTO affected.
1654 | ENDIF.
1655 |
1656 |
1657 | * S_TCODE
1658 |
1659 | AUTHORITY-CHECK OBJECT 'S_TCODE'
1660 | ID 'TCD' FIELD '*'.
1661 | IF sy-subrc > 4.
1662 | may_be_insufficient = abap_true.
1663 | IF affected IS NOT INITIAL. CONCATENATE affected ', ' INTO affected RESPECTING BLANKS. ENDIF.
1664 | CONCATENATE affected 'S_TCODE' INTO affected.
1665 | ENDIF.
1666 |
1667 | * S_CTS_ADMI
1668 |
1669 | AUTHORITY-CHECK OBJECT 'S_CTS_ADMI'
1670 | ID 'CTS_ADMFCT' FIELD 'TABL'.
1671 |
1672 | IF sy-subrc > 4.
1673 | may_be_insufficient = abap_true.
1674 | IF affected IS NOT INITIAL. CONCATENATE affected ', ' INTO affected RESPECTING BLANKS. ENDIF.
1675 | CONCATENATE affected 'S_CTS_ADMI' INTO affected.
1676 | ENDIF.
1677 |
1678 | * S_CTS_SADM
1679 | IF may_be_insufficient = abap_true.
1680 | AUTHORITY-CHECK OBJECT 'S_CTS_SADM'
1681 | ID 'DOMAIN' DUMMY
1682 | ID 'DESTSYS' DUMMY
1683 | ID 'CTS_ADMFCT' FIELD 'TABL'.
1684 | IF sy-subrc >= 12.
1685 | DATA: and TYPE string.
1686 | and = 'and'(108). CONDENSE and.
1687 | CONCATENATE affected ' ' and ' S_CTS_ADMI' INTO affected RESPECTING BLANKS.
1688 | ENDIF.
1689 | ENDIF.
1690 |
1691 | * Prepare authorization message
1692 | * ... in case authorization appears to be insufficient
1693 | IF may_be_insufficient = abap_true.
1694 | rv_message = 'Warning : Authorization may be missing for'(102).
1695 | CONCATENATE '* ' rv_message ' ' affected ' *' INTO rv_message RESPECTING BLANKS.
1696 | IF strlen( rv_message ) > 120.
1697 | rv_message = 'Warning : Authorizations may be missing.'(107).
1698 | CONCATENATE '* ' rv_message ' *' INTO rv_message RESPECTING BLANKS.
1699 | ENDIF.
1700 | ENDIF.
1701 |
1702 | ENDMETHOD. "evaluate_authorization
1703 | * METHOD is_binary_file.
1704 | *
1705 | * rv_is_binary_file = abap_undefined.
1706 | * IF ( lcl_function=>text_matches_pattern( iv_text = iv_file_path iv_pattern_list = me->binary_file_patterns ) = abap_true ).
1707 | * rv_is_binary_file = abap_true.
1708 | * ENDIF.
1709 | *
1710 | * ENDMETHOD. "is_binary_file
1711 | *
1712 | * METHOD is_file_to_be_ignored.
1713 | *
1714 | * rv_ignore = abap_false.
1715 | * IF ( lcl_function=>text_matches_pattern( iv_text = iv_file_path iv_pattern_list = me->ignores ) = abap_true ).
1716 | * rv_ignore = abap_true.
1717 | * ENDIF.
1718 | *
1719 | * ENDMETHOD. "is_file_to_be_ignored
1720 | *
1721 | * METHOD is_text_file.
1722 | *
1723 | * rv_is_text_file = abap_undefined.
1724 | * IF ( lcl_function=>text_matches_pattern( iv_text = iv_file_path iv_pattern_list = me->text_file_patterns ) = abap_true ).
1725 | * rv_is_text_file = abap_true.
1726 | * ENDIF.
1727 | *
1728 | * ENDMETHOD. "is_text_file
1729 |
1730 | METHOD set_name.
1731 |
1732 | DATA: message TYPE string.
1733 |
1734 | * Remember name
1735 | me->name = iv_name.
1736 |
1737 | * Check if UI5 Repository already exists. If yes retrieve API.
1738 | TRY.
1739 | me->api = /ui5/cl_ui5_rep_dt=>/ui5/if_ui5_rep_dt~get_api( iv_name = me->name ).
1740 | me->already_exists = abap_true.
1741 | message = TEXT-029.
1742 |
1743 | CATCH cx_root.
1744 | CLEAR me->api.
1745 | me->already_exists = abap_false.
1746 | message = TEXT-028.
1747 | ENDTRY.
1748 | CONCATENATE message ' : ' iv_name INTO message.
1749 | " APPEND message TO me->log_messages_ref->*.
1750 |
1751 | * Check that name is valid
1752 | DATA: p_application_name TYPE o2applname,
1753 | p_application_ext TYPE o2applext.
1754 | p_application_name = iv_name.
1755 | p_application_ext = p_application_name.
1756 | CALL METHOD cl_o2_helper=>check_application_name_valid
1757 | EXPORTING
1758 | p_application_name = p_application_name
1759 | p_application_ext = p_application_ext
1760 | EXCEPTIONS
1761 | invalid = 1.
1762 | IF sy-subrc NE 0.
1763 | MESSAGE ID sy-msgid
1764 | TYPE 'S'
1765 | NUMBER sy-msgno
1766 | WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO message.
1767 | CONCATENATE '* ' message INTO message RESPECTING BLANKS.
1768 | APPEND message TO me->log_messages_ref->*.
1769 | CLEAR me->name.
1770 | EXIT.
1771 | ENDIF.
1772 |
1773 | ENDMETHOD. "set_name
1774 |
1775 |
1776 | ENDCLASS. "lcl_ui5_repository IMPLEMENTATION
1777 |
--------------------------------------------------------------------------------