@sapui5/sap.ushell_abap 1.90.2 → 1.90.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/main/js/sap/ui2/srvc/ODataWrapper.js +1297 -1274
- package/src/main/js/sap/ushell_abap/.library +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/AppStateAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/ClientSideTargetResolutionAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/ConfigurationDefaultsAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/ContainerAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/EndUserFeedbackAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/LaunchPageAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/NavTargetResolutionAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/PageBuildingAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/PagePersistenceAdapter.js +3 -5
- package/src/main/js/sap/ushell_abap/adapters/abap/PersonalizationAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/SearchAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/SupportTicketAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/abap/Ui5ComponentLoaderAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/adapters/hana/ContainerAdapter.js +1 -1
- package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.configure.ushell.js +1 -1
- package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.catalog.js +6 -8
- package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.pageset.js +10 -9
- package/src/main/js/sap/ushell_abap/library.js +2 -2
package/package.json
CHANGED
|
@@ -1,1274 +1,1297 @@
|
|
|
1
|
-
// Copyright (c) 2009-2020 SAP SE, All Rights Reserved
|
|
2
|
-
/**
|
|
3
|
-
* @fileOverview A wrapper around <code>OData</code>, providing CSRF token handling, caching and
|
|
4
|
-
* generic batch support.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
(function () {
|
|
8
|
-
"use strict";
|
|
9
|
-
/*global
|
|
10
|
-
jQuery.sap.declare("sap.ui2.srvc.ODataWrapper");
|
|
11
|
-
|
|
12
|
-
// Note:
|
|
13
|
-
//
|
|
14
|
-
//
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* <
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
* <
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
* //
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* @
|
|
97
|
-
*
|
|
98
|
-
* @
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
*
|
|
120
|
-
* @
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
*
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
* @
|
|
155
|
-
* the
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (oStickySessionConfiguration
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
*
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
*
|
|
274
|
-
*
|
|
275
|
-
*
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
*
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
*
|
|
392
|
-
*
|
|
393
|
-
*
|
|
394
|
-
*
|
|
395
|
-
*
|
|
396
|
-
*
|
|
397
|
-
*
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
*
|
|
414
|
-
*
|
|
415
|
-
*
|
|
416
|
-
* @param {
|
|
417
|
-
* a
|
|
418
|
-
*
|
|
419
|
-
* @
|
|
420
|
-
* a
|
|
421
|
-
*/
|
|
422
|
-
sap.ui2.srvc.testPublishAt(that);
|
|
423
|
-
function
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
*
|
|
544
|
-
*
|
|
545
|
-
*
|
|
546
|
-
*
|
|
547
|
-
*
|
|
548
|
-
*
|
|
549
|
-
*
|
|
550
|
-
*
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
*
|
|
558
|
-
*
|
|
559
|
-
*
|
|
560
|
-
*
|
|
561
|
-
*
|
|
562
|
-
*
|
|
563
|
-
*
|
|
564
|
-
* (
|
|
565
|
-
*
|
|
566
|
-
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
573
|
-
*
|
|
574
|
-
*
|
|
575
|
-
*
|
|
576
|
-
*
|
|
577
|
-
*
|
|
578
|
-
*
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
*
|
|
586
|
-
*
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
*
|
|
590
|
-
*
|
|
591
|
-
*
|
|
592
|
-
*
|
|
593
|
-
*
|
|
594
|
-
*
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
*
|
|
617
|
-
*
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
*
|
|
642
|
-
*
|
|
643
|
-
*
|
|
644
|
-
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
647
|
-
* @param {function()} [fnSuccess]
|
|
648
|
-
* callback function that is executed if the request succeeds, taking
|
|
649
|
-
* @param {function (string, object=)} [fnFailure]
|
|
650
|
-
* error handler taking an error message and, since version 1.28.6, an
|
|
651
|
-
* optional object containing the complete error information as delivered
|
|
652
|
-
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
653
|
-
* for more details.
|
|
654
|
-
* Defaults to the OData service facade's default error handler
|
|
655
|
-
*
|
|
656
|
-
* @public
|
|
657
|
-
* @since 1.19.0
|
|
658
|
-
*/
|
|
659
|
-
this.
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
*
|
|
677
|
-
*
|
|
678
|
-
*
|
|
679
|
-
*
|
|
680
|
-
*
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
*
|
|
704
|
-
*
|
|
705
|
-
*
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
*
|
|
713
|
-
*
|
|
714
|
-
*
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
*
|
|
719
|
-
*
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
*
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
*
|
|
730
|
-
*
|
|
731
|
-
*
|
|
732
|
-
*
|
|
733
|
-
*
|
|
734
|
-
*
|
|
735
|
-
*
|
|
736
|
-
*
|
|
737
|
-
*
|
|
738
|
-
*
|
|
739
|
-
*
|
|
740
|
-
*
|
|
741
|
-
*
|
|
742
|
-
*
|
|
743
|
-
*
|
|
744
|
-
* error
|
|
745
|
-
*
|
|
746
|
-
*
|
|
747
|
-
*
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
}
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
*
|
|
816
|
-
*
|
|
817
|
-
* @
|
|
818
|
-
*
|
|
819
|
-
*
|
|
820
|
-
* @see #
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
*
|
|
835
|
-
*
|
|
836
|
-
* @
|
|
837
|
-
*
|
|
838
|
-
*
|
|
839
|
-
*
|
|
840
|
-
*
|
|
841
|
-
*
|
|
842
|
-
*
|
|
843
|
-
* @
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
*
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
)
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
};
|
|
934
|
-
|
|
935
|
-
/**
|
|
936
|
-
*
|
|
937
|
-
*
|
|
938
|
-
*
|
|
939
|
-
*
|
|
940
|
-
*
|
|
941
|
-
*
|
|
942
|
-
*
|
|
943
|
-
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
946
|
-
*
|
|
947
|
-
*
|
|
948
|
-
* for more details
|
|
949
|
-
*
|
|
950
|
-
*
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
* @
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
*
|
|
1044
|
-
*
|
|
1045
|
-
*
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1049
|
-
*
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
}
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
*
|
|
1063
|
-
*
|
|
1064
|
-
* @param {
|
|
1065
|
-
*
|
|
1066
|
-
*
|
|
1067
|
-
*
|
|
1068
|
-
*
|
|
1069
|
-
*
|
|
1070
|
-
*
|
|
1071
|
-
*
|
|
1072
|
-
*
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
//
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
}
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
*
|
|
1165
|
-
* @
|
|
1166
|
-
*
|
|
1167
|
-
* @
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
}
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
*
|
|
1188
|
-
*
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
//
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
*
|
|
1222
|
-
*
|
|
1223
|
-
*
|
|
1224
|
-
*
|
|
1225
|
-
*
|
|
1226
|
-
*
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
*
|
|
1245
|
-
*
|
|
1246
|
-
*
|
|
1247
|
-
* @
|
|
1248
|
-
*
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1
|
+
// Copyright (c) 2009-2020 SAP SE, All Rights Reserved
|
|
2
|
+
/**
|
|
3
|
+
* @fileOverview A wrapper around <code>OData</code>, providing CSRF token handling, caching and
|
|
4
|
+
* generic batch support.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
(function () {
|
|
8
|
+
"use strict";
|
|
9
|
+
/*global OData */
|
|
10
|
+
jQuery.sap.declare("sap.ui2.srvc.ODataWrapper");
|
|
11
|
+
|
|
12
|
+
// Note: Migration from jquery.sap.log via
|
|
13
|
+
// var Log = sap.ui.require("sap/base/Log");
|
|
14
|
+
// does not work out of the box and leads to an error in the unit tests.
|
|
15
|
+
|
|
16
|
+
// Note: Only the section between @begin and @end is included in pbs-template.js.
|
|
17
|
+
// In pbs-template fnRequire is differently initialized (in case UI5 is not available)!
|
|
18
|
+
// Thus this variable is used in the coding below and not directly jQuery.sap.require.
|
|
19
|
+
// avoid fnRequire = jQuery.sap.require as require cannot be spied on afterwards
|
|
20
|
+
var fnRequire = function () {
|
|
21
|
+
jQuery.sap.require.apply(this, arguments);
|
|
22
|
+
};
|
|
23
|
+
function nop () { /* null object pattern */ }
|
|
24
|
+
|
|
25
|
+
sap.ui2.srvc.testPublishAt = sap.ui2.srvc.testPublishAt || function () {
|
|
26
|
+
// intentionally left blank
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/// @begin
|
|
30
|
+
// if OData is missing, automatically require SAPUI5's datajs implementation
|
|
31
|
+
if (typeof OData !== "object") {
|
|
32
|
+
fnRequire("sap.ui.thirdparty.datajs");
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reject the given <code>jQuery.Deferred</code> object(s) (array or single one) with the
|
|
37
|
+
* given error response.
|
|
38
|
+
*
|
|
39
|
+
* @param {jQuery.Deferred|jQuery.Deferred[]} vDeferred
|
|
40
|
+
* deferred or array of deferreds to be rejected
|
|
41
|
+
* @param {object} oResponse
|
|
42
|
+
* parameter of (each) reject call
|
|
43
|
+
*/
|
|
44
|
+
function reject (vDeferred, oResponse) {
|
|
45
|
+
if (sap.ui2.srvc.isArray(vDeferred)) {
|
|
46
|
+
// a failed change set: reject each single jQuery.Deferred in the same way
|
|
47
|
+
vDeferred.forEach(function (oDeferred) {
|
|
48
|
+
oDeferred.reject(oResponse);
|
|
49
|
+
});
|
|
50
|
+
} else {
|
|
51
|
+
// a failed GET request
|
|
52
|
+
vDeferred.reject(oResponse);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// "public class" ************************************************************
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Constructs a wrapper around <code>OData</code>, providing CSRF token handling, caching and
|
|
60
|
+
* generic batch support. The sap-statistics header is automatically added to all requests if
|
|
61
|
+
* the URL query parameter <code>sap-statistics=true</code> is set (see
|
|
62
|
+
* <a href="http://help.sap.com/saphelp_nw74/helpdata/de/40/93b81292194d6a926e105c10d5048d/content.htm">
|
|
63
|
+
* SAP Performance Statistics</a>).
|
|
64
|
+
* If <code>OData</code> is missing, "sap.ui.thirdparty.datajs" is required automatically.
|
|
65
|
+
* <p>
|
|
66
|
+
* The preferred way to call the constructor is from a "sub-class" of
|
|
67
|
+
* {@link sap.ui2.srvc.ODataService}:
|
|
68
|
+
* <pre>
|
|
69
|
+
* function Service() {
|
|
70
|
+
* var oWrapper = new sap.ui2.srvc.ODataWrapper(oSettings, this);
|
|
71
|
+
* sap.ui2.srvc.ODataService.call(this, oWrapper, fnDefaultFailure);
|
|
72
|
+
* }
|
|
73
|
+
* var myService = new Service();
|
|
74
|
+
* </pre>
|
|
75
|
+
* This provides public inheritance of <code>sap.ui2.srvc.ODataService</code> methods and
|
|
76
|
+
* private inheritance of <code>sap.ui2.srvc.ODataWrapper</code> methods. In case you are not
|
|
77
|
+
* providing a public "sub-class" of <code>sap.ui2.srvc.ODataService</code> but only want to
|
|
78
|
+
* use methods from <code>sap.ui2.srvc.ODataWrapper</code>,
|
|
79
|
+
* {@link sap.ui2.srvc.createODataWrapper} is the preferred way to construct an instance.
|
|
80
|
+
*
|
|
81
|
+
* @param {object} oSettings
|
|
82
|
+
* An object containing various properties:
|
|
83
|
+
* <pre>
|
|
84
|
+
* {
|
|
85
|
+
* baseUrl: "/OData/OData.svc", // Mandatory base URL of the OData service
|
|
86
|
+
* supportsChangeSets: false, // Type: boolean, Default: false
|
|
87
|
+
* // Whether the OData service supports change sets with <b>multiple</b>
|
|
88
|
+
* // operations bundled into a single logical unit of work. Otherwise
|
|
89
|
+
* // each modifying operation is isolated in a change set of its own.
|
|
90
|
+
* "sap-language": "EN", // header which is set for all requests sent
|
|
91
|
+
* "sap-client": 120, // header which is set for all requests sent
|
|
92
|
+
* "sap-statistics": true // header which is set for all requests sent; in order to receive
|
|
93
|
+
* // some performance statistics
|
|
94
|
+
* }
|
|
95
|
+
* </pre>
|
|
96
|
+
* @param {sap.ui2.srvc.ODataService} oODataService
|
|
97
|
+
* facade to any OData service, keeping track of CSRF token and default error handler
|
|
98
|
+
* (see {@link #getODataService})
|
|
99
|
+
*
|
|
100
|
+
* @class
|
|
101
|
+
* @public
|
|
102
|
+
* @since 1.19.0
|
|
103
|
+
*/
|
|
104
|
+
// OLD API: function (sBaseUrl, oODataService, bSupportsChangeSets)
|
|
105
|
+
sap.ui2.srvc.ODataWrapper = function (oSettings, oODataService) {
|
|
106
|
+
var S_STICKY_SESSION_HEADER = "saplb", // header to check during sticky session
|
|
107
|
+
aBatchQueue, // corresponds to data.__batchRequests
|
|
108
|
+
bChangeSetOpen, // whether a change set is currently open at the end of our batch queue
|
|
109
|
+
aDeferredQueue, // jQuery.Deferred() objects corresponding to each request
|
|
110
|
+
that = this,
|
|
111
|
+
sBaseUrl,
|
|
112
|
+
bSupportsChangeSets;
|
|
113
|
+
|
|
114
|
+
// BEWARE: constructor code below!
|
|
115
|
+
|
|
116
|
+
// "private" methods -------------------------------------------------------
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Converts old api calls of the ODataWrapper constructor to the current one.
|
|
120
|
+
* @param {object} oArgs
|
|
121
|
+
* An arguments object containing the parameters of the constructor function. See Constructor for details.
|
|
122
|
+
* @returns {object}
|
|
123
|
+
* Settings for ODataWrapper in an object instead of arguments
|
|
124
|
+
* @private
|
|
125
|
+
*/
|
|
126
|
+
function handleOldConstructorApi (oArgs) {
|
|
127
|
+
var oSettingsODataWrapper = {};
|
|
128
|
+
|
|
129
|
+
oSettingsODataWrapper.baseUrl = oArgs[0];
|
|
130
|
+
// This is not a mandatory parameter and might be undefined
|
|
131
|
+
if (typeof oArgs[2] === "boolean") {
|
|
132
|
+
oSettingsODataWrapper.supportsChangeSets = oArgs[2];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return oSettingsODataWrapper;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* eslint-disable no-unused-vars */
|
|
139
|
+
/**
|
|
140
|
+
* Getter mainly used for testing.
|
|
141
|
+
*
|
|
142
|
+
* @returns {object}
|
|
143
|
+
*/
|
|
144
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
145
|
+
function getBatchQueue () {
|
|
146
|
+
return aBatchQueue;
|
|
147
|
+
}
|
|
148
|
+
/* eslint-enable no-unused-vars */
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Iterates over the given headers map and returns the first value for the requested key (case
|
|
152
|
+
* insensitive). If no such key is found, <code>undefined</code> is returned.
|
|
153
|
+
*
|
|
154
|
+
* @param {string} sKey
|
|
155
|
+
* the requested key
|
|
156
|
+
* @param {object} [mHeaders={}]
|
|
157
|
+
* an object treated as a <code>map<string, object></code>
|
|
158
|
+
* @returns {string}
|
|
159
|
+
* the header value or <code>undefined</code> if the header was not found
|
|
160
|
+
*/
|
|
161
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
162
|
+
function headerValue (sKey, mHeaders) {
|
|
163
|
+
sKey = sKey.toLowerCase();
|
|
164
|
+
for (var sCurrentKey in mHeaders) {
|
|
165
|
+
if (Object.prototype.hasOwnProperty.call(mHeaders, sCurrentKey)
|
|
166
|
+
&& sCurrentKey.toLowerCase() === sKey) {
|
|
167
|
+
return mHeaders[sCurrentKey];
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return undefined;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Gets an object supposed to be the headers object used for OData requests.
|
|
175
|
+
* Adds headers set as static properties of sap.ui2.srvc.ODataWrapper or as part of Constructor settings.
|
|
176
|
+
* The following headers may be added:
|
|
177
|
+
* - sap-language
|
|
178
|
+
* - sap-statistics
|
|
179
|
+
* - sap-client
|
|
180
|
+
*
|
|
181
|
+
* @param {object} [oHeaders={}]
|
|
182
|
+
* optional object supposed to be the headers object used for OData requests
|
|
183
|
+
* @returns {object}
|
|
184
|
+
* returns oHeader (if not given, a new object is created) additional headers may be added as
|
|
185
|
+
* properties to the object.
|
|
186
|
+
*/
|
|
187
|
+
function addGlobalSapHeaders (oHeaders) {
|
|
188
|
+
var sSapLanguage = oSettings["sap-language"] || sap.ui2.srvc.ODataWrapper["sap-language"],
|
|
189
|
+
sSapStatistics = oSettings["sap-statistics"] || sap.ui2.srvc.ODataWrapper["sap-statistics"],
|
|
190
|
+
sSapClient = oSettings["sap-client"] || sap.ui2.srvc.ODataWrapper["sap-client"];
|
|
191
|
+
|
|
192
|
+
oHeaders = oHeaders || {};
|
|
193
|
+
if (sSapLanguage) {
|
|
194
|
+
oHeaders["sap-language"] = sSapLanguage;
|
|
195
|
+
}
|
|
196
|
+
if (sSapStatistics || (sSapStatistics === "false")) {
|
|
197
|
+
// If sSapStatistics is set, all requests done via ODataWrapper, will contain the
|
|
198
|
+
// sap-statistics header. See
|
|
199
|
+
// http://help.sap.com/saphelp_nw74/helpdata/de/40/93b81292194d6a926e105c10d5048d/content.htm
|
|
200
|
+
oHeaders["sap-statistics"] = "" + sSapStatistics;
|
|
201
|
+
}
|
|
202
|
+
if (sSapClient) {
|
|
203
|
+
oHeaders["sap-client"] = sSapClient;
|
|
204
|
+
}
|
|
205
|
+
return oHeaders;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Adds previously detected sticky session headers to the given object
|
|
210
|
+
* (which is supposed to be the headers object used for OData requests).
|
|
211
|
+
*
|
|
212
|
+
* @param {object} [oHeaders={}]
|
|
213
|
+
* optional object supposed to be the headers object used for OData requests
|
|
214
|
+
* @returns {object}
|
|
215
|
+
* returns oHeader (if not given, a new object is created) additional
|
|
216
|
+
* headers may be added as properties to the object.
|
|
217
|
+
*/
|
|
218
|
+
function addStickySessionHeader (oHeaders) {
|
|
219
|
+
oHeaders = oHeaders || {};
|
|
220
|
+
|
|
221
|
+
var oStickySessionConfiguration =
|
|
222
|
+
sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration[sBaseUrl];
|
|
223
|
+
|
|
224
|
+
/*
|
|
225
|
+
* NOTE: not assuming oStickySessionConfiguration is defined (see comment
|
|
226
|
+
* on assigment of sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration)
|
|
227
|
+
* down in this file.
|
|
228
|
+
*/
|
|
229
|
+
if (typeof oStickySessionConfiguration === "undefined") {
|
|
230
|
+
return oHeaders;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
if (oStickySessionConfiguration && oStickySessionConfiguration.enabled &&
|
|
234
|
+
typeof oStickySessionConfiguration.value !== "undefined") {
|
|
235
|
+
|
|
236
|
+
oHeaders[S_STICKY_SESSION_HEADER] = oStickySessionConfiguration.value;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return oHeaders;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Detects sticky session based on the given response headers and, in case
|
|
244
|
+
* of success, updates the static
|
|
245
|
+
* sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration with the sticky
|
|
246
|
+
* session value found in the header.
|
|
247
|
+
*
|
|
248
|
+
* @param {object} oResponseHeaders
|
|
249
|
+
* the response headers
|
|
250
|
+
*/
|
|
251
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
252
|
+
function detectStickySession (oResponseHeaders) {
|
|
253
|
+
var sHeaderValue,
|
|
254
|
+
oStickySessionConfiguration =
|
|
255
|
+
sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration[sBaseUrl];
|
|
256
|
+
|
|
257
|
+
if (!oStickySessionConfiguration || !oStickySessionConfiguration.enabled) {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// add sticky session header value if found
|
|
262
|
+
sHeaderValue = headerValue(S_STICKY_SESSION_HEADER, oResponseHeaders);
|
|
263
|
+
if (typeof sHeaderValue === "undefined") {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (oStickySessionConfiguration.value !== sHeaderValue) { // take the last value from server
|
|
268
|
+
oStickySessionConfiguration.value = sHeaderValue;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Iterates over the given headers map and returns the first value for the well-known
|
|
274
|
+
* "X-CSRF-Token" key (case insensitive). If no such key is found, or if the request
|
|
275
|
+
* was cached, <code>""</code> is returned.
|
|
276
|
+
*
|
|
277
|
+
* @param {object} [mHeaders={}]
|
|
278
|
+
* an object treated as a <code>map<string, object></code>
|
|
279
|
+
* @returns {string}
|
|
280
|
+
*/
|
|
281
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
282
|
+
function csrfTokenValue (mHeaders) {
|
|
283
|
+
|
|
284
|
+
// Access CSRF token value
|
|
285
|
+
var sCsrfTokenHeaderValue = headerValue("x-csrf-token", mHeaders);
|
|
286
|
+
|
|
287
|
+
// Return always if value was "Required"
|
|
288
|
+
// ... Happens when server reported http status "403 Forbidden" and token was invalid or expired
|
|
289
|
+
if (sCsrfTokenHeaderValue === "Required") {
|
|
290
|
+
return sCsrfTokenHeaderValue;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// Do not return if no value or request was cached
|
|
294
|
+
// ... as indicated by cache-control header, Expires header not evaluated here
|
|
295
|
+
var sCacheControlHeaderValue = headerValue("cache-control", mHeaders);
|
|
296
|
+
if (sCacheControlHeaderValue === undefined
|
|
297
|
+
|| sCacheControlHeaderValue.indexOf("max-age=0") > -1
|
|
298
|
+
|| sCacheControlHeaderValue.indexOf("no-cache") > -1) {
|
|
299
|
+
return sCsrfTokenHeaderValue || "";
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return "";
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/**
|
|
306
|
+
* Wrapper around
|
|
307
|
+
* <a href="http://datajs.codeplex.com/wikipage?title=datajs%20OData%20API#OData.request">
|
|
308
|
+
* <code>OData.request</code></a> which is able to automatically fetch a CSRF token if
|
|
309
|
+
* required.
|
|
310
|
+
*
|
|
311
|
+
* @param {string} sRequestUrl
|
|
312
|
+
* a string containing the <b>absolute</b> URL
|
|
313
|
+
* @param {string} sMethod
|
|
314
|
+
* the HTTP method to use, e.g. "POST"
|
|
315
|
+
* @param {object} oPayload
|
|
316
|
+
* payload of the request (in intermediate format)
|
|
317
|
+
* @param {function(object)} [fnSuccess]
|
|
318
|
+
* callback function that is executed if the request succeeds, taking the processed data
|
|
319
|
+
* @param {function (string, object=)} [fnFailure]
|
|
320
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
321
|
+
* optional object containing the complete error information as delivered
|
|
322
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
323
|
+
* for more details.
|
|
324
|
+
* Defaults to the OData service facade's default error handler
|
|
325
|
+
* @param {object} [oHandler]
|
|
326
|
+
* (OData/datajs) handler for the response data
|
|
327
|
+
* @param {boolean} [bIsRepeatedRequest]
|
|
328
|
+
* This function recursively calls itself to re-execute it in case the CSRF token was invalid and has been fetched.
|
|
329
|
+
* To prevent endless loops when the server returns an invalid token, this flag is used.
|
|
330
|
+
*/
|
|
331
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
332
|
+
function doRequest (sRequestUrl, sMethod, oPayload, fnSuccess, fnFailure, oHandler, bIsRepeatedRequest) {
|
|
333
|
+
var oHeaders;
|
|
334
|
+
fnSuccess = fnSuccess || nop;
|
|
335
|
+
fnFailure = fnFailure || oODataService.getDefaultErrorHandler();
|
|
336
|
+
that.check(fnSuccess, fnFailure);
|
|
337
|
+
oHeaders = {
|
|
338
|
+
Accept: "application/json",
|
|
339
|
+
"Accept-Language": (sap.ui && sap.ui.getCore().getConfiguration().getLanguage()) || "",
|
|
340
|
+
"X-CSRF-Token": oODataService.getCsrfToken()
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
addGlobalSapHeaders(oHeaders);
|
|
344
|
+
addStickySessionHeader(oHeaders);
|
|
345
|
+
|
|
346
|
+
OData.request({
|
|
347
|
+
requestUri: sRequestUrl,
|
|
348
|
+
method: sMethod,
|
|
349
|
+
data: oPayload,
|
|
350
|
+
headers: oHeaders
|
|
351
|
+
},
|
|
352
|
+
function (oData, oResponse) {
|
|
353
|
+
detectStickySession((oResponse || {}).headers);
|
|
354
|
+
jQuery.sap.log.debug("Received OData response for " + sMethod + ' "' + sRequestUrl + '"',
|
|
355
|
+
null,
|
|
356
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
357
|
+
// Note: drop excess parameters; try/catch
|
|
358
|
+
sap.ui2.srvc.call(fnSuccess.bind(null, oData), fnFailure);
|
|
359
|
+
},
|
|
360
|
+
function (oError) {
|
|
361
|
+
// wrappers for success & failure handlers to reset flag
|
|
362
|
+
function failure () {
|
|
363
|
+
fnFailure.apply(null, arguments);
|
|
364
|
+
}
|
|
365
|
+
function success () {
|
|
366
|
+
fnSuccess.apply(null, arguments);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
if (!bIsRepeatedRequest
|
|
370
|
+
&& oError.response.statusCode === 403
|
|
371
|
+
&& csrfTokenValue(oError.response.headers).toLowerCase() === "required") {
|
|
372
|
+
// refresh CSRF token and repeat original request
|
|
373
|
+
jQuery.sap.log.debug("CSRF token required for " + sMethod + ' "' + sRequestUrl
|
|
374
|
+
+ '", refreshing it', JSON.stringify(oError.response),
|
|
375
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
376
|
+
|
|
377
|
+
oODataService.refreshCsrfToken(
|
|
378
|
+
doRequest.bind(that, sRequestUrl, sMethod, oPayload, success, failure, oHandler, /*bIsRepeatedRequest*/ true),
|
|
379
|
+
failure
|
|
380
|
+
);
|
|
381
|
+
} else {
|
|
382
|
+
that.onError(sMethod, sRequestUrl, fnFailure, /*oDeferred*/null, oError);
|
|
383
|
+
}
|
|
384
|
+
},
|
|
385
|
+
oHandler);
|
|
386
|
+
jQuery.sap.log.debug("Sent OData request for " + sMethod + ' "' + sRequestUrl + '"', null,
|
|
387
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Transforms the given absolute URL into a relative URL w.r.t. this OData wrapper's base URL,
|
|
392
|
+
* removing protocol, host, port, and base URL, but preserving query parameters and a fragment
|
|
393
|
+
* part.
|
|
394
|
+
*
|
|
395
|
+
* @param {string} sRequestUrl
|
|
396
|
+
* a string containing an <b>absolute</b> URL, e.g.
|
|
397
|
+
* "http://acme.corp/OData/OData.svc/Products(1)?$foo=bar#abc"
|
|
398
|
+
* @returns {string}
|
|
399
|
+
* a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL, e.g.
|
|
400
|
+
* "Products(1)?$foo=bar#abc"
|
|
401
|
+
*/
|
|
402
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
403
|
+
function toRelativeUrl (sRequestUrl) {
|
|
404
|
+
var i = sRequestUrl.indexOf(sBaseUrl);
|
|
405
|
+
if (i < 0) {
|
|
406
|
+
throw new sap.ui2.srvc.Error('Not relative to base URL "' + sBaseUrl + '": ' + sRequestUrl,
|
|
407
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
408
|
+
}
|
|
409
|
+
return sRequestUrl.slice(i + sBaseUrl.length);
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Transforms the given relative URL into an absolute URL w.r.t. this OData wrapper's base URL,
|
|
414
|
+
* making sure there is exactly one slash in between.
|
|
415
|
+
*
|
|
416
|
+
* @param {string} sRelativeUrl
|
|
417
|
+
* a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL, e.g.
|
|
418
|
+
* "Products(1)"
|
|
419
|
+
* @returns {string}
|
|
420
|
+
* a string containing the <b>absolute</b> URL, e.g. "/OData/OData.svc/Products(1)"
|
|
421
|
+
*/
|
|
422
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
423
|
+
function toRequestUrl (sRelativeUrl) {
|
|
424
|
+
if (/^\//.test(sRelativeUrl)) {
|
|
425
|
+
throw new sap.ui2.srvc.Error("Not a relative URL: " + sRelativeUrl,
|
|
426
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
427
|
+
}
|
|
428
|
+
return sBaseUrl + sRelativeUrl;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Wrapper around
|
|
433
|
+
* <a href="http://datajs.codeplex.com/wikipage?title=datajs%20OData%20API#OData.read">
|
|
434
|
+
* <code>OData.read</code></a> which supports queuing up for "$batch" requests.
|
|
435
|
+
*
|
|
436
|
+
* @param {string} sRelativeUrl
|
|
437
|
+
* a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL, e.g.
|
|
438
|
+
* "Products(1)"
|
|
439
|
+
* @param {function(object,object)} fnRawSuccess
|
|
440
|
+
* a callback function that is executed if the request succeeds, taking the processed data
|
|
441
|
+
* and the response object
|
|
442
|
+
* @param {function (object)} fnRawFailure
|
|
443
|
+
* a callback function that is executed if the request fails, taking an error object
|
|
444
|
+
*/
|
|
445
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
446
|
+
function readOrBatch (sRelativeUrl, fnRawSuccess, fnRawFailure) {
|
|
447
|
+
var oDeferred,
|
|
448
|
+
sRequestUrl = toRequestUrl(sRelativeUrl),
|
|
449
|
+
oHeaders = addStickySessionHeader(addGlobalSapHeaders()); // may return an empty object
|
|
450
|
+
|
|
451
|
+
if (aBatchQueue) {
|
|
452
|
+
jQuery.sap.log.debug('Queued OData request for GET "' + sRelativeUrl + '"', null,
|
|
453
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
454
|
+
aBatchQueue.push({
|
|
455
|
+
method: "GET",
|
|
456
|
+
requestUri: sRelativeUrl,
|
|
457
|
+
headers: oHeaders
|
|
458
|
+
});
|
|
459
|
+
oDeferred = (new jQuery.Deferred()).done(fnRawSuccess).fail(fnRawFailure);
|
|
460
|
+
aDeferredQueue.push(oDeferred);
|
|
461
|
+
bChangeSetOpen = false;
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// add specifc headers for read request
|
|
466
|
+
oHeaders.Accept = "application/json";
|
|
467
|
+
oHeaders["Accept-Language"] = (sap.ui && sap.ui.getCore().getConfiguration().getLanguage()) || "";
|
|
468
|
+
// always fetch a new token with GET requests;
|
|
469
|
+
// this avoids using old tokens from responses served from browser cache
|
|
470
|
+
// see internal BCP incident 1570753380
|
|
471
|
+
oHeaders["X-CSRF-Token"] = "Fetch";
|
|
472
|
+
|
|
473
|
+
OData.read({
|
|
474
|
+
requestUri: sRequestUrl,
|
|
475
|
+
headers: oHeaders
|
|
476
|
+
}, fnRawSuccess, fnRawFailure);
|
|
477
|
+
jQuery.sap.log.debug('Sent OData request for GET "' + sRequestUrl + '"', null,
|
|
478
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
/**
|
|
482
|
+
* Wrapper around {@link #doRequest} which supports queuing up for "$batch" requests.
|
|
483
|
+
*
|
|
484
|
+
* @param {string} sRelativeUrl
|
|
485
|
+
* a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL, e.g.
|
|
486
|
+
* "Products"
|
|
487
|
+
* @param {string} sMethod
|
|
488
|
+
* the HTTP method to use, either "POST", "PUT" or "DELETE" (retrieve requests using "GET"
|
|
489
|
+
* must be made via {@link #readOrBatch} instead!)
|
|
490
|
+
* @param {object} oPayload
|
|
491
|
+
* payload of the request (in intermediate format)
|
|
492
|
+
* @param {function(object)} [fnSuccess]
|
|
493
|
+
* callback function that is executed if the request succeeds, taking the processed data
|
|
494
|
+
* @param {function (string, object=)} [fnFailure]
|
|
495
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
496
|
+
* optional object containing the complete error information as delivered
|
|
497
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
498
|
+
* for more details.
|
|
499
|
+
* Defaults to the OData service facade's default error handler
|
|
500
|
+
*/
|
|
501
|
+
sap.ui2.srvc.testPublishAt(that);
|
|
502
|
+
function requestOrBatch (sRelativeUrl, sMethod, oPayload, fnSuccess, fnFailure) {
|
|
503
|
+
/*jslint nomen:true */
|
|
504
|
+
var oDeferred,
|
|
505
|
+
oChangeRequest = {
|
|
506
|
+
data: oPayload,
|
|
507
|
+
method: sMethod,
|
|
508
|
+
requestUri: sRelativeUrl,
|
|
509
|
+
headers: addStickySessionHeader(addGlobalSapHeaders()) // may return an empty object
|
|
510
|
+
},
|
|
511
|
+
sRequestUrl = toRequestUrl(sRelativeUrl);
|
|
512
|
+
|
|
513
|
+
if (aBatchQueue) {
|
|
514
|
+
fnSuccess = fnSuccess || nop;
|
|
515
|
+
fnFailure = fnFailure || oODataService.getDefaultErrorHandler();
|
|
516
|
+
that.check(fnSuccess, fnFailure);
|
|
517
|
+
jQuery.sap.log.debug("Queued OData request for " + sMethod + ' "' + sRelativeUrl + '"',
|
|
518
|
+
null, "sap.ui2.srvc.ODataWrapper");
|
|
519
|
+
if (!bChangeSetOpen) {
|
|
520
|
+
aBatchQueue.push({__changeRequests: []});
|
|
521
|
+
aDeferredQueue.push([]);
|
|
522
|
+
bChangeSetOpen = bSupportsChangeSets;
|
|
523
|
+
}
|
|
524
|
+
aBatchQueue[aBatchQueue.length - 1].__changeRequests.push(oChangeRequest);
|
|
525
|
+
oDeferred = (new jQuery.Deferred())
|
|
526
|
+
.done(function (oData, oResponse) {
|
|
527
|
+
jQuery.sap.log.debug("Received OData response for "
|
|
528
|
+
+ sMethod + ' "' + sRequestUrl + '"', null, "sap.ui2.srvc.ODataWrapper");
|
|
529
|
+
// Note: drop excess parameters; try/catch
|
|
530
|
+
sap.ui2.srvc.call(fnSuccess.bind(null, oData), fnFailure);
|
|
531
|
+
})
|
|
532
|
+
.fail(that.onError.bind(that, sMethod, sRequestUrl, fnFailure, /*oDeferred*/null));
|
|
533
|
+
aDeferredQueue[aDeferredQueue.length - 1].push(oDeferred);
|
|
534
|
+
return;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
doRequest(sRequestUrl, sMethod, oPayload, fnSuccess, fnFailure);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
// "public" methods --------------------------------------------------------
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Checks whether session stickyness is configured and enabled
|
|
544
|
+
*
|
|
545
|
+
* @returns {boolean}
|
|
546
|
+
* whether the sticky session header is configured and active
|
|
547
|
+
*
|
|
548
|
+
* @public
|
|
549
|
+
*
|
|
550
|
+
* @since 1.30.0
|
|
551
|
+
*/
|
|
552
|
+
this.isStickySessionEnabled = function () {
|
|
553
|
+
return (sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration[sBaseUrl] || {}).enabled || false;
|
|
554
|
+
};
|
|
555
|
+
|
|
556
|
+
/**
|
|
557
|
+
* <p>
|
|
558
|
+
* Configures and activates session stickiness.
|
|
559
|
+
* </p>
|
|
560
|
+
* <p>
|
|
561
|
+
* Session stickiness allows the client to execute OData requests to the
|
|
562
|
+
* same application server. This is achieved by copying a certain sticky
|
|
563
|
+
* session header
|
|
564
|
+
* (found in the OData response from the server) to the OData request made
|
|
565
|
+
* by ODataWrapper, indicating the load balancer that requests should be
|
|
566
|
+
* made against a certain application server. Once detected, the sticky
|
|
567
|
+
* header is automatically shared by all instances of
|
|
568
|
+
* <code>sap.ui2.srvc.ODataWrapper</code> connected to exactly the same
|
|
569
|
+
* base URL.
|
|
570
|
+
* </p>
|
|
571
|
+
* <p>
|
|
572
|
+
* NOTE: The sticky session header sent from the server always overrides
|
|
573
|
+
* the last sticky session header requested. This is to avoid that the
|
|
574
|
+
* feature is disabled if the load balancer returns another value for the
|
|
575
|
+
* sticky session header for some reason (e.g. the application server goes
|
|
576
|
+
* offline).
|
|
577
|
+
* </p>
|
|
578
|
+
* <p>
|
|
579
|
+
* NOTE: In line with {@link sap.ui2.srvc.PageBuildingService}, session
|
|
580
|
+
* stickiness is only supported in scopes different from PERS.
|
|
581
|
+
* </p>
|
|
582
|
+
* <p>
|
|
583
|
+
* Currently, session stickiness is affected by the following limitations:
|
|
584
|
+
* <ul>
|
|
585
|
+
* <li>If the client caches the response headers for certain requests, these
|
|
586
|
+
* cached headers will be used instead of the headers sent from the server
|
|
587
|
+
* (as in if cache was disabled).</li>
|
|
588
|
+
* <li>If initial requests to different URLs that share the same base URL are
|
|
589
|
+
* performed asynchronously (e.g. through multiple instances of
|
|
590
|
+
* ODataWrapper), sticky session may be disabled for a part or all of these
|
|
591
|
+
* initial requests. This is because the requests are made before the first
|
|
592
|
+
* response with a sticky session header is obtained.</li>
|
|
593
|
+
* <li>This mechanism only guarantees that requests are forwarded to the
|
|
594
|
+
* specified application server. For example, if the application server in
|
|
595
|
+
* turn contacts further load balanced servers, the session may not be
|
|
596
|
+
* maintain and load balancing may still occur.</li>
|
|
597
|
+
* </ul>
|
|
598
|
+
* </p>
|
|
599
|
+
* @public
|
|
600
|
+
*
|
|
601
|
+
* @since 1.30.0
|
|
602
|
+
*/
|
|
603
|
+
this.enableStickySession = function () {
|
|
604
|
+
sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration[sBaseUrl].enabled = true;
|
|
605
|
+
};
|
|
606
|
+
|
|
607
|
+
/**
|
|
608
|
+
* Checks that the given callback functions are really functions. This check
|
|
609
|
+
* is useful to "fail fast" because these callbacks are not called immediately.
|
|
610
|
+
*
|
|
611
|
+
* @param {function} fnSuccess
|
|
612
|
+
* success callback
|
|
613
|
+
* @param {function} fnFailure
|
|
614
|
+
* error callback
|
|
615
|
+
*
|
|
616
|
+
* @public
|
|
617
|
+
* @since 1.19.0
|
|
618
|
+
*/
|
|
619
|
+
this.check = function (fnSuccess, fnFailure) {
|
|
620
|
+
if (!fnSuccess) {
|
|
621
|
+
throw new sap.ui2.srvc.Error("Missing success callback",
|
|
622
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
623
|
+
}
|
|
624
|
+
if (typeof fnSuccess !== "function") {
|
|
625
|
+
throw new sap.ui2.srvc.Error("Success callback is not a function",
|
|
626
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
627
|
+
}
|
|
628
|
+
if (!fnFailure) {
|
|
629
|
+
throw new sap.ui2.srvc.Error("Missing error callback",
|
|
630
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
631
|
+
}
|
|
632
|
+
if (typeof fnFailure !== "function") {
|
|
633
|
+
throw new sap.ui2.srvc.Error("Error callback is not a function",
|
|
634
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
635
|
+
}
|
|
636
|
+
};
|
|
637
|
+
|
|
638
|
+
/**
|
|
639
|
+
* Wrapper around <code>OData.request</code> which is able to automatically fetch a CSRF token
|
|
640
|
+
* if required. It uses POST as a method.
|
|
641
|
+
*
|
|
642
|
+
* @param {string} sRelativeUrl
|
|
643
|
+
* a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL, e.g.
|
|
644
|
+
* "Products"
|
|
645
|
+
* @param {object} oPayload
|
|
646
|
+
* payload of the request (in intermediate format)
|
|
647
|
+
* @param {function(object)} [fnSuccess]
|
|
648
|
+
* callback function that is executed if the request succeeds, taking the processed data
|
|
649
|
+
* @param {function (string, object=)} [fnFailure]
|
|
650
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
651
|
+
* optional object containing the complete error information as delivered
|
|
652
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
653
|
+
* for more details.
|
|
654
|
+
* Defaults to the OData service facade's default error handler
|
|
655
|
+
*
|
|
656
|
+
* @public
|
|
657
|
+
* @since 1.19.0
|
|
658
|
+
*/
|
|
659
|
+
this.create = function (sRelativeUrl, oPayload, fnSuccess, fnFailure) {
|
|
660
|
+
requestOrBatch(sRelativeUrl, "POST", oPayload, fnSuccess, fnFailure);
|
|
661
|
+
};
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Wrapper around <code>OData.request</code> which is able to automatically fetch a CSRF token
|
|
665
|
+
* if required. It uses DELETE as a method.
|
|
666
|
+
*
|
|
667
|
+
* @param {string|object} vEntity
|
|
668
|
+
* either a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL,
|
|
669
|
+
* e.g. "Products(1)", or the datajs representation of the entity
|
|
670
|
+
* @param {function()} [fnSuccess]
|
|
671
|
+
* callback function that is executed if the request succeeds, taking no data
|
|
672
|
+
* @param {function (string, object=)} [fnFailure]
|
|
673
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
674
|
+
* optional object containing the complete error information as delivered
|
|
675
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
676
|
+
* for more details.
|
|
677
|
+
* Defaults to the OData service facade's default error handler
|
|
678
|
+
*
|
|
679
|
+
* @public
|
|
680
|
+
* @since 1.19.0
|
|
681
|
+
*/
|
|
682
|
+
this.del = function (vEntity, fnSuccess, fnFailure) {
|
|
683
|
+
/*jslint nomen:true */
|
|
684
|
+
var sRelativeUrl = vEntity;
|
|
685
|
+
|
|
686
|
+
if (typeof sRelativeUrl !== "string") {
|
|
687
|
+
sRelativeUrl = toRelativeUrl(vEntity.__metadata.uri);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
requestOrBatch(sRelativeUrl, "DELETE", null, function (oData) {
|
|
691
|
+
if (fnSuccess) {
|
|
692
|
+
// Note: try/catch already done by doRequest()
|
|
693
|
+
fnSuccess(); // drop excess parameters (oData === undefined)
|
|
694
|
+
}
|
|
695
|
+
}, fnFailure);
|
|
696
|
+
};
|
|
697
|
+
|
|
698
|
+
/**
|
|
699
|
+
* Returns the wrapper's base URL.
|
|
700
|
+
*
|
|
701
|
+
* @returns {string}
|
|
702
|
+
* base URL of the OData service, e.g. "/OData/OData.svc/"
|
|
703
|
+
*
|
|
704
|
+
* @public
|
|
705
|
+
* @since 1.19.0
|
|
706
|
+
*/
|
|
707
|
+
this.getBaseUrl = function () {
|
|
708
|
+
return sBaseUrl;
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Returns this wrapper's facade to an OData service (which was passed to the constructor
|
|
713
|
+
* {@link sap.ui2.srvc.ODataWrapper}).
|
|
714
|
+
*
|
|
715
|
+
* @returns {sap.ui2.srvc.ODataService}
|
|
716
|
+
* this wrapper's facade to an OData service.
|
|
717
|
+
*
|
|
718
|
+
* @public
|
|
719
|
+
* @since 1.19.1
|
|
720
|
+
*/
|
|
721
|
+
this.getODataService = function () {
|
|
722
|
+
return oODataService;
|
|
723
|
+
};
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Wraps the given generic OData failure handler. It processes the raw
|
|
727
|
+
* OData error response object, calls the given failure handler with an
|
|
728
|
+
* error message and, since version 1.28.6, an object containing additional
|
|
729
|
+
* technical details. If a Deferred object is given, it is rejected with
|
|
730
|
+
* the same arguments passed to the failure handler call.
|
|
731
|
+
*
|
|
732
|
+
* This method logs technical information to the console if this is
|
|
733
|
+
* available at the time the error occurs.
|
|
734
|
+
*
|
|
735
|
+
* @param {string} sMethod
|
|
736
|
+
* the HTTP method used in the OData request, e.g. "POST"
|
|
737
|
+
* @param {string} sRequestUrl
|
|
738
|
+
* the <b>absolute</b> URL the request is sent to
|
|
739
|
+
* @param {function (string, object=)} fnFailure
|
|
740
|
+
* the wrapped failure handler that will be called synchronously. The
|
|
741
|
+
* first parameter is a human-readable error message containing technical
|
|
742
|
+
* information, including sMethod and sRequestUrl; the second parameter
|
|
743
|
+
* is an <b>optional</b> object containing the complete error information
|
|
744
|
+
* returned in the <code>error</code> value contained in the body of the
|
|
745
|
+
* OData error response object, plus the HTTP response status code.
|
|
746
|
+
*
|
|
747
|
+
* For example, the returned error object has the following structure:
|
|
748
|
+
* <pre>
|
|
749
|
+
* {
|
|
750
|
+
* httpStatus: 404,
|
|
751
|
+
* // ... other keys and values from oError.response.body.error
|
|
752
|
+
* }
|
|
753
|
+
* </pre>
|
|
754
|
+
*
|
|
755
|
+
* Please refer to the documentation of the specific OData service used
|
|
756
|
+
* for details about keys and values returned in
|
|
757
|
+
* <code>oError.response.body.error</code>.<br />
|
|
758
|
+
*
|
|
759
|
+
* <b>IMPORTANT:</b> the second parameter may be undefined if the error
|
|
760
|
+
* cannot be parsed or is not returned in the OData error response.<br />
|
|
761
|
+
*
|
|
762
|
+
* <b>NOTE:</b> the second parameter is returned since version 1.28.6.
|
|
763
|
+
* @param {jQuery.Deferred} [oDeferred]
|
|
764
|
+
* a <code>jQuery.Deferred</code> object that will be rejected with the
|
|
765
|
+
* same arguments fnFailure is called
|
|
766
|
+
* @param {object} oError
|
|
767
|
+
* error object provided by datajs, should contain the response
|
|
768
|
+
*
|
|
769
|
+
* @public
|
|
770
|
+
* @since 1.19.0
|
|
771
|
+
*/
|
|
772
|
+
this.onError = function (sMethod, sRequestUrl, fnFailure, oDeferred, oError) {
|
|
773
|
+
var oParsedErrorInformation,
|
|
774
|
+
sMessage = "Error ";
|
|
775
|
+
|
|
776
|
+
if (oError.response && oError.response.statusCode) {
|
|
777
|
+
sMessage += "(" + oError.response.statusCode + ", " + oError.response.statusText + ") ";
|
|
778
|
+
}
|
|
779
|
+
sMessage += "in OData response for " + sMethod + ' "' + sRequestUrl + '": ' + oError.message;
|
|
780
|
+
|
|
781
|
+
if (oError.response && oError.response.body) {
|
|
782
|
+
|
|
783
|
+
try {
|
|
784
|
+
oParsedErrorInformation = JSON.parse(oError.response.body).error;
|
|
785
|
+
|
|
786
|
+
if (oParsedErrorInformation) {
|
|
787
|
+
|
|
788
|
+
if (oParsedErrorInformation.hasOwnProperty("message") &&
|
|
789
|
+
oParsedErrorInformation.message.hasOwnProperty("value")) {
|
|
790
|
+
sMessage += "\nDetails: " + oParsedErrorInformation.message.value;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
// NOTE: there was an agreement to not alter the data in
|
|
794
|
+
// oError.response.body.error (except from adding the status if
|
|
795
|
+
// it's not there already)
|
|
796
|
+
if (oError.response.statusCode && !oParsedErrorInformation.httpStatus) {
|
|
797
|
+
oParsedErrorInformation.httpStatus = oError.response.statusCode;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
} catch (ex) {
|
|
801
|
+
// do not rely on subtleties of error response, treat error details as optional
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
jQuery.sap.log.error(sMessage, JSON.stringify(oError.response),
|
|
806
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
807
|
+
|
|
808
|
+
if (oDeferred) {
|
|
809
|
+
oDeferred.reject(sMessage, oParsedErrorInformation);
|
|
810
|
+
}
|
|
811
|
+
fnFailure(sMessage, oParsedErrorInformation);
|
|
812
|
+
};
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Opens a new queue where all requests are parked until a call to {@link #submitBatchQueue}.
|
|
816
|
+
*
|
|
817
|
+
* @public
|
|
818
|
+
* @since 1.19.0
|
|
819
|
+
*
|
|
820
|
+
* @see #isBatchQueueOpen
|
|
821
|
+
* @see #submitBatchQueue
|
|
822
|
+
*/
|
|
823
|
+
this.openBatchQueue = function () {
|
|
824
|
+
if (aBatchQueue) {
|
|
825
|
+
throw new sap.ui2.srvc.Error("Batch queue already open", "sap.ui2.srvc.ODataWrapper");
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
aBatchQueue = [];
|
|
829
|
+
aDeferredQueue = [];
|
|
830
|
+
bChangeSetOpen = false;
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
/**
|
|
834
|
+
* Checks whether the queue of requests is already open or not
|
|
835
|
+
*
|
|
836
|
+
* @returns {boolean}
|
|
837
|
+
* true if batchQueue is already open
|
|
838
|
+
*
|
|
839
|
+
* @public
|
|
840
|
+
* @since 1.34.0
|
|
841
|
+
*
|
|
842
|
+
* @see #openBatchQueue
|
|
843
|
+
* @see #submitBatchQueue
|
|
844
|
+
*/
|
|
845
|
+
this.isBatchQueueOpen = function () {
|
|
846
|
+
return !!aBatchQueue;
|
|
847
|
+
};
|
|
848
|
+
|
|
849
|
+
/**
|
|
850
|
+
* Wrapper around
|
|
851
|
+
* <a href="http://datajs.codeplex.com/wikipage?title=datajs%20OData%20API#OData.read">
|
|
852
|
+
* <code>OData.read</code></a> which supports caching.
|
|
853
|
+
*
|
|
854
|
+
* @param {string} sRelativeUrl
|
|
855
|
+
* a string containing the <b>relative</b> URL w.r.t. this OData wrapper's base URL, e.g.
|
|
856
|
+
* "Products(1)"
|
|
857
|
+
* @param {function(object)} fnSuccess
|
|
858
|
+
* a callback function that is executed if the request succeeds, taking the processed data
|
|
859
|
+
* @param {function (string, object=)} [fnFailure]
|
|
860
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
861
|
+
* optional object containing the complete error information as delivered
|
|
862
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
863
|
+
* for more details.
|
|
864
|
+
* Defaults to the OData service facade's default error handler
|
|
865
|
+
* ({@link sap.ui2.srvc.ODataService#getDefaultErrorHandler})
|
|
866
|
+
* @param {boolean} [bCache=false]
|
|
867
|
+
* whether the response is cached for further calls (since 1.11.0) in
|
|
868
|
+
* <code>OData.read.$cache</code>, a <code>sap.ui2.srvc.Map</code> from
|
|
869
|
+
* <code>sRequestUrl</code> to a <code>jQuery.Deferred</code> object created on demand;
|
|
870
|
+
* without this flag, the cache is neither written nor read!
|
|
871
|
+
*
|
|
872
|
+
* @public
|
|
873
|
+
* @since 1.19.0
|
|
874
|
+
*/
|
|
875
|
+
this.read = function (sRelativeUrl, fnSuccess, fnFailure, bCache) {
|
|
876
|
+
var oDeferred,
|
|
877
|
+
sRequestUrl = toRequestUrl(sRelativeUrl),
|
|
878
|
+
sSapMessage;
|
|
879
|
+
|
|
880
|
+
/*
|
|
881
|
+
* Success handler for <code>OData.read</code>.
|
|
882
|
+
*/
|
|
883
|
+
function success (oData, oResponse) {
|
|
884
|
+
detectStickySession(oResponse.headers);
|
|
885
|
+
oODataService.setCsrfToken(
|
|
886
|
+
csrfTokenValue(oResponse.headers) || oODataService.getCsrfToken() // prefer a new token
|
|
887
|
+
);
|
|
888
|
+
jQuery.sap.log.debug('Received OData response for GET "' + sRequestUrl + '"', null,
|
|
889
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
890
|
+
// The sap-message header is a Gateway feature used e.g. by the INTEROP service
|
|
891
|
+
// It returns structured information (as XML). We don't evaluate it, we only log it.
|
|
892
|
+
// Severity is also part of the structure, but we simply assume warning.
|
|
893
|
+
sSapMessage = headerValue("sap-message", oResponse.headers);
|
|
894
|
+
if (sSapMessage) {
|
|
895
|
+
jQuery.sap.log.warning("SAP message for GET " + sRequestUrl, sSapMessage,
|
|
896
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
897
|
+
}
|
|
898
|
+
if (oDeferred) {
|
|
899
|
+
// put arguments for fnSuccess into cache; clone oData first
|
|
900
|
+
oDeferred.resolve(JSON.parse(JSON.stringify(oData)), oODataService.getCsrfToken());
|
|
901
|
+
}
|
|
902
|
+
// Note: drop excess parameters; try/catch
|
|
903
|
+
sap.ui2.srvc.call(fnSuccess.bind(null, oData), fnFailure);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
fnFailure = fnFailure || oODataService.getDefaultErrorHandler();
|
|
907
|
+
this.check(fnSuccess, fnFailure);
|
|
908
|
+
|
|
909
|
+
if (bCache) {
|
|
910
|
+
OData.read.$cache = OData.read.$cache || new sap.ui2.srvc.Map();
|
|
911
|
+
oDeferred = OData.read.$cache.get(sRequestUrl); // the promise is cached
|
|
912
|
+
if (oDeferred) {
|
|
913
|
+
jQuery.sap.log.debug('Using cached response for GET "' + sRequestUrl + '"', null,
|
|
914
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
915
|
+
oDeferred.done(function (oData, sCachedCsrfToken) {
|
|
916
|
+
// prefer our own token
|
|
917
|
+
oODataService.setCsrfToken(oODataService.getCsrfToken() || sCachedCsrfToken);
|
|
918
|
+
// clone cached oData before passing to success handler
|
|
919
|
+
// Note: try/catch
|
|
920
|
+
sap.ui2.srvc.call(fnSuccess.bind(null, JSON.parse(JSON.stringify(oData))), fnFailure);
|
|
921
|
+
}).fail(fnFailure);
|
|
922
|
+
return;
|
|
923
|
+
}
|
|
924
|
+
oDeferred = new jQuery.Deferred();
|
|
925
|
+
OData.read.$cache.put(sRequestUrl, oDeferred.promise());
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
readOrBatch(
|
|
929
|
+
sRelativeUrl,
|
|
930
|
+
success,
|
|
931
|
+
this.onError.bind(this, "GET", sRequestUrl, fnFailure, oDeferred)
|
|
932
|
+
);
|
|
933
|
+
};
|
|
934
|
+
|
|
935
|
+
/**
|
|
936
|
+
* Performs a batch request with the given payload.
|
|
937
|
+
*
|
|
938
|
+
* <b>Warning:</b> This bypasses the batch queue.
|
|
939
|
+
*
|
|
940
|
+
* @param {object} oPayload
|
|
941
|
+
* payload of the request (in intermediate format)
|
|
942
|
+
* @param {function(object)} [fnSuccess]
|
|
943
|
+
* callback function that is executed if the request succeeds, taking the processed data
|
|
944
|
+
* @param {function (string, object=)} [fnFailure]
|
|
945
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
946
|
+
* optional object containing the complete error information as delivered
|
|
947
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
948
|
+
* for more details.
|
|
949
|
+
* Defaults to the OData service facade's default error handler
|
|
950
|
+
* @private
|
|
951
|
+
*/
|
|
952
|
+
this.batch = function (oPayload, fnSuccess, fnFailure) {
|
|
953
|
+
var sRequestUrl = toRequestUrl("$batch");
|
|
954
|
+
|
|
955
|
+
doRequest(sRequestUrl, "POST", oPayload, fnSuccess, fnFailure, OData.batchHandler);
|
|
956
|
+
};
|
|
957
|
+
|
|
958
|
+
/**
|
|
959
|
+
* Submits the current batch queue opened by {@link #openBatchQueue} by sending a single
|
|
960
|
+
* "$batch" request to the OData service and deletes the current batch queue immediately.
|
|
961
|
+
*
|
|
962
|
+
* @param {function()} [fnBatchAccepted]
|
|
963
|
+
* A callback function that is executed if the batch request is accepted by the
|
|
964
|
+
* server, no matter whether individual operations fail. It will be called <b>after</b> all
|
|
965
|
+
* success or failure handlers of individual operations.
|
|
966
|
+
* @param {function(string, object=)} [fnBatchItselfFailed]
|
|
967
|
+
* A callback function that is executed if the batch request itself
|
|
968
|
+
* fails, error handler taking an error message and, since version
|
|
969
|
+
* 1.28.6, an optional object containing the complete error information
|
|
970
|
+
* as delivered by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
971
|
+
* for more details.<br />
|
|
972
|
+
*
|
|
973
|
+
* Defaults to the OData service facade's default
|
|
974
|
+
* error handler ({@link sap.ui2.srvc.ODataService#getDefaultErrorHandler}).<br />
|
|
975
|
+
*
|
|
976
|
+
* This is called <b>instead</b> of individual failure handlers in this case!
|
|
977
|
+
*
|
|
978
|
+
* @public
|
|
979
|
+
* @since 1.19.0
|
|
980
|
+
*
|
|
981
|
+
* @see #openBatchQueue
|
|
982
|
+
* @see #isBatchQueueOpen
|
|
983
|
+
*/
|
|
984
|
+
this.submitBatchQueue = function (fnBatchAccepted, fnBatchItselfFailed) {
|
|
985
|
+
/*jslint nomen:true */
|
|
986
|
+
var aMyDeferredQueue = aDeferredQueue; // used in closure below
|
|
987
|
+
|
|
988
|
+
/*
|
|
989
|
+
* Success handler for $batch request.
|
|
990
|
+
*
|
|
991
|
+
* @param {object} oData
|
|
992
|
+
*/
|
|
993
|
+
function onBatchSuccess (oData) {
|
|
994
|
+
var iActual = oData.__batchResponses.length,
|
|
995
|
+
iExpected = aMyDeferredQueue.length;
|
|
996
|
+
|
|
997
|
+
if (iExpected !== iActual) {
|
|
998
|
+
that.onError("POST", toRequestUrl("$batch"), fnBatchItselfFailed, /*oDeferred*/null, {
|
|
999
|
+
message: "Protocol error! Expected " + iExpected
|
|
1000
|
+
+ " responses, but received " + iActual
|
|
1001
|
+
});
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
oData.__batchResponses.forEach(function (oResponse, i) {
|
|
1006
|
+
// Note: "raw" success/failure signatures for all requests!
|
|
1007
|
+
var oDeferred = aMyDeferredQueue[i];
|
|
1008
|
+
if (oResponse.response) {
|
|
1009
|
+
// if it contains a nested response, it must be a failure
|
|
1010
|
+
reject(oDeferred, oResponse);
|
|
1011
|
+
} else if (oResponse.__changeResponses) {
|
|
1012
|
+
// successful change set
|
|
1013
|
+
oResponse.__changeResponses.forEach(function (oChangeResponse, j) {
|
|
1014
|
+
oDeferred[j].resolve(oChangeResponse.data, oChangeResponse);
|
|
1015
|
+
});
|
|
1016
|
+
} else {
|
|
1017
|
+
// successful GET request
|
|
1018
|
+
oDeferred.resolve(oResponse.data, oResponse);
|
|
1019
|
+
}
|
|
1020
|
+
});
|
|
1021
|
+
|
|
1022
|
+
if (fnBatchAccepted) {
|
|
1023
|
+
sap.ui2.srvc.call(fnBatchAccepted, oODataService.getDefaultErrorHandler());
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
if (!aBatchQueue) {
|
|
1028
|
+
throw new sap.ui2.srvc.Error("No open batch queue to submit", "sap.ui2.srvc.ODataWrapper");
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
if (aBatchQueue.length > 0) {
|
|
1032
|
+
this.batch({__batchRequests: aBatchQueue}, onBatchSuccess, fnBatchItselfFailed);
|
|
1033
|
+
} else if (fnBatchAccepted) {
|
|
1034
|
+
// call success handler (if given) directly (async) if batchQueue is empty
|
|
1035
|
+
sap.ui2.srvc.call(fnBatchAccepted, oODataService.getDefaultErrorHandler(), /*async=*/true);
|
|
1036
|
+
}
|
|
1037
|
+
|
|
1038
|
+
aBatchQueue = undefined;
|
|
1039
|
+
aDeferredQueue = undefined; // be nice to the garbage collector
|
|
1040
|
+
};
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* Returns this wrapper's string representation.
|
|
1044
|
+
*
|
|
1045
|
+
* @param {boolean} [bVerbose=false]
|
|
1046
|
+
* flag whether to show all properties
|
|
1047
|
+
* @returns {string}
|
|
1048
|
+
* this wrapper's string representation
|
|
1049
|
+
*
|
|
1050
|
+
* @public
|
|
1051
|
+
* @since 1.19.0
|
|
1052
|
+
*/
|
|
1053
|
+
this.toString = function (bVerbose) {
|
|
1054
|
+
var aResult = ['sap.ui2.srvc.ODataWrapper({sBaseUrl:"', sBaseUrl, '"'];
|
|
1055
|
+
// if (bVerbose) {
|
|
1056
|
+
// }
|
|
1057
|
+
aResult.push("})");
|
|
1058
|
+
return aResult.join("");
|
|
1059
|
+
};
|
|
1060
|
+
|
|
1061
|
+
/** executes a put request
|
|
1062
|
+
*
|
|
1063
|
+
* @param {string} sRelativeUrl the relative URL to use
|
|
1064
|
+
* @param {object} oPayload the payload
|
|
1065
|
+
* @param {function ()} [fnSuccess]
|
|
1066
|
+
* callback function that is executed if the request succeeds, taking no data
|
|
1067
|
+
* @param {function (string, object=)} [fnFailure]
|
|
1068
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
1069
|
+
* optional object containing the complete error information as delivered
|
|
1070
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
1071
|
+
* for more details.
|
|
1072
|
+
* Defaults to the OData service facade's default error handler
|
|
1073
|
+
*/
|
|
1074
|
+
this.put = function (sRelativeUrl, oPayload, fnSuccess, fnFailure) {
|
|
1075
|
+
requestOrBatch(sRelativeUrl, "PUT", oPayload, function (oData) {
|
|
1076
|
+
if (fnSuccess) {
|
|
1077
|
+
// Note: try/catch already done by doRequest()
|
|
1078
|
+
fnSuccess(); // drop excess parameters (oData === undefined)
|
|
1079
|
+
}
|
|
1080
|
+
}, fnFailure);
|
|
1081
|
+
};
|
|
1082
|
+
/**
|
|
1083
|
+
* Generic entity update method.
|
|
1084
|
+
*
|
|
1085
|
+
* @param {object} oEntity
|
|
1086
|
+
* the datajs representation of the entity
|
|
1087
|
+
* @param {function ()} [fnSuccess]
|
|
1088
|
+
* callback function that is executed if the request succeeds, taking no data
|
|
1089
|
+
* @param {function (string, object=)} [fnFailure]
|
|
1090
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
1091
|
+
* optional object containing the complete error information as delivered
|
|
1092
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
1093
|
+
* for more details.
|
|
1094
|
+
* Defaults to the OData service facade's default error handler
|
|
1095
|
+
*
|
|
1096
|
+
* @public
|
|
1097
|
+
* @since 1.19.0
|
|
1098
|
+
*/
|
|
1099
|
+
this.update = function (oEntity, fnSuccess, fnFailure) {
|
|
1100
|
+
/*jslint nomen:true */
|
|
1101
|
+
var oPayload = {
|
|
1102
|
+
__metadata: {
|
|
1103
|
+
type: oEntity.__metadata && oEntity.__metadata.type
|
|
1104
|
+
}
|
|
1105
|
+
},
|
|
1106
|
+
sPropertyName,
|
|
1107
|
+
sRelativeUrl = toRelativeUrl(oEntity.__metadata.uri);
|
|
1108
|
+
|
|
1109
|
+
// copy all original property values of entity into request data
|
|
1110
|
+
for (sPropertyName in oEntity) {
|
|
1111
|
+
if (Object.prototype.hasOwnProperty.call(oEntity, sPropertyName)
|
|
1112
|
+
&& sPropertyName.indexOf("$") !== 0
|
|
1113
|
+
&& typeof oEntity[sPropertyName] !== "object") {
|
|
1114
|
+
oPayload[sPropertyName] = oEntity[sPropertyName];
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
this.put(sRelativeUrl, oPayload, fnSuccess, fnFailure);
|
|
1118
|
+
};
|
|
1119
|
+
|
|
1120
|
+
// constructor code -------------------------------------------------------
|
|
1121
|
+
if (!sap.ui2.srvc.Map) {
|
|
1122
|
+
fnRequire("sap.ui2.srvc.utils");
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
// Detect old API and transform it to the current one
|
|
1126
|
+
if (typeof oSettings === "string") {
|
|
1127
|
+
oSettings = handleOldConstructorApi(arguments);
|
|
1128
|
+
} else if (typeof oSettings === "object") {
|
|
1129
|
+
// clone to ensure it is not changed afterwards
|
|
1130
|
+
oSettings = cloneObject(oSettings);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
if (!oSettings || !oSettings.baseUrl || typeof oSettings.baseUrl !== "string") {
|
|
1134
|
+
throw new sap.ui2.srvc.Error("Missing base URL", "sap.ui2.srvc.ODataWrapper");
|
|
1135
|
+
}
|
|
1136
|
+
if (!oODataService || typeof oODataService !== "object") {
|
|
1137
|
+
throw new sap.ui2.srvc.Error("Missing OData service facade", "sap.ui2.srvc.ODataWrapper");
|
|
1138
|
+
}
|
|
1139
|
+
|
|
1140
|
+
// ensure that base URL has a trailing /
|
|
1141
|
+
oSettings.baseUrl = oSettings.baseUrl.replace(/\/$/, "") + "/";
|
|
1142
|
+
|
|
1143
|
+
sBaseUrl = oSettings.baseUrl;
|
|
1144
|
+
bSupportsChangeSets = oSettings.supportsChangeSets;
|
|
1145
|
+
|
|
1146
|
+
if (typeof sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration === "undefined") {
|
|
1147
|
+
jQuery.sap.log.error("sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration is not defined!",
|
|
1148
|
+
"the sap.ui2.srvc.ODataWrapper constructor was called before the static property was defined",
|
|
1149
|
+
"sap.ui2.srvc.ODataWrapper");
|
|
1150
|
+
} else if (typeof sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration[sBaseUrl] === "undefined") {
|
|
1151
|
+
|
|
1152
|
+
// Define the sticky session configuration for the base URL managed by
|
|
1153
|
+
// this ODataWrapper instance.
|
|
1154
|
+
sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration[sBaseUrl] = {
|
|
1155
|
+
enabled: false, // sticky session disabled by default
|
|
1156
|
+
value: undefined // the value detected if enabled = true
|
|
1157
|
+
};
|
|
1158
|
+
}
|
|
1159
|
+
};
|
|
1160
|
+
|
|
1161
|
+
/**
|
|
1162
|
+
* Detects and, if needed, converts old api calls of the createODataWrapper function to the current one.
|
|
1163
|
+
* @param {object} oArgs
|
|
1164
|
+
* An arguments object containing the parameters of the createODataWrapper function. See createODataWrapper for details
|
|
1165
|
+
* @returns {object}
|
|
1166
|
+
* Settings for ODataWrapper and default failure function
|
|
1167
|
+
* @private
|
|
1168
|
+
*/
|
|
1169
|
+
function handleOldCreateODataWrapperApi (oArgs) {
|
|
1170
|
+
var oSettings = {};
|
|
1171
|
+
var oTransformedApi = {};
|
|
1172
|
+
|
|
1173
|
+
oSettings.baseUrl = oArgs[0];
|
|
1174
|
+
// These are non mandatory parameters and might be undefined
|
|
1175
|
+
if (typeof oArgs[1] === "boolean") {
|
|
1176
|
+
oSettings.supportsChangeSets = oArgs[1];
|
|
1177
|
+
}
|
|
1178
|
+
if (typeof oArgs[2] === "function") {
|
|
1179
|
+
oTransformedApi.defaultFailure = oArgs[2];
|
|
1180
|
+
}
|
|
1181
|
+
oTransformedApi.settings = oSettings;
|
|
1182
|
+
|
|
1183
|
+
return oTransformedApi;
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
/**
|
|
1187
|
+
* Clones an Object to avoid unwanted changes
|
|
1188
|
+
* @param {object} oInputObject
|
|
1189
|
+
* The object that needs to be cloned
|
|
1190
|
+
* @returns {object}
|
|
1191
|
+
* The cloned object
|
|
1192
|
+
* @private
|
|
1193
|
+
*/
|
|
1194
|
+
function cloneObject (oInputObject) {
|
|
1195
|
+
if (oInputObject === undefined) {
|
|
1196
|
+
return undefined;
|
|
1197
|
+
}
|
|
1198
|
+
try {
|
|
1199
|
+
return JSON.parse(JSON.stringify(oInputObject));
|
|
1200
|
+
} catch (e) {
|
|
1201
|
+
return undefined;
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
|
|
1205
|
+
/*
|
|
1206
|
+
* Configuration for sticky session is done here as it is a static property
|
|
1207
|
+
* that should not rely on the instance initialization. Also, it may happen
|
|
1208
|
+
* that an already defined sap.ui2.srvc.ODataWrapper name is re-assigned
|
|
1209
|
+
* because this file is re-executed or re-loaded. Such a scenario may be
|
|
1210
|
+
* possible if this file is required twice (after being registered to two
|
|
1211
|
+
* different module paths).
|
|
1212
|
+
*/
|
|
1213
|
+
if (typeof sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration === "undefined") {
|
|
1214
|
+
sap.ui2.srvc.ODataWrapper.oStickySessionConfiguration = {};
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
// public factory function ***************************************************
|
|
1218
|
+
|
|
1219
|
+
/**
|
|
1220
|
+
* Checks the sap-statistics setting form UI5's configuration and set it on the ODataWrapper.
|
|
1221
|
+
* If UI5 is not available, it is checked if the sap-statistics query parameter is set.
|
|
1222
|
+
* Note: this function is directly executed
|
|
1223
|
+
* @param {string} getWindowLocationSearch
|
|
1224
|
+
* value of window.location.search; to be able to test the behavior of this method with
|
|
1225
|
+
* different search strings.
|
|
1226
|
+
* @private
|
|
1227
|
+
*/
|
|
1228
|
+
sap.ui2.srvc.testPublishAt(sap.ui2.srvc.ODataWrapper);
|
|
1229
|
+
function checkSapStatisticsSetting (sWindowLocationSearch) {
|
|
1230
|
+
try {
|
|
1231
|
+
// read the value from UI5 as it may be set via [CTRL-SHIFT-ALT-P]
|
|
1232
|
+
sap.ui2.srvc.ODataWrapper["sap-statistics"] =
|
|
1233
|
+
sap.ui.getCore().getConfiguration().getStatistics();
|
|
1234
|
+
} catch (e) {
|
|
1235
|
+
// Read sap-statistics directly form query parameter in scenarios without UI5
|
|
1236
|
+
sap.ui2.srvc.ODataWrapper["sap-statistics"] =
|
|
1237
|
+
/sap-statistics=(true|x|X)/.test(sWindowLocationSearch);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1240
|
+
// call function directly (immediate function pattern will break testPublishAt)
|
|
1241
|
+
checkSapStatisticsSetting(window.location.search);
|
|
1242
|
+
|
|
1243
|
+
/**
|
|
1244
|
+
* Constructs and returns a {@link sap.ui2.srvc.ODataWrapper} which knows its
|
|
1245
|
+
* {@link sap.ui2.srvc.ODataService} twin, see {@link sap.ui2.srvc.ODataWrapper#getODataService}.
|
|
1246
|
+
*
|
|
1247
|
+
* @param {object} oSettings
|
|
1248
|
+
* An object containing various properties:
|
|
1249
|
+
* <pre>
|
|
1250
|
+
* {
|
|
1251
|
+
* baseUrl: "/OData/OData.svc", // Mandatory base URL of the OData service
|
|
1252
|
+
* supportsChangeSets: false, // Type: boolean, Default: false
|
|
1253
|
+
* // Whether the OData service supports change sets with <b>multiple</b>
|
|
1254
|
+
* // operations bundled into a single logical unit of work. Otherwise
|
|
1255
|
+
* // each modifying operation is isolated in a change set of its own.
|
|
1256
|
+
* "sap-language": "EN", // header which is set for all requests sent
|
|
1257
|
+
* "sap-client": 120, // header which is set for all requests sent
|
|
1258
|
+
* "sap-statistics": true // header which is set for all requests sent; in order to receive
|
|
1259
|
+
* // some performance statistics
|
|
1260
|
+
* }
|
|
1261
|
+
* </pre>
|
|
1262
|
+
* @param {function (string, object=)} [fnDefaultFailure]
|
|
1263
|
+
* error handler taking an error message and, since version 1.28.6, an
|
|
1264
|
+
* optional object containing the complete error information as delivered
|
|
1265
|
+
* by the ODataService. See fnFailure parameter of {@link sap.ui2.srvc.ODataWrapper#onError}
|
|
1266
|
+
* for more details.
|
|
1267
|
+
* @returns {sap.ui2.srvc.ODataWrapper}
|
|
1268
|
+
* new instance of ODataWapper/ODataService
|
|
1269
|
+
*
|
|
1270
|
+
* @public
|
|
1271
|
+
* @since 1.19.1
|
|
1272
|
+
*/
|
|
1273
|
+
// OLD API: function (sBaseUrl, bSupportsChangeSets, fnDefaultFailure)
|
|
1274
|
+
sap.ui2.srvc.createODataWrapper = function (oSettings, fnDefaultFailure) {
|
|
1275
|
+
// If old API is used we need to transform it to the current one.
|
|
1276
|
+
if (typeof arguments[0] === "string") {
|
|
1277
|
+
var oTransformedApi = handleOldCreateODataWrapperApi(arguments);
|
|
1278
|
+
oSettings = oTransformedApi.settings;
|
|
1279
|
+
if (oTransformedApi.defaultFailure) {
|
|
1280
|
+
fnDefaultFailure = oTransformedApi.defaultFailure;
|
|
1281
|
+
}
|
|
1282
|
+
} else if (typeof arguments[0] === "object") {
|
|
1283
|
+
// clone to ensure it is not changed afterwards
|
|
1284
|
+
oSettings = cloneObject(oSettings);
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
function Service () {
|
|
1288
|
+
var oWrapper = new sap.ui2.srvc.ODataWrapper(oSettings, this);
|
|
1289
|
+
fnRequire("sap.ui2.srvc.ODataService");
|
|
1290
|
+
sap.ui2.srvc.ODataService.call(this, oWrapper, fnDefaultFailure);
|
|
1291
|
+
return oWrapper;
|
|
1292
|
+
}
|
|
1293
|
+
|
|
1294
|
+
return new Service(); // BEWARE: this actually _returns_ the wrapper, not the service!
|
|
1295
|
+
};
|
|
1296
|
+
/// @end
|
|
1297
|
+
}());
|