@sapui5/sap.ushell_abap 1.94.0 → 1.96.1

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.
Files changed (115) hide show
  1. package/package.json +1 -1
  2. package/src/main/js/sap/ui2/srvc/ODataWrapper.js +1 -1
  3. package/src/main/js/sap/ushell_abap/.library +4 -9
  4. package/src/main/js/sap/ushell_abap/adapters/abap/AdapterContainer.js +12 -5
  5. package/src/main/js/sap/ushell_abap/adapters/abap/AppStateAdapter.js +11 -7
  6. package/src/main/js/sap/ushell_abap/adapters/abap/ClientSideTargetResolutionAdapter.js +47 -32
  7. package/src/main/js/sap/ushell_abap/adapters/abap/ConfigurationDefaultsAdapter.js +1 -1
  8. package/src/main/js/sap/ushell_abap/adapters/abap/ContainerAdapter.js +46 -38
  9. package/src/main/js/sap/ushell_abap/adapters/abap/LaunchPageAdapter.js +438 -398
  10. package/src/main/js/sap/ushell_abap/adapters/abap/NavTargetResolutionAdapter.js +1 -1
  11. package/src/main/js/sap/ushell_abap/adapters/abap/PageBuildingAdapter.js +25 -15
  12. package/src/main/js/sap/ushell_abap/adapters/abap/PagePersistenceAdapter.js +3 -2
  13. package/src/main/js/sap/ushell_abap/adapters/abap/PersonalizationAdapter.js +16 -7
  14. package/src/main/js/sap/ushell_abap/adapters/abap/SearchAdapter.js +1 -1
  15. package/src/main/js/sap/ushell_abap/adapters/abap/SupportTicketAdapter.js +8 -8
  16. package/src/main/js/sap/ushell_abap/adapters/abap/Ui5ComponentLoaderAdapter.js +1 -1
  17. package/src/main/js/sap/ushell_abap/adapters/abap/UserInfoAdapter.js +11 -4
  18. package/src/main/js/sap/ushell_abap/adapters/hana/ContainerAdapter.js +9 -3
  19. package/src/main/js/sap/ushell_abap/bootstrap/evo/XhrLogonEventHandler.js +13 -11
  20. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap-def-dev.js +1 -1
  21. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap-def.js +1 -1
  22. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.bootstrap.utils.js +8 -4
  23. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.configure.ushell.js +1 -1
  24. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.constants.js +9 -0
  25. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.get.server.config.Urls.js +12 -5
  26. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.load.launchpad.js +21 -22
  27. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.pageset.js +8 -2
  28. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.server.config.js +6 -3
  29. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.request.startup.js +10 -5
  30. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.ui5.boot.handler.js +7 -4
  31. package/src/main/js/sap/ushell_abap/bootstrap/evo/abap.xhr.handler.js +10 -3
  32. package/src/main/js/sap/ushell_abap/bootstrap/evo/boottask.js +21 -16
  33. package/src/main/js/sap/ushell_abap/library.js +2 -2
  34. package/src/main/js/sap/ushell_abap/pbServices/ui2/AllCatalogs.js +186 -0
  35. package/src/main/js/sap/ushell_abap/pbServices/ui2/Bag.js +704 -0
  36. package/src/main/js/sap/ushell_abap/pbServices/ui2/Catalog.js +930 -0
  37. package/src/main/js/sap/ushell_abap/pbServices/ui2/Chip.js +1027 -0
  38. package/src/main/js/sap/ushell_abap/pbServices/ui2/ChipDefinition.js +216 -0
  39. package/src/main/js/sap/ushell_abap/pbServices/ui2/ChipInstance.js +933 -0
  40. package/src/main/js/sap/ushell_abap/pbServices/ui2/Error.js +45 -0
  41. package/src/main/js/sap/ushell_abap/pbServices/ui2/Factory.js +647 -0
  42. package/src/main/js/sap/ushell_abap/pbServices/ui2/ODataService.js +251 -0
  43. package/src/main/js/sap/ushell_abap/pbServices/ui2/ODataWrapper.js +1262 -0
  44. package/src/main/js/sap/ushell_abap/pbServices/ui2/Page.js +920 -0
  45. package/src/main/js/sap/ushell_abap/pbServices/ui2/PageBuildingService.js +1498 -0
  46. package/src/main/js/sap/ushell_abap/pbServices/ui2/PageSet.js +466 -0
  47. package/src/main/js/sap/ushell_abap/pbServices/ui2/RemoteCatalogService.js +52 -0
  48. package/src/main/js/sap/ushell_abap/pbServices/ui2/Utils.js +767 -0
  49. package/src/main/js/sap/ushell_abap/pbServices/ui2/chipdefinition.xsd +139 -0
  50. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/actions.js +244 -0
  51. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/bag.js +150 -0
  52. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/configuration.js +165 -0
  53. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/configurationUi.js +330 -0
  54. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/fullscreen.js +70 -0
  55. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/navigation.js +50 -0
  56. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/preview.js +289 -0
  57. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/refresh.js +43 -0
  58. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/search.js +115 -0
  59. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/types.js +9 -0
  60. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/url.js +105 -0
  61. package/src/main/js/sap/ushell_abap/pbServices/ui2/contracts/visible.js +128 -0
  62. package/ui5.yaml +30 -0
  63. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/Component.js +0 -426
  64. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/css/style.css +0 -1
  65. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n.properties +0 -56
  66. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ar.properties +0 -36
  67. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_bg.properties +0 -36
  68. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ca.properties +0 -36
  69. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_cs.properties +0 -36
  70. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_cy.properties +0 -36
  71. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_da.properties +0 -36
  72. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_de.properties +0 -36
  73. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_el.properties +0 -36
  74. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_en.properties +0 -36
  75. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_en_GB.properties +0 -36
  76. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_en_US_sappsd.properties +0 -36
  77. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_en_US_saprigi.properties +0 -36
  78. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_en_US_saptrc.properties +0 -36
  79. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_es.properties +0 -36
  80. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_es_MX.properties +0 -36
  81. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_et.properties +0 -36
  82. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_fi.properties +0 -36
  83. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_fr.properties +0 -36
  84. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_fr_CA.properties +0 -36
  85. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_hi.properties +0 -36
  86. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_hr.properties +0 -36
  87. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_hu.properties +0 -36
  88. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_id.properties +0 -36
  89. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_it.properties +0 -36
  90. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_iw.properties +0 -36
  91. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ja.properties +0 -36
  92. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_kk.properties +0 -36
  93. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ko.properties +0 -36
  94. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_lt.properties +0 -36
  95. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_lv.properties +0 -36
  96. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ms.properties +0 -36
  97. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_nl.properties +0 -36
  98. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_no.properties +0 -36
  99. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_pl.properties +0 -36
  100. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_pt.properties +0 -36
  101. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_pt_PT.properties +0 -36
  102. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ro.properties +0 -36
  103. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_ru.properties +0 -36
  104. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_sh.properties +0 -36
  105. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_sk.properties +0 -36
  106. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_sl.properties +0 -36
  107. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_sv.properties +0 -36
  108. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_th.properties +0 -36
  109. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_tr.properties +0 -36
  110. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_uk.properties +0 -36
  111. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_vi.properties +0 -36
  112. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_zh_CN.properties +0 -36
  113. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/i18n/i18n_zh_TW.properties +0 -36
  114. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/manifest.json +0 -153
  115. package/src/main/js/sap/ushell_abap/plugins/fcc-transport-ui/model/models.js +0 -14
@@ -0,0 +1,1498 @@
1
+ // Copyright (c) 2009-2021 SAP SE. All rights reserved.
2
+
3
+ /**
4
+ * @fileOverview A facade to the page building service, providing all needed
5
+ * CRUD operations based on OData4SAP for the entities page, catalog, CHIP,
6
+ * and CHIP instance.
7
+ */
8
+ sap.ui.define([
9
+ "sap/ushell_abap/pbServices/ui2/Utils",
10
+ "sap/ushell_abap/pbServices/ui2/ODataService",
11
+ "sap/ushell_abap/pbServices/ui2/ODataWrapper",
12
+ "sap/ushell_abap/pbServices/ui2/Error"
13
+ ], function (
14
+ Utils,
15
+ ODataService,
16
+ ODataWrapper,
17
+ SrvcError
18
+ ) {
19
+ "use strict";
20
+
21
+ /* global OData */
22
+
23
+ // "public class" ************************************************************
24
+
25
+ /**
26
+ * Constructs a facade to the page building service with the given
27
+ * base URI, providing all needed CRUD operations based on OData for the
28
+ * entities page, catalog, bag, CHIP, and CHIP instance.
29
+ * <p>
30
+ * <strong>Ensure that datajs library is available at runtime</strong>. If
31
+ * SAPUI5 is available this script automatically imports their datajs implementation.
32
+ * <p>
33
+ * This facade automatically takes care of Gateway's CSRF protection mechanism
34
+ * via a token. Please perform a read request first, because read requests acquire this token.
35
+ * Otherwise write requests will have fail on first attempt, but automatically acquire this token
36
+ * via reading the service document before repeating the write request. This is a slight
37
+ * performance penalty.
38
+ * <p>
39
+ * The objects returned by this facade are <strong>de-serialized JSON representations</strong>
40
+ * of the entities in question, as converted from the OData's response by datajs.
41
+ * They may be decorated with new properties as long as the property names start with a dollar
42
+ * symbol ("$"). This is needed to tell original properties and decorations apart for the purpose
43
+ * of update operations.
44
+ *
45
+ * @param {string|ODataWrapper} vODataBase
46
+ * either the base URI of the page building service or (since 1.19.0) a corresponding
47
+ * <code>ODataWrapper</code>
48
+ * @param {function (string, object=)} [fnDefaultFailure]
49
+ * error handler taking an error message and, since version 1.28.6, an
50
+ * optional object containing the complete error information as delivered
51
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
52
+ * for more details.
53
+ * @param {boolean} [bIsPersonalization=false]
54
+ * defines the return value of {@link #isPersonalization}; nothing else (since 1.16.1)
55
+ *
56
+ * @class
57
+ * @augments ODataService
58
+ * @since 1.2.0
59
+ */
60
+ var PageBuildingService = function (vODataBase, fnDefaultFailure, bIsPersonalization) {
61
+ var oWrapper,
62
+ that = this;
63
+
64
+ // BEWARE: constructor code below!
65
+
66
+ // "private" methods -------------------------------------------------------
67
+ /**
68
+ * Encodes a sting to be used in an OData $filter parameter.
69
+ *
70
+ * @param {string} sString
71
+ * string to be encoded.
72
+ * @returns {string}
73
+ * the encoded string
74
+ * @public
75
+ * @since 1.28.0
76
+ */
77
+ function encodeODataFilterValue (sString) {
78
+ return sString.replace(/'/g, "''").replace(/&/g, "%26");
79
+ }
80
+
81
+ /**
82
+ * Returns the URL for accessing a bag.
83
+ *
84
+ * @param {string|object} vParent
85
+ * ID of the page or parent object (either page or page CHIP instance; must be the result
86
+ * of a previous create or read operation) of the bag to be read
87
+ * @param {string} sBagId
88
+ * the bag ID
89
+ * @param {boolean} bExpand
90
+ * tells if the properties of the bag should be expanded in the OData call
91
+ * @returns {string}
92
+ * relative(!) URL
93
+ *
94
+ * @private
95
+ */
96
+ function getBagUrl (vParent, sBagId, bExpand) {
97
+ var sPageId;
98
+
99
+ if (typeof vParent === "string") {
100
+ // for backwards compatibility, allow passing page ID
101
+ sPageId = vParent;
102
+ } else {
103
+ if (vParent.instanceId) {
104
+ // parent is a CHIP instance
105
+ return "ChipInstanceBags(pageId='" + encodeURIComponent(vParent.pageId)
106
+ + "',instanceId='" + encodeURIComponent(vParent.instanceId)
107
+ + "',id='" + encodeURIComponent(sBagId) + "')"
108
+ + (bExpand ? "?$expand=ChipInstanceProperties" : "");
109
+ }
110
+ // parent is a page
111
+ sPageId = vParent.id;
112
+ }
113
+ return "Bags(pageId='" + encodeURIComponent(sPageId)
114
+ + "',id='" + encodeURIComponent(sBagId) + "')"
115
+ + (bExpand ? "?$expand=Properties" : "");
116
+ }
117
+
118
+ /**
119
+ * Evaluates status code from OData batch response entry and returns the corresponding OData
120
+ * entity or the status message.
121
+ * @param oEntry The batch response entry which is an element of
122
+ * (For change) oData.__batchResponses[0]._changeResponses array
123
+ * (For read) oData.__batchResponses array (without the element for change responses)
124
+ * @returns OData entity (object or undefined) or status message as string
125
+ *
126
+ * @private
127
+ */
128
+ PageBuildingService.extractBatchResponseEntry = function (oEntry) {
129
+ if (oEntry.statusCode === "201") {
130
+ // POST was ok, return the new entity
131
+ return oEntry.data;
132
+ }
133
+ if (oEntry.statusCode === "204") {
134
+ // PUT or DELETE was ok, return nothing
135
+ return undefined;
136
+ }
137
+ // request failed, return error message or empty string
138
+ return oEntry.message || "";
139
+ };
140
+
141
+ /**
142
+ * Sends a batch request to the OData server. The batch request contains a
143
+ * sequence of change requests (PUT, POST) contained in a single changeset.
144
+ *
145
+ * @param {array} [aChangeRequests=[]]
146
+ * array of objects representing the change requests as specified by datajs. See
147
+ * <a href="http://datajs.codeplex.com/wikipage?title=OData%20Code%20Snippets&referringTitle=Documentation">
148
+ * datajs batch coding sample</a> and
149
+ * <a href="http://datajs.codeplex.com/wikipage?title=OData%20Payload%20Formats#Batch Requests">
150
+ * datajs payload format for batch</a>
151
+ * @param {array} [aGetRequests]
152
+ * array of objects representing the read requests as specified by datajs
153
+ * @param {function(array,array)} [fnSuccess]
154
+ * a callback function that is executed if the request succeeds, taking
155
+ * an array of response objects with responses for each change request
156
+ * and an array with responses for each read request. For a successful
157
+ * POST, the response object is the new entity, for a successful PUT it
158
+ * is undefined and for a successful GET it is the entity returned. For a
159
+ * failed request it is the corresponding error message.
160
+ * @param {function (string, object=)} [fnFailure]
161
+ * error handler taking an error message and, since version 1.28.6, an
162
+ * optional object containing the complete error information as delivered
163
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
164
+ * for more details.
165
+ * @private
166
+ * @deprecated Used only by {@link PageBuildingService#updateBagProperties}.
167
+ */
168
+ this.batch = function (aChangeRequests, aGetRequests, fnSuccess, fnFailure) {
169
+ /*jslint nomen:true */
170
+ var aRequests = [];
171
+
172
+ function extract (aResponses) {
173
+ var i, aResult = [];
174
+
175
+ for (i = 0; i < aResponses.length; i += 1) {
176
+ aResult[i] = PageBuildingService.extractBatchResponseEntry(aResponses[i]);
177
+ }
178
+ return aResult;
179
+ }
180
+
181
+ fnSuccess = fnSuccess || function () { /* null object pattern */ };
182
+ fnFailure = fnFailure || that.getDefaultErrorHandler();
183
+ oWrapper.check(fnSuccess, fnFailure);
184
+
185
+ aChangeRequests = aChangeRequests || [];
186
+ aGetRequests = aGetRequests || [];
187
+ if (aChangeRequests.length > 0) {
188
+ aRequests.push({ __changeRequests: aChangeRequests });
189
+ }
190
+ aRequests = aRequests.concat(aGetRequests);
191
+ if (aRequests.length === 0) {
192
+ Utils.callHandler(fnSuccess.bind(null, [], []), fnFailure, true);
193
+ return;
194
+ }
195
+ oWrapper.batch({ __batchRequests: aRequests },
196
+ function (oData) {
197
+ var aBatchResponses = oData.__batchResponses,
198
+ aChangeResponses = aBatchResponses[0].__changeResponses;
199
+
200
+ if (aBatchResponses[0].response && aBatchResponses[0].message) { // error
201
+ oWrapper.onError("POST", oWrapper.getBaseUrl() + "$batch", fnFailure, undefined,
202
+ oData.__batchResponses[0]);
203
+ return;
204
+ }
205
+ if ((aChangeResponses && (aChangeResponses.length !== aChangeRequests.length))
206
+ || (aBatchResponses.length !== aRequests.length)) {
207
+ fnFailure("Number of requests differs from number of responses in $batch");
208
+ return;
209
+ }
210
+ if (aChangeResponses) { // change requests and (maybe) additional read requests
211
+ Utils.callHandler(
212
+ fnSuccess.bind(null, extract(aChangeResponses), extract(aBatchResponses.slice(1))),
213
+ fnFailure,
214
+ false
215
+ );
216
+ } else { //read requests only
217
+ Utils.callHandler(
218
+ fnSuccess.bind(null, [], extract(aBatchResponses)),
219
+ fnFailure,
220
+ false
221
+ );
222
+ }
223
+ },
224
+ fnFailure);
225
+ };
226
+
227
+ // "public" methods --------------------------------------------------------
228
+
229
+ /**
230
+ * Tells whether this facade is reading from and writing to the "PERSONALIZATION" scope.
231
+ *
232
+ * @returns {boolean}
233
+ * whether this facade is reading from and writing to the "PERSONALIZATION" scope
234
+ * @since 1.16.1
235
+ */
236
+ this.isPersonalization = function () {
237
+ return !!bIsPersonalization;
238
+ };
239
+
240
+ /**
241
+ * Reads the metadata document of the page building service.
242
+ *
243
+ * @param {function (object)} fnSuccess
244
+ * a callback function that is executed if the request succeeds, taking
245
+ * the processed data
246
+ * @param {function (string, object=)} [fnFailure]
247
+ * error handler taking an error message and, since version 1.28.6, an
248
+ * optional object containing the complete error information as delivered
249
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
250
+ * for more details.
251
+ * @param {boolean} bNoCache
252
+ * (since 1.5.0) whether to avoid caching
253
+ * @since 1.2.0
254
+ *
255
+ * @deprecated Since 1.17.0 it is no longer necessary to fetch a CSRF token first; this is
256
+ * done automatically.
257
+ */
258
+ this.readMetadata = function (fnSuccess, fnFailure, bNoCache) {
259
+ var sRequestUrl = oWrapper.getBaseUrl() + "$metadata" + (bNoCache ? "?" + Date.now() : "");
260
+
261
+ fnFailure = fnFailure || this.getDefaultErrorHandler();
262
+ oWrapper.check(fnSuccess, fnFailure);
263
+
264
+ OData.read(sRequestUrl, function (oData) {
265
+ // Note: drop excess parameters; try/catch
266
+ Utils.callHandler(fnSuccess.bind(null, oData), fnFailure);
267
+ }, oWrapper.onError.bind(oWrapper, "GET", sRequestUrl, fnFailure, /*oDeferred*/undefined),
268
+ OData.metadataHandler);
269
+ };
270
+
271
+ /**
272
+ * Deletes the bag with given IDs.
273
+ * It is not an error if the bag does not exist.
274
+ *
275
+ * @param {string|object} vParent
276
+ * ID of the page or parent object (either page or page CHIP instance; must be the result
277
+ * of a previous create or read operation) of the bag to be deleted
278
+ * @param {string} sBagId
279
+ * ID of the bag to be deleted
280
+ * @param {function ()} [fnSuccess]
281
+ * a callback function that is executed if delete succeeds, taking no data
282
+ * @param {function (string, object=)} [fnFailure]
283
+ * error handler taking an error message and, since version 1.28.6, an
284
+ * optional object containing the complete error information as delivered
285
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
286
+ * for more details.
287
+ * @since 1.3.0
288
+ */
289
+ this.deleteBag = function (vParent, sBagId, fnSuccess, fnFailure) {
290
+ if (!vParent) {
291
+ throw new SrvcError("Missing parent ID or object",
292
+ "PageBuildingService");
293
+ }
294
+ if (!sBagId) {
295
+ throw new SrvcError("Missing bag ID", "PageBuildingService");
296
+ }
297
+
298
+ oWrapper.del(getBagUrl(vParent, sBagId, false), fnSuccess, fnFailure);
299
+ };
300
+
301
+ /**
302
+ * Reads the bag with the given IDs.
303
+ *
304
+ * @param {string|object} vParent
305
+ * ID of the page or parent object (either page or page CHIP instance; must be the result
306
+ * of a previous create or read operation) of the bag to be read
307
+ * @param {string} sBagId
308
+ * ID of the bag to be read. If the bag does not exist the error handler will be called.
309
+ * @param {function (object)} fnSuccess
310
+ * a callback function that is executed if the request succeeds, taking the processed data
311
+ * @param {function (string, object=)} [fnFailure]
312
+ * error handler taking an error message and, since version 1.28.6, an
313
+ * optional object containing the complete error information as delivered
314
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
315
+ * for more details.
316
+ * @since 1.3.0
317
+ */
318
+ this.readBag = function (vParent, sBagId, fnSuccess, fnFailure) {
319
+ if (!vParent) {
320
+ throw new SrvcError("Missing parent ID or object",
321
+ "PageBuildingService");
322
+ }
323
+ if (!sBagId) {
324
+ throw new SrvcError("Missing bag ID", "PageBuildingService");
325
+ }
326
+ oWrapper.read(getBagUrl(vParent, sBagId, true), fnSuccess, fnFailure);
327
+ };
328
+
329
+ /**
330
+ * Reads the "allCatalogs" collection (ordered by ID) that belongs to the page with the given
331
+ * ID.
332
+ *
333
+ * @param {string} sPageId
334
+ * ID of the page
335
+ * @param {function (object)} fnSuccess
336
+ * a callback function that is executed if the request succeeds, taking the processed data
337
+ * @param {function (string, object=)} [fnFailure]
338
+ * error handler taking an error message and, since version 1.28.6, an
339
+ * optional object containing the complete error information as delivered
340
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
341
+ * for more details.
342
+ * @param {string} [sFilter]
343
+ * filter value as defined by OData specification e.g. "type eq 'H'" for HANA catalogs.
344
+ * Filter has been introduced with version 1.16.2.
345
+ * @param {string} sSorting
346
+ * name of the field to be sorted on via $orderby as defined by OData specification.
347
+ * If not defined the dafault sorting would be on the field id (since 1.44)
348
+ * @param {string} bCache
349
+ * Use cache when true, added with 1.70 .0
350
+ * @since 1.7.0
351
+ */
352
+ this.readAllCatalogs = function (sPageId, fnSuccess, fnFailure, sFilter, sSorting, bCache) {
353
+ var sSortField = "id";
354
+ bCache = bCache === undefined ? true : bCache;
355
+ if (sSorting && typeof sSorting === "string") {
356
+ sSortField = sSorting;
357
+ }
358
+ var sUrl = "Pages('" + encodeURIComponent(sPageId)
359
+ + "')/allCatalogs?$expand=Chips/ChipBags/ChipProperties&"
360
+ + "$orderby=" + sSortField;
361
+ if (sFilter && typeof sFilter === "string") {
362
+ sUrl = sUrl + "&$filter=" + encodeURIComponent(sFilter);
363
+ }
364
+ if (this.readAllCatalogs.cacheBusterTokens && this.readAllCatalogs.cacheBusterTokens.get(sPageId)) {
365
+ // There is a cache buster token maintained (!== "") for this ID, so add it to the URL
366
+ sUrl += "&sap-cache-id=" + this.readAllCatalogs.cacheBusterTokens.get(sPageId);
367
+ }
368
+ oWrapper.read(sUrl, fnSuccess, fnFailure, bCache);
369
+ };
370
+
371
+ /**
372
+ * Reads all catalogs ordered by ID.
373
+ *
374
+ * @param {function (object)} fnSuccess
375
+ * a callback function that is executed if the request succeeds, taking the processed data
376
+ * @param {function (string, object=)} [fnFailure]
377
+ * error handler taking an error message and, since version 1.28.6, an
378
+ * optional object containing the complete error information as delivered
379
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
380
+ * for more details.
381
+ * @param {string} [sFilter]
382
+ * filter value as defined by OData specification e.g. "type eq 'H'" for HANA catalogs.
383
+ * Filter has been introduced with version 1.26.0
384
+ * @since 1.2.0
385
+ */
386
+ this.readCatalogs = function (fnSuccess, fnFailure, sFilter) {
387
+ var sUrl = "Catalogs?$orderby=id";
388
+ if (sFilter && typeof sFilter === "string") {
389
+ sUrl = sUrl + "&$filter=" + encodeURIComponent(sFilter);
390
+ }
391
+ oWrapper.read(sUrl, fnSuccess, fnFailure);
392
+ };
393
+
394
+ /**
395
+ * Reads all catalogs for current user filtered by given expression.
396
+ * @param {string} sFilter
397
+ * filter value as defined by OData specification e.g. "type eq 'H'" for HANA catalogs
398
+ * @param {function (object)} fnSuccess
399
+ * a callback function that is executed if the request succeeds, taking the processed data
400
+ * @param {function (string, object=)} [fnFailure]
401
+ * error handler taking an error message and, since version 1.28.6, an
402
+ * optional object containing the complete error information as delivered
403
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
404
+ * for more details.
405
+ * @private
406
+ */
407
+ this.readAllCatalogsForUser = function (sFilter, fnSuccess, fnFailure) {
408
+ var sUrlParameter = sFilter ? "?$filter=" + encodeURIComponent(sFilter) : "";
409
+ // Page ID for the allCatalogs relation is not relevant
410
+ oWrapper.read("Pages('unused')/allCatalogs" + sUrlParameter, fnSuccess, fnFailure);
411
+ };
412
+
413
+ /**
414
+ * Detect if a CHIP is referenced by other CHIPs, also within other catalogs.
415
+ * The CHIP which is checked is specified by its ID (not the ID of its CHIP instance
416
+ * representation on the catalog page).
417
+ * The success handler receives an array of all catalog IDs which contain at least
418
+ * one CHIP which references the CHIP with sReferenceChipId.
419
+ * If the request fails, fnFailure is invoked.
420
+ *
421
+ * @param {string} sReferencedChipId
422
+ * ID of the CHIP for which references are searched
423
+ * @param {function (array)} fnSuccess
424
+ * A callback function that is executed if the request succeeds. It is taking an array of
425
+ * catalog IDs which contain the referenced CHIP ID.
426
+ * The list may be in arbitrary order, notably not the order of the initial array
427
+ * @param {function (string, object=)} [fnFailure]
428
+ * error handler taking an error message and, since version 1.28.6, an
429
+ * optional object containing the complete error information as delivered
430
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
431
+ * for more details.
432
+ * @since 1.28.0
433
+ */
434
+ this.getReferencingCatalogIds = function (sReferencedChipId, fnSuccess, fnFailure) {
435
+ // support SP11 interface: sReferencedChipId, aCatalogIds, fnSuccess, fnFailure
436
+ if (typeof fnSuccess !== "function") {
437
+ fnSuccess = fnFailure;
438
+ // note: using arguments[3] leads to Lint warnings but a named arg will be visible in JSDoc
439
+ fnFailure = arguments[3];
440
+ }
441
+
442
+ function success (oResponse) {
443
+ var aRefCatalogIds = [],
444
+ aReferenceChips = oResponse.results || [];
445
+
446
+ aReferenceChips.forEach(function (oChip) {
447
+ if (oChip.referenceChipId === sReferencedChipId) { //remove when CSN 1570015473 is solved
448
+ // no redundant catalog Ids in aRefCatalogIds
449
+ if (aRefCatalogIds.indexOf(oChip.catalogId) === -1) {
450
+ aRefCatalogIds.push(oChip.catalogId);
451
+ }
452
+ }
453
+ });
454
+
455
+ fnSuccess(aRefCatalogIds);
456
+ }
457
+
458
+ // parameter checks
459
+ if (typeof sReferencedChipId !== "string") {
460
+ throw new SrvcError("sReferencedChipId must be a string",
461
+ "PageBuildingService");
462
+ }
463
+ if (typeof fnSuccess !== "function") {
464
+ throw new SrvcError("fnSuccess is mandatory",
465
+ "PageBuildingService");
466
+ }
467
+
468
+ oWrapper.read("Chips?$filter=" + encodeURIComponent("referenceChipId eq '" +
469
+ encodeODataFilterValue(sReferencedChipId) + "'"),
470
+ success,
471
+ function (sMsg /*, oErrorInformation */) {
472
+ /* eslint-disable no-new */
473
+ new SrvcError(sMsg, "PageBuildingService");
474
+ /* eslint-enable no-new */
475
+ fnFailure.apply(null, arguments);
476
+ });
477
+ };
478
+
479
+ /**
480
+ * Creates a new catalog based on a catalog page, using the given domain ID and title. Note
481
+ * that the page building service will default to a certain type (e.g. "CATALOG_PAGE" in case
482
+ * of ABAP) and will create an ID from that type and the given domain-specific ID (e.g. by
483
+ * adding the prefix "X-SAP-UI2-CATALOGPAGE:" in case of ABAP). Access the object passed to the
484
+ * success callback in order to learn the resulting ID! Note that the catalog page has the
485
+ * same ID as the corresponding catalog and can be retrieved by {@link #readPage}.
486
+ *
487
+ * @param {string} sDomainId
488
+ * the catalog's domain-specific ID
489
+ * @param {string} [sTitle]
490
+ * the catalog's title, also used for the catalog page
491
+ * @param {function (object)} [fnSuccess]
492
+ * a callback function that is executed if the request succeeds, taking the processed data
493
+ * (as a catalog, not as a page)
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 ODataWrapper#onError}
498
+ * for more details.
499
+ * Default: see {@link #getDefaultErrorHandler}
500
+ *
501
+ * @since 1.19.1
502
+ */
503
+ this.createPageBasedCatalog = function (sDomainId, sTitle, fnSuccess, fnFailure) {
504
+ if (!sDomainId) {
505
+ throw new SrvcError("Missing domain ID", "PageBuildingService");
506
+ }
507
+ // TODO: test if type: "CATALOG_PAGE" is the default so we dont need to set it here.
508
+ oWrapper.create("Catalogs", { domainId: sDomainId, title: sTitle, type: "CATALOG_PAGE" },
509
+ fnSuccess, fnFailure);
510
+ };
511
+
512
+ /**
513
+ * Creates a new catalog based on the given raw data. Typically, this will be used to create
514
+ * "remote catalogs", i.e. pointers to existing catalogs on a remote server.
515
+ *
516
+ * @param {object} oCatalog
517
+ * the raw catalog representation (<code>__metadata</code> not needed!), e.g.
518
+ * <pre>
519
+ * {
520
+ * baseUrl: "/sap/hba/apps/kpi/s/odata/hana_chip_catalog.xsodata/",
521
+ * domainId: "Z_REMOTE_HANA_CATALOG",
522
+ * remoteId: "HANA_CATALOG",
523
+ * systemAlias: "sanssouci",
524
+ * title: "Remote HANA catalog",
525
+ * type: "REMOTE"
526
+ * }
527
+ * </pre>
528
+ * @param {function (object)} fnSuccess
529
+ * a callback function that is executed if the request succeeds, taking the processed data
530
+ * @param {function (string, object=)} [fnFailure]
531
+ * error handler taking an error message and, since version 1.28.6, an
532
+ * optional object containing the complete error information as delivered
533
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
534
+ * for more details.
535
+ *
536
+ * @since 1.19.1
537
+ */
538
+ this.createCatalog = function (oCatalog, fnSuccess, fnFailure) {
539
+ oWrapper.create("Catalogs", oCatalog, fnSuccess, fnFailure);
540
+ };
541
+
542
+ /**
543
+ * Deletes the catalog with the given representation which must be the result of a previous
544
+ * create or read operation. If the catalog is based on a catalog page
545
+ * ({@link #createPageBasedCatalog}), that page is also deleted including all of its CHIP
546
+ * instances and bags.
547
+ *
548
+ * @param {object} oCatalog
549
+ * the de-serialized JSON representing the catalog to be deleted
550
+ * @param {function ()} [fnSuccess]
551
+ * a callback function that is executed if the request succeeds, taking no data
552
+ * @param {function (string, object=)} [fnFailure]
553
+ * error handler taking an error message and, since version 1.28.6, an
554
+ * optional object containing the complete error information as delivered
555
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
556
+ * for more details.
557
+ * Default: see {@link #getDefaultErrorHandler}
558
+ *
559
+ * @since 1.19.1
560
+ */
561
+ this.deleteCatalog = function (oCatalog, fnSuccess, fnFailure) {
562
+ oWrapper.del(oCatalog, fnSuccess, fnFailure);
563
+ };
564
+
565
+ /**
566
+ * Creates a new catalog in the backend as a clone of the catalog with given ID, using the
567
+ * given new domain ID. Note that the page building service will create an ID from the
568
+ * catalog's type and the given domain-specific ID (e.g. by adding the prefix
569
+ * "X-SAP-UI2-CATALOGPAGE:" for type "CATALOG_PAGE" in case of ABAP). Access the object passed
570
+ * to the success callback in order to learn the resulting ID!
571
+ *
572
+ * @param {string} sCatalogId
573
+ * the old catalog's ID as returned from the page building service
574
+ * @param {string} sNewDomainId
575
+ * the new catalog's domain-specific ID which must not contain a colon
576
+ * @param {string} [sNewTitle]
577
+ * the new catalog's title; if the parameter is <code>undefined</code>,
578
+ * the old catalog's title will be used
579
+ * @param {function (object)} fnSuccess
580
+ * a callback function that is executed if the request succeeds, taking the processed data
581
+ * (BEWARE: the Chips relation is not expanded, but still deferred!)
582
+ * @param {function (string, object=)} [fnFailure]
583
+ * error handler taking an error message and, since version 1.28.6, an
584
+ * optional object containing the complete error information as delivered
585
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
586
+ * for more details.
587
+ * Default: see {@link #getDefaultErrorHandler}
588
+ * @since 1.19.1
589
+ */
590
+ this.cloneCatalog = function (sCatalogId, sNewDomainId, sNewTitle, fnSuccess, fnFailure) {
591
+ if (!sCatalogId) {
592
+ throw new SrvcError("Missing source catalog ID",
593
+ "PageBuildingService");
594
+ }
595
+ if (!sNewDomainId) {
596
+ throw new SrvcError("Missing new domain ID", "PageBuildingService");
597
+ }
598
+ if (sNewDomainId.indexOf(":") >= 0) {
599
+ throw new SrvcError("Illegal domain ID: " + sNewDomainId,
600
+ "PageBuildingService");
601
+ }
602
+
603
+ oWrapper.create("CloneCatalog?sourceId='" + encodeURIComponent(sCatalogId)
604
+ + "'&targetId='" + encodeURIComponent(sNewDomainId)
605
+ + (sNewTitle !== undefined ? "'&title='" + encodeURIComponent(sNewTitle) + "'" : "'"),
606
+ {}, //payload
607
+ fnSuccess,
608
+ fnFailure);
609
+ };
610
+
611
+ /**
612
+ * Adds a reference CHIP instance to the page with ID <code>sTargetPageId</code>. The new
613
+ * reference refers to the CHIP instance with the given ID located on the source page with the
614
+ * given ID.
615
+ *
616
+ * @param {string} sSourcePageId
617
+ * ID of the source page the CHIP instance with ID <code>sSourceChipInstanceId</code> is
618
+ * located on
619
+ * @param {string} sSourceChipInstanceId
620
+ * ID of the CHIP instance referenced to
621
+ * @param {string} sTargetPageId
622
+ * ID of the page where the reference CHIP Instance shall be added to
623
+ * @param {function (object)} fnSuccess
624
+ * a callback function that is executed if the request succeeds, taking the processed data
625
+ * @param {function (string, object=)} [fnFailure]
626
+ * error handler taking an error message and, since version 1.28.6, an
627
+ * optional object containing the complete error information as delivered
628
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
629
+ * for more details.
630
+ * Default: see {@link #getDefaultErrorHandler}
631
+ *
632
+ * @since 1.21.1
633
+ */
634
+ this.clonePageChipInstance = function (sSourcePageId, sSourceChipInstanceId,
635
+ sTargetPageId, fnSuccess, fnFailure) {
636
+ if (!sSourcePageId) {
637
+ throw new SrvcError("Missing source page ID",
638
+ "PageBuildingService");
639
+ }
640
+ if (!sSourceChipInstanceId) {
641
+ throw new SrvcError("Missing source CHIP instance ID",
642
+ "PageBuildingService");
643
+ }
644
+ if (!sTargetPageId) {
645
+ throw new SrvcError("Missing target page ID",
646
+ "PageBuildingService");
647
+ }
648
+ oWrapper.create("ClonePageChipInstance?sourcePageId='" + encodeURIComponent(sSourcePageId)
649
+ + "'&sourceChipInstanceId='" + encodeURIComponent(sSourceChipInstanceId)
650
+ + "'&targetPageId='" + encodeURIComponent(sTargetPageId) + "'",
651
+ {}, //payload
652
+ function (oRawChipInstance) {
653
+ // ClonePageChipInstance cannot expand the result
654
+ // Note: the CHIP instance cannot be remote and the CHIP has already been loaded
655
+ oWrapper.read("PageChipInstances(pageId='" + encodeURIComponent(oRawChipInstance.pageId)
656
+ + "',instanceId='" + encodeURIComponent(oRawChipInstance.instanceId) + "')"
657
+ + "?$expand=ChipInstanceBags/ChipInstanceProperties",
658
+ fnSuccess,
659
+ fnFailure);
660
+ },
661
+ fnFailure);
662
+ };
663
+
664
+ /**
665
+ * Reads the catalog with the given ID including all contained CHIPs (unless specified
666
+ * otherwise). Note that the corresponding catalog page (if applicable) has the same ID and can
667
+ * be retrieved by {@link #readPage}.
668
+ *
669
+ * @param {string} sCatalogId
670
+ * ID of the catalog to be loaded
671
+ * @param {function (object)} fnSuccess
672
+ * a callback function that is executed if the request succeeds, taking the processed data
673
+ * @param {function (string, object=)} [fnFailure]
674
+ * error handler taking an error message and, since version 1.28.6, an
675
+ * optional object containing the complete error information as delivered
676
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
677
+ * for more details.
678
+ * @param {boolean} [bNoChips=false]
679
+ * whether to avoid including all contained CHIPs
680
+ * @param {boolean} [bNoChipBags=false]
681
+ * whether to avoid including CHIP bags and properties
682
+ * @since 1.2.0
683
+ */
684
+ this.readCatalog = function (sCatalogId, fnSuccess, fnFailure, bNoChips, bNoChipBags) {
685
+ var sUrl;
686
+
687
+ if (!sCatalogId) {
688
+ throw new SrvcError("Missing catalog ID", "PageBuildingService");
689
+ }
690
+
691
+ sUrl = "Catalogs('" + encodeURIComponent(sCatalogId) + "')";
692
+ if (!bNoChips) {
693
+ sUrl += "?$expand=Chips";
694
+ if (!bNoChipBags) {
695
+ sUrl += "/ChipBags/ChipProperties";
696
+ }
697
+ }
698
+ oWrapper.read(sUrl, fnSuccess, fnFailure);
699
+ };
700
+
701
+ /**
702
+ * Updates the catalog with the given representation which must be the result of a previous
703
+ * create or read operation. Note that you cannot update keys, in this case the "id" property.
704
+ * Note that for a catalog based on a catalog page ({@link #createPageBasedCatalog}), the
705
+ * "title" property is shared between the catalog and its corresponding catalog page!
706
+ *
707
+ * @param {object} oCatalog
708
+ * the de-serialized JSON representing the catalog to be updated
709
+ * @param {function ()} [fnSuccess]
710
+ * a callback function that is executed if the request succeeds, taking no data
711
+ * @param {function (string, object=)} [fnFailure]
712
+ * error handler taking an error message and, since version 1.28.6, an
713
+ * optional object containing the complete error information as delivered
714
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
715
+ * for more details.
716
+ *
717
+ * @since 1.19.1
718
+ */
719
+ this.updateCatalog = function (oCatalog, fnSuccess, fnFailure) {
720
+ oWrapper.update(oCatalog, fnSuccess, fnFailure);
721
+ };
722
+
723
+ /**
724
+ * Reads the given CHIPs from the catalog with the given ID.
725
+ *
726
+ * @param {string} sCatalogId
727
+ * ID of the catalog to be loaded
728
+ * @param {string[]} [aChipIds]
729
+ * the IDs of the CHIPs to be loaded. If <code>undefined</code>, all CHIPs will be loaded.
730
+ * @param {function (object)} fnSuccess
731
+ * a callback function that is executed if the request succeeds, taking the processed data
732
+ * @param {function (string, object=)} [fnFailure]
733
+ * error handler taking an error message and, since version 1.28.6, an
734
+ * optional object containing the complete error information as delivered
735
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
736
+ * for more details.
737
+ * @throws Error if an empty array is given for filtering
738
+ * @since 1.16.4
739
+ */
740
+ this.readCatalogChips = function (sCatalogId, aChipIds, fnSuccess, fnFailure) {
741
+ var sUrl,
742
+ sFilter = "",
743
+ sPrefix = "?$filter=";
744
+
745
+ if (!sCatalogId) {
746
+ throw new SrvcError("Missing catalog ID", "PageBuildingService");
747
+ }
748
+
749
+ // TODO: read also CHIP bags
750
+ sUrl = "Catalogs('" + encodeURIComponent(sCatalogId) + "')/Chips";
751
+ if (aChipIds) {
752
+ if (!aChipIds.length) {
753
+ throw new SrvcError("No CHIP IDs given", "PageBuildingService");
754
+ }
755
+ aChipIds.forEach(function (sId) {
756
+ sFilter = sFilter + sPrefix + "id%20eq%20'" + encodeURIComponent(sId) + "'";
757
+ sPrefix = "%20or%20";
758
+ });
759
+ // ensure that the resulting URL does not exceed length limits
760
+ if (oWrapper.getBaseUrl().length + sUrl.length + sFilter.length > 2000) {
761
+ sFilter = "";
762
+ }
763
+ }
764
+ oWrapper.read(sUrl + sFilter, fnSuccess, fnFailure);
765
+ };
766
+
767
+ /**
768
+ * Creates a new page with the given properties.
769
+ *
770
+ * @param {string} sId
771
+ * ID of the new page
772
+ * @param {string} sCatalogId
773
+ * ID of the catalog for the new page
774
+ * @param {string} sLayout
775
+ * value of the layout property for the new page
776
+ * @param {string} sTitle
777
+ * title of the new page
778
+ * @param {function (object)} [fnSuccess]
779
+ * a callback function that is executed if the request succeeds, taking the processed data
780
+ * @param {function (string, object=)} [fnFailure]
781
+ * error handler taking an error message and, since version 1.28.6, an
782
+ * optional object containing the complete error information as delivered
783
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
784
+ * for more details.
785
+ * @since 1.2.0
786
+ */
787
+ this.createPage = function (sId, sCatalogId, sLayout, sTitle, fnSuccess, fnFailure) {
788
+ if (!sId) {
789
+ throw new SrvcError("Missing page ID", "PageBuildingService");
790
+ }
791
+
792
+ oWrapper.create("Pages", {
793
+ id: sId,
794
+ catalogId: sCatalogId,
795
+ layout: sLayout,
796
+ title: sTitle
797
+ }, fnSuccess, fnFailure);
798
+ };
799
+
800
+ /**
801
+ * Reads all pages ordered by ID including all contained catalogs (unless specified otherwise).
802
+ *
803
+ * @param {function (object)} fnSuccess
804
+ * a callback function that is executed if the request succeeds, taking the processed data
805
+ * @param {function (string, object=)} [fnFailure]
806
+ * error handler taking an error message and, since version 1.28.6, an
807
+ * optional object containing the complete error information as delivered
808
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
809
+ * for more details.
810
+ * @param {boolean} [bNoCatalogs=false]
811
+ * whether to avoid including all contained catalogs
812
+ * @since 1.2.0
813
+ */
814
+ this.readPages = function (fnSuccess, fnFailure, bNoCatalogs) {
815
+ var sUrl = "Pages?";
816
+ if (!bNoCatalogs) {
817
+ sUrl += "$expand=Catalog&";
818
+ }
819
+ oWrapper.read(sUrl + "$orderby=id", fnSuccess, fnFailure);
820
+ };
821
+
822
+ /**
823
+ * Reads the page with the given ID including all contained <br>
824
+ * - CHIP instances and their CHIPs, <br>
825
+ * - bags and properties (page, CHIP and CHIP instance bags), <br>
826
+ * - RemoteCatalog data.
827
+ * <p>
828
+ * Via the parameter <code>sCustomExpand</code> you can specify a different $expand statement.
829
+ *
830
+ * @param {string} sId
831
+ * ID of the page to be read
832
+ * @param {function (object)} fnSuccess
833
+ * a callback function that is executed if the request succeeds, taking the processed data
834
+ * @param {function (string, object=)} [fnFailure]
835
+ * error handler taking an error message and, since version 1.28.6, an
836
+ * optional object containing the complete error information as delivered
837
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
838
+ * for more details.
839
+ * @param {string} [sCustomExpand="Bags/Properties,PageChipInstances/Chip/ChipBags/ChipProperties,PageChipInstances/RemoteCatalog,PageChipInstances/ChipInstanceBags/ChipInstanceProperties"]
840
+ * (since 1.30.0) can be used to overwrite the default $expand value. If "" is used, the
841
+ * entire $expand parameter will be skipped
842
+ * @since 1.2.0
843
+ */
844
+ this.readPage = function (sId, fnSuccess, fnFailure, sCustomExpand) {
845
+ var sUrl = "Pages('" + encodeURIComponent(sId) + "')";
846
+ if (!sId) {
847
+ throw new SrvcError("Missing page ID", "PageBuildingService");
848
+ }
849
+
850
+ if (sCustomExpand === undefined) {
851
+ // use default expand
852
+ sUrl += "?$expand=Bags/Properties,PageChipInstances/Chip/ChipBags/ChipProperties,"
853
+ + "PageChipInstances/RemoteCatalog,"
854
+ + "PageChipInstances/ChipInstanceBags/ChipInstanceProperties";
855
+ } else if (sCustomExpand !== "") {
856
+ sUrl += "?$expand=" + sCustomExpand;
857
+ }
858
+
859
+ oWrapper.read(sUrl, fnSuccess, fnFailure);
860
+ };
861
+
862
+ /**
863
+ * Reads the page set with the given ID including all contained pages and their CHIP instances.
864
+ * Property bags are not loaded.
865
+ * Note: Cache buster tokens (sap-cache-id), can be set via
866
+ * <code>oPbs.readPageSet.cacheBusterTokens.put("PageSetId", "cbtoken")</code>
867
+ *
868
+ * @param {string} sId
869
+ * ID of the page set to be read
870
+ * @param {function (object)} fnSuccess
871
+ * a callback function that is executed if the request succeeds, taking the processed data
872
+ * @param {function (string, object=)} [fnFailure]
873
+ * error handler taking an error message and, since version 1.28.6, an
874
+ * optional object containing the complete error information as delivered
875
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
876
+ * for more details.
877
+ * @param {string} bCache
878
+ * Use cache when true, added with 1.70.0
879
+ * @since 1.11.0
880
+ * @private
881
+ */
882
+ this.readPageSet = function (sId, fnSuccess, fnFailure, bCache) {
883
+ var sUrl;
884
+ var that = this;
885
+ var appendedParametersKeys;
886
+ bCache = bCache === undefined ? true : bCache;
887
+
888
+ if (!sId) {
889
+ throw new SrvcError("Missing page set ID", "PageBuildingService");
890
+ }
891
+
892
+ sUrl = "PageSets('" + encodeURIComponent(sId) + "')?$expand="
893
+ + "Pages/PageChipInstances/Chip/ChipBags/ChipProperties,"
894
+ + "Pages/PageChipInstances/RemoteCatalog,"
895
+ + "Pages/PageChipInstances/ChipInstanceBags/ChipInstanceProperties,"
896
+ + "AssignedPages,"
897
+ + "DefaultPage";
898
+
899
+ if (this.readPageSet.cacheBusterTokens && this.readPageSet.cacheBusterTokens.get(sId)) {
900
+ // There is a cache buster token maintained (!== "") for this ID, so add it to the URL
901
+ // Note: Same parameter order as in ABAP bootstrap must be used as the response is cached
902
+ // in OData.read.$cache under exactly that URL string
903
+ sUrl += "&sap-cache-id=" + this.readPageSet.cacheBusterTokens.get(sId);
904
+ }
905
+ if (this.readPageSet.appendedParameters) {
906
+ appendedParametersKeys = Object.keys(this.readPageSet.appendedParameters);
907
+ if (appendedParametersKeys.length > 0) {
908
+ appendedParametersKeys.sort();
909
+ appendedParametersKeys.forEach(function (key) {
910
+ sUrl += "&" + encodeURIComponent(key) + "=" + encodeURIComponent(that.readPageSet.appendedParameters[key]);
911
+ });
912
+ }
913
+ }
914
+ oWrapper.read(sUrl, fnSuccess, fnFailure, bCache);
915
+ };
916
+
917
+ /**
918
+ * Updates the page set with the given representation which must be the result of
919
+ * a previous read operation.
920
+ *
921
+ * @param {object} oPageSet
922
+ * the de-serialized JSON representing the page set to be updated
923
+ * @param {function ()} [fnSuccess]
924
+ * a callback function that is executed if the request succeeds, taking no data
925
+ * @param {function (string, object=)} [fnFailure]
926
+ * error handler taking an error message and, since version 1.28.6, an
927
+ * optional object containing the complete error information as delivered
928
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
929
+ * for more details.
930
+ * @since 1.11.0
931
+ * @private
932
+ */
933
+ this.updatePageSet = function (oPageSet, fnSuccess, fnFailure) {
934
+ oWrapper.update(oPageSet, fnSuccess, fnFailure);
935
+ };
936
+
937
+ /**
938
+ * Creates a new page with given title in given page set.
939
+ *
940
+ * @param {string} sPageSetId
941
+ * ID of the page set
942
+ * @param {string} sPageTitle
943
+ * title (might be an empty) of the new page
944
+ * @param {string} sCatalogId
945
+ * ID of the default catalog of the new page
946
+ * @param {function (object)} fnSuccess
947
+ * a callback function that is executed if the request succeeds, taking the processed data
948
+ * @param {function (string, object=)} [fnFailure]
949
+ * error handler taking an error message and, since version 1.28.6, an
950
+ * optional object containing the complete error information as delivered
951
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
952
+ * for more details.
953
+ * @private
954
+ */
955
+ this.createPageInPageSet = function (sPageSetId, sPageTitle, sCatalogId, fnSuccess, fnFailure) {
956
+ // TODO refactor parameters use one object instead of multiple strings
957
+ if (!sPageSetId) {
958
+ throw new SrvcError("Missing page set ID", "PageBuildingService");
959
+ }
960
+ oWrapper.create("PageSets('" + encodeURIComponent(sPageSetId) + "')/Pages", {
961
+ catalogId: sCatalogId || "",
962
+ layout: "",
963
+ title: sPageTitle || ""
964
+ }, fnSuccess, fnFailure);
965
+ };
966
+
967
+ /**
968
+ * Updates the page with the given representation which must be the result of
969
+ * a previous create or read operation.
970
+ *
971
+ * @param {object} oPage
972
+ * the de-serialized JSON representing the page to be updated
973
+ * @param {function ()} [fnSuccess]
974
+ * a callback function that is executed if the request succeeds, taking no data
975
+ * @param {function (string, object=)} [fnFailure]
976
+ * error handler taking an error message and, since version 1.28.6, an
977
+ * optional object containing the complete error information as delivered
978
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
979
+ * for more details.
980
+ * @since 1.2.0
981
+ */
982
+ this.updatePage = function (oPage, fnSuccess, fnFailure) {
983
+ oWrapper.update(oPage, fnSuccess, fnFailure);
984
+ };
985
+
986
+ /**
987
+ * Deletes the page with the given ID.
988
+ *
989
+ * @param {string} sId
990
+ * ID of page to be deleted
991
+ * @param {function ()} [fnSuccess]
992
+ * a callback function that is executed if the request succeeds, taking no data
993
+ * @param {function (string, object=)} [fnFailure]
994
+ * error handler taking an error message and, since version 1.28.6, an
995
+ * optional object containing the complete error information as delivered
996
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
997
+ * for more details.
998
+ * @since 1.2.0
999
+ */
1000
+ this.deletePage = function (sId, fnSuccess, fnFailure) {
1001
+ if (!sId) {
1002
+ throw new SrvcError("Missing page ID", "PageBuildingService");
1003
+ }
1004
+
1005
+ oWrapper.del("Pages('" + encodeURIComponent(sId) + "')",
1006
+ fnSuccess, fnFailure);
1007
+ };
1008
+
1009
+ /**
1010
+ * Creates a CHIP instance with the given properties inside the page with given ID.
1011
+ *
1012
+ * @param {string} sPageId
1013
+ * ID of page containing the new CHIP instance
1014
+ * @param {string} [sInstanceId]
1015
+ * ID of new CHIP instance (optional, a UUID will be created as a default)
1016
+ * @param {string} sChipId
1017
+ * ID of CHIP to be used
1018
+ * @param {string} sTitle
1019
+ * title of CHIP instance
1020
+ * @param {string} sConfiguration
1021
+ * configuration of CHIP instance
1022
+ * @param {string} sLayoutData
1023
+ * layout data of CHIP instance
1024
+ * @param {function (object)} [fnSuccess]
1025
+ * a callback function that is executed if the request succeeds, taking the processed data
1026
+ * (Note: The instance's "Chips" relation will not be expanded!)
1027
+ * @param {function (string, object=)} [fnFailure]
1028
+ * error handler taking an error message and, since version 1.28.6, an
1029
+ * optional object containing the complete error information as delivered
1030
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1031
+ * for more details.
1032
+ * @since 1.2.0
1033
+ */
1034
+ this.createPageChipInstance = function (sPageId, sInstanceId,
1035
+ sChipId, sTitle, sConfiguration, sLayoutData, fnSuccess, fnFailure) {
1036
+ this.createPageChipInstanceFromRawData({
1037
+ pageId: sPageId,
1038
+ instanceId: sInstanceId,
1039
+ chipId: sChipId,
1040
+ title: sTitle,
1041
+ configuration: sConfiguration,
1042
+ layoutData: sLayoutData
1043
+ }, fnSuccess, fnFailure);
1044
+ };
1045
+
1046
+ /**
1047
+ * Creates a CHIP instance with the given properties inside the page with given ID.
1048
+ *
1049
+ * @param {object} oChipInstance
1050
+ * the de-serialized JSON representing the CHIP instance to be created
1051
+ * @param {string} oChipInstance.pageId
1052
+ * ID of page containing the new CHIP instance
1053
+ * @param {string} [oChipInstance.instanceId]
1054
+ * ID of new CHIP instance (optional, a UUID will be created as a default)
1055
+ * @param {string} oChipInstance.chipId
1056
+ * ID of CHIP to be used
1057
+ * @param {string} [oChipInstance.title]
1058
+ * title of CHIP instance
1059
+ * @param {string} [oChipInstance.configuration]
1060
+ * configuration of CHIP instance
1061
+ * @param {string} [oChipInstance.layoutData]
1062
+ * layout data of CHIP instance
1063
+ * @param {function (object)} [fnSuccess]
1064
+ * a callback function that is executed if the request succeeds, taking the processed data
1065
+ * (Note: The instance's "Chips" relation will not be expanded!)
1066
+ * @param {function (string, object=)} [fnFailure]
1067
+ * error handler taking an error message and, since version 1.28.6, an
1068
+ * optional object containing the complete error information as delivered
1069
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1070
+ * for more details.
1071
+ * @since 1.9.0
1072
+ */
1073
+ this.createPageChipInstanceFromRawData = function (oChipInstance, fnSuccess, fnFailure) {
1074
+ if (typeof oChipInstance !== "object") {
1075
+ throw new SrvcError("Invalid raw data", "PageBuildingService");
1076
+ }
1077
+ if (!oChipInstance.pageId) {
1078
+ throw new SrvcError("Missing page ID", "PageBuildingService");
1079
+ }
1080
+ if (!oChipInstance.chipId) {
1081
+ throw new SrvcError("Missing CHIP ID", "PageBuildingService");
1082
+ }
1083
+ oChipInstance.instanceId = oChipInstance.instanceId || "";
1084
+ oChipInstance.title = oChipInstance.title || "";
1085
+ oChipInstance.configuration = oChipInstance.configuration || "";
1086
+ oChipInstance.layoutData = oChipInstance.layoutData || "";
1087
+ //oChipInstance.remoteCatalogId = oChipInstance.remoteCatalogId || "";
1088
+
1089
+ //TODO the equivalent of "?$expand=Chips/ChipBags/ChipProperties" is missing!
1090
+ oWrapper.create("PageChipInstances", oChipInstance, fnSuccess, fnFailure);
1091
+ };
1092
+
1093
+ /**
1094
+ * Updates the CHIP instance with the given representation which must be the
1095
+ * result of a previous create or read operation.
1096
+ *
1097
+ * @param {object} oChipInstance
1098
+ * the de-serialized JSON representing the CHIP instance to be updated
1099
+ * @param {function ()} [fnSuccess]
1100
+ * a callback function that is executed if the request succeeds, taking no data
1101
+ * @param {function (string, object=)} [fnFailure]
1102
+ * error handler taking an error message and, since version 1.28.6, an
1103
+ * optional object containing the complete error information as delivered
1104
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1105
+ * for more details.
1106
+ * @since 1.2.0
1107
+ */
1108
+ this.updatePageChipInstance = function (oChipInstance, fnSuccess, fnFailure) {
1109
+ oWrapper.update(oChipInstance, fnSuccess, fnFailure);
1110
+ };
1111
+
1112
+ /**
1113
+ * Deletes the CHIP instance with the given ID inside the page with given ID.
1114
+ *
1115
+ * @param {string} sPageId
1116
+ * ID of page from which CHIP instance is to be deleted
1117
+ * @param {string} sInstanceId
1118
+ * ID of CHIP instance to be deleted
1119
+ * @param {function ()} [fnSuccess]
1120
+ * a callback function that is executed if the request succeeds, taking no data
1121
+ * @param {function (string, object=)} [fnFailure]
1122
+ * error handler taking an error message and, since version 1.28.6, an
1123
+ * optional object containing the complete error information as delivered
1124
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1125
+ * for more details.
1126
+ * @since 1.2.0
1127
+ */
1128
+ this.deletePageChipInstance = function (sPageId, sInstanceId, fnSuccess, fnFailure) {
1129
+ if (!sPageId) {
1130
+ throw new SrvcError("Missing page ID", "PageBuildingService");
1131
+ }
1132
+ if (!sInstanceId) {
1133
+ throw new SrvcError("Missing instance ID", "PageBuildingService");
1134
+ }
1135
+
1136
+ oWrapper.del("PageChipInstances(pageId='" + encodeURIComponent(sPageId)
1137
+ + "',instanceId='" + encodeURIComponent(sInstanceId) + "')",
1138
+ fnSuccess, fnFailure);
1139
+ };
1140
+
1141
+ /**
1142
+ * Updates all changed properties for the specified bag using a single batch request.
1143
+ *
1144
+ * @param {object} oParent
1145
+ * parent of the bag to be updated (either page or page CHIP instance)
1146
+ * @param {string} sBagId
1147
+ * ID of the bag
1148
+ * @param {array} [aChangedProperties=[]]
1149
+ * array of existing properties to be changed
1150
+ * @param {array} [aNewProperties=[]]
1151
+ * array of properties to be created
1152
+ * @param {array} [aResetProperties=[]]
1153
+ * array of properties to be reset (since 1.17.1)
1154
+ * @param {function(array,array,array)} [fnSuccess]
1155
+ * a callback function that is executed if the request succeeds, taking three arrays of
1156
+ * response objects for changed, new and reset properties respectively.
1157
+ * For a successful creation, the response object is the new entity. For a successful
1158
+ * change, it is undefined. For a successful reset it is the entity from the underlying scope
1159
+ * or undefined if this does not exist.
1160
+ * For a failed request, it is the corresponding error message.
1161
+ * @param {function (string, object=)} [fnFailure]
1162
+ * error handler taking an error message and, since version 1.28.6, an
1163
+ * optional object containing the complete error information as delivered
1164
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1165
+ * for more details.
1166
+ * <br/>
1167
+ * <b>NOTE:</b> it is called only in case the whole
1168
+ * <code>$batch</code> request fails!)
1169
+ *
1170
+ * @since 1.11.0
1171
+ * @deprecated Use {@link ODataService#openBatchQueue} instead.
1172
+ */
1173
+ this.updateBagProperties = function (oParent, sBagId, aChangedProperties, aNewProperties,
1174
+ aResetProperties, fnSuccess, fnFailure) {
1175
+ var aChangeRequests = [],
1176
+ aGetRequests = [],
1177
+ i,
1178
+ pos,
1179
+ oProperty,
1180
+ sRequestUri,
1181
+ sMETADATA = "__metadata"; // constant to make JSLint happy
1182
+
1183
+ /* @returns {object} */
1184
+ function extractPayload (oEntity) {
1185
+ var oResult = {
1186
+ __metadata: {
1187
+ type: oEntity[sMETADATA].type,
1188
+ uri: oEntity[sMETADATA].uri
1189
+ }
1190
+ },
1191
+ sPropertyName;
1192
+
1193
+ // filter out unnecessary properties
1194
+ for (sPropertyName in oEntity) {
1195
+ if (Object.prototype.hasOwnProperty.call(oEntity, sPropertyName)
1196
+ && sPropertyName !== sMETADATA
1197
+ && sPropertyName.indexOf("$") !== 0
1198
+ && typeof oEntity[sPropertyName] !== "object") {
1199
+ oResult[sPropertyName] = oEntity[sPropertyName];
1200
+ }
1201
+ }
1202
+ return oResult;
1203
+ }
1204
+
1205
+ if (!oParent) {
1206
+ throw new SrvcError("Missing parent object",
1207
+ "PageBuildingService");
1208
+ }
1209
+
1210
+ if (!sBagId) {
1211
+ throw new SrvcError("Missing bag ID", "PageBuildingService");
1212
+ }
1213
+
1214
+ //Compatibility for callers not having newly inserted parameter aResetProperties
1215
+ if (typeof aResetProperties === "function") {
1216
+ this.updateBagProperties(oParent, sBagId, aChangedProperties, aNewProperties, [],
1217
+ /*fnSuccess=*/aResetProperties, /*fnFailure=*/fnSuccess);
1218
+ return;
1219
+ }
1220
+
1221
+ aChangedProperties = aChangedProperties || [];
1222
+ aNewProperties = aNewProperties || [];
1223
+ aResetProperties = aResetProperties || [];
1224
+
1225
+ if (aChangedProperties.length === 0 && aNewProperties.length === 0 &&
1226
+ aResetProperties.length === 0) {
1227
+ throw new SrvcError("No properties to update, create or reset",
1228
+ "PageBuildingService");
1229
+ }
1230
+
1231
+ // PUT requests
1232
+ for (i = 0; i < aChangedProperties.length; i += 1) {
1233
+ oProperty = aChangedProperties[i];
1234
+ sRequestUri = oProperty[sMETADATA].uri;
1235
+ // cut protocol, hostname and base URI from request URI
1236
+ pos = sRequestUri.indexOf(oWrapper.getBaseUrl());
1237
+ if (pos >= 0) {
1238
+ sRequestUri = sRequestUri.slice(pos + oWrapper.getBaseUrl().length);
1239
+ }
1240
+ aChangeRequests.push({
1241
+ requestUri: sRequestUri,
1242
+ method: "PUT",
1243
+ data: extractPayload(oProperty)
1244
+ });
1245
+ }
1246
+
1247
+ // POST requests
1248
+ sRequestUri = oParent.instanceId ? "ChipInstanceProperties" : "Properties";
1249
+ for (i = 0; i < aNewProperties.length; i += 1) {
1250
+ oProperty = aNewProperties[i];
1251
+ if (!oProperty.name) {
1252
+ throw new SrvcError("Missing property name", "PageBuildingService");
1253
+ }
1254
+ if (oParent.instanceId) {
1255
+ oProperty.instanceId = oParent.instanceId;
1256
+ oProperty.pageId = oParent.pageId;
1257
+ } else {
1258
+ oProperty.pageId = oParent.id;
1259
+ }
1260
+ oProperty.bagId = sBagId;
1261
+ aChangeRequests.push({
1262
+ requestUri: sRequestUri,
1263
+ method: "POST",
1264
+ data: oProperty
1265
+ });
1266
+ }
1267
+
1268
+ // Reset property maps to DELETE and GET request
1269
+ for (i = 0; i < aResetProperties.length; i += 1) {
1270
+ oProperty = aResetProperties[i];
1271
+ sRequestUri = oProperty[sMETADATA].uri;
1272
+ // cut protocol, hostname and base URI from request URI
1273
+ pos = sRequestUri.indexOf(oWrapper.getBaseUrl());
1274
+ if (pos >= 0) {
1275
+ sRequestUri = sRequestUri.slice(pos + oWrapper.getBaseUrl().length);
1276
+ }
1277
+ aChangeRequests.push({
1278
+ requestUri: sRequestUri,
1279
+ method: "DELETE"
1280
+ });
1281
+ aGetRequests.push({
1282
+ requestUri: sRequestUri,
1283
+ method: "GET"
1284
+ });
1285
+ }
1286
+
1287
+ this.batch(aChangeRequests, aGetRequests,
1288
+ function (aChangeResponses, aGetResponses) {
1289
+ var aResetResponses =
1290
+ aChangeResponses.slice(aNewProperties.length + aChangedProperties.length),
1291
+ i;
1292
+
1293
+ for (i = 0; i < aResetResponses.length; i += 1) {
1294
+ if (aResetResponses[i] === undefined) { //DELETE ok
1295
+ if (typeof aGetResponses[i] === "object") { //GET ok
1296
+ aResetResponses[i] = aGetResponses[i];
1297
+ }
1298
+ }
1299
+ }
1300
+ if (fnSuccess) {
1301
+ fnSuccess(
1302
+ aChangeResponses.slice(0, aChangedProperties.length), // PUT responses
1303
+ aChangeResponses.slice(aChangedProperties.length,
1304
+ aNewProperties.length + aChangedProperties.length), // POST responses
1305
+ aResetResponses
1306
+ );
1307
+ }
1308
+ }, fnFailure);
1309
+ };
1310
+
1311
+ /**
1312
+ * Creates a new property with the given value.
1313
+ *
1314
+ * @param {string|object} vParent
1315
+ * ID of the page or parent object (either page or page CHIP instance; must be the result
1316
+ * of a previous create or read operation) of the bag for which a property needs to be
1317
+ * created
1318
+ * @param {string} sBagId
1319
+ * ID of the bag
1320
+ * @param {string} sPropertyName
1321
+ * the property name
1322
+ * @param {string} sValue
1323
+ * the property value
1324
+ * @param {string} [sTranslatable]
1325
+ * determines if the new property is a translatable one (since 1.19.0)
1326
+ * <b>Note:</b> this is treated here as a plain string by intent, although the backend will
1327
+ * treat it like a boolean (<code>" "</code> vs. <code>"X"</code>)
1328
+ * @param {function (object)} [fnSuccess]
1329
+ * a callback function that is executed if the request succeeds, taking the processed data
1330
+ * @param {function (string, object=)} [fnFailure]
1331
+ * error handler taking an error message and, since version 1.28.6, an
1332
+ * optional object containing the complete error information as delivered
1333
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1334
+ * for more details.
1335
+ * @since 1.3.0
1336
+ */
1337
+ this.createProperty = function (vParent, sBagId, sPropertyName, sValue, sTranslatable,
1338
+ fnSuccess, fnFailure) {
1339
+ var oProperty;
1340
+
1341
+ if (!vParent) {
1342
+ throw new SrvcError("Missing parent ID or object",
1343
+ "PageBuildingService");
1344
+ }
1345
+ if (!sBagId) {
1346
+ throw new SrvcError("Missing bag ID", "PageBuildingService");
1347
+ }
1348
+ if (!sPropertyName) {
1349
+ throw new SrvcError("Missing property name", "PageBuildingService");
1350
+ }
1351
+ if (typeof sTranslatable === "function") {
1352
+ // sTranslatable missing, shift arguments appropriately
1353
+ this.createProperty(vParent, sBagId, sPropertyName, sValue, undefined,
1354
+ /*fnSuccess=*/sTranslatable, /*fnFailure=*/fnSuccess);
1355
+ return;
1356
+ }
1357
+
1358
+ oProperty = {
1359
+ bagId: sBagId,
1360
+ name: sPropertyName,
1361
+ pageId: vParent,
1362
+ translatable: sTranslatable,
1363
+ value: sValue
1364
+ };
1365
+ if (typeof vParent !== "string") {
1366
+ if (vParent.instanceId) {
1367
+ oProperty.instanceId = vParent.instanceId;
1368
+ oProperty.pageId = vParent.pageId;
1369
+ } else {
1370
+ oProperty.pageId = vParent.id;
1371
+ }
1372
+ }
1373
+
1374
+ oWrapper.create((oProperty.instanceId ? "ChipInstanceProperties" : "Properties"),
1375
+ oProperty, fnSuccess, fnFailure);
1376
+ };
1377
+
1378
+ /**
1379
+ * Updates the property with the given representation which must be the result of
1380
+ * a previous create or read operation.
1381
+ *
1382
+ * @param {object} oProperty
1383
+ * the de-serialized JSON representing the property to be updated
1384
+ * @param {function ()} [fnSuccess]
1385
+ * a callback function that is executed if the request succeeds, taking no data
1386
+ * @param {function (string, object=)} [fnFailure]
1387
+ * error handler taking an error message and, since version 1.28.6, an
1388
+ * optional object containing the complete error information as delivered
1389
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1390
+ * for more details.
1391
+ * @since 1.3.0
1392
+ */
1393
+ this.updateProperty = function (oProperty, fnSuccess, fnFailure) {
1394
+ oWrapper.update(oProperty, fnSuccess, fnFailure);
1395
+ };
1396
+
1397
+ /**
1398
+ * Deletes the property with the given representation which must be the result of
1399
+ * a previous create or read operation.
1400
+ *
1401
+ * @param {object} oProperty
1402
+ * the de-serialized JSON representing the property to be deleted
1403
+ * @param {function ()} [fnSuccess]
1404
+ * a callback function that is executed if the request succeeds, taking no data
1405
+ * @param {function (string, object=)} [fnFailure]
1406
+ * error handler taking an error message and, since version 1.28.6, an
1407
+ * optional object containing the complete error information as delivered
1408
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1409
+ * for more details.
1410
+ * @since 1.19.0
1411
+ */
1412
+ this.deleteProperty = function (oProperty, fnSuccess, fnFailure) {
1413
+ oWrapper.del(oProperty, fnSuccess, fnFailure);
1414
+ };
1415
+
1416
+ /**
1417
+ * Reads the CHIP with the given ID.
1418
+ *
1419
+ * @param {string} sChipId
1420
+ * ID of the CHIP to be loaded
1421
+ * @param {function (object)} fnSuccess
1422
+ * a callback function that is executed if the request succeeds, taking the processed data
1423
+ * @param {function (string, object=)} [fnFailure]
1424
+ * error handler taking an error message and, since version 1.28.6, an
1425
+ * optional object containing the complete error information as delivered
1426
+ * by the ODataService. See fnFailure parameter of {@link ODataWrapper#onError}
1427
+ * for more details.
1428
+ * @since 1.2.0
1429
+ */
1430
+ this.readChip = function (sChipId, fnSuccess, fnFailure) {
1431
+ if (!sChipId) {
1432
+ throw new SrvcError("Missing CHIP ID", "PageBuildingService");
1433
+ }
1434
+
1435
+ oWrapper.read("Chips('" + encodeURIComponent(sChipId) + "')" +
1436
+ "?$expand=ChipBags/ChipProperties", fnSuccess, fnFailure);
1437
+ };
1438
+
1439
+ // constructor code -------------------------------------------------------
1440
+ if (typeof vODataBase === "string") {
1441
+ oWrapper = PageBuildingService._createODataWrapper(vODataBase, this);
1442
+ } else {
1443
+ oWrapper = vODataBase;
1444
+ }
1445
+
1446
+ /*
1447
+ * Add cache buster token maps as property of the corresponding method.
1448
+ * Entries must look like:
1449
+ * key: ID of entity
1450
+ * value: cache buster token
1451
+ */
1452
+ this.readAllCatalogs.cacheBusterTokens = new Utils.Map();
1453
+ this.readPageSet.cacheBusterTokens = new Utils.Map();
1454
+
1455
+ /*
1456
+ * Enable sticky session in non PERS scopes: All operations in PERS should be
1457
+ * faster and synchronous than in CONF and CUST. So the user must be really
1458
+ * fast to obtain an error because of load balancing inconsistencies. Another
1459
+ * reason is client-side caching. If the response is cached, the load balancing
1460
+ * mechanism may be bypassed. This may not be fine for users of the launchpad.
1461
+ */
1462
+ if (!oWrapper.isStickySessionEnabled() && !bIsPersonalization) {
1463
+ oWrapper.enableStickySession();
1464
+ }
1465
+
1466
+ ODataService.call(this, oWrapper, fnDefaultFailure);
1467
+ };
1468
+
1469
+
1470
+ PageBuildingService._createODataWrapper = function (vODataBase, base) {
1471
+ return new ODataWrapper(vODataBase, base, /*bSupportsChangeSets=*/true);
1472
+ };
1473
+
1474
+ // public factory function ***************************************************
1475
+
1476
+
1477
+ /**
1478
+ * Constructs a facade to the page building service with the given base URI.
1479
+ *
1480
+ * @param {string} sBaseUri
1481
+ * base URI of the page building service
1482
+ * @param {function (string)} [fnDefaultFailure]
1483
+ * default error handler, taking an error message
1484
+ * @param {boolean} [bIsPersonalization=false]
1485
+ * defines the return value of {@link PageBuildingService#isPersonalization} of
1486
+ * the returned instance (since 1.16.1)
1487
+ * @returns {PageBuildingService}
1488
+ * a facade to the page building service
1489
+ * @since 1.2.0
1490
+ *
1491
+ * @see PageBuildingService
1492
+ */
1493
+ PageBuildingService.createPageBuildingService = function (sBaseUri, fnDefaultFailure, bIsPersonalization) {
1494
+ return new PageBuildingService(sBaseUri, fnDefaultFailure, bIsPersonalization);
1495
+ };
1496
+
1497
+ return PageBuildingService;
1498
+ }, true);