@sapui5/sap.ushell_abap 1.94.1 → 1.97.0

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 +574 -454
  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 +718 -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 +951 -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 +31 -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,930 @@
1
+ // Copyright (c) 2009-2021 SAP SE. All rights reserved.
2
+
3
+ /**
4
+ * @fileOverview A wrapper for a catalog loaded from the page building service.
5
+ */
6
+
7
+
8
+ sap.ui.define([
9
+ "sap/ushell_abap/pbServices/ui2/Error",
10
+ "sap/ushell_abap/pbServices/ui2/Utils",
11
+ "sap/base/Log"
12
+ ], function (
13
+ SrvcError,
14
+ Utils,
15
+ Log
16
+ ) {
17
+ "use strict";
18
+
19
+ /**
20
+ * @namespace The namespace for services related to page building and CHIP implementation.
21
+ * @since 1.2.0
22
+ */
23
+
24
+ // "public class" ************************************************************
25
+
26
+ /**
27
+ * Constructs a new representation (wrapper) of the CHIP catalog with the given
28
+ * ID to be loaded from the given factory's page building service.
29
+ * <p>
30
+ * Initially a stub is created, which can later load its properties and related objects
31
+ * asynchronously.
32
+ * <p>
33
+ * Catalogs are currently read-only and cannot be updated through the page building service.
34
+ *
35
+ * @param {sap.ushell_abap.pbServices.ui2.Factory} oFactory
36
+ * the factory
37
+ * @param {object|string} vCatalogData
38
+ * the catalog's ID or its catalog data as loaded via page building service
39
+ *
40
+ * @class
41
+ * @see sap.ushell_abap.pbServices.ui2.PageBuildingService
42
+ * @see sap.ushell_abap.pbServices.ui2.Chip
43
+ * @since 1.2.0
44
+ */
45
+ var Catalog = function (oFactory, vCatalogData) {
46
+ var oAlterEgo, // catalog's representation with all relations removed
47
+ oCatalogPage,
48
+ aChips = [],
49
+ oReadPromise, // if existing and in state "pending", a load/refresh is running; see read
50
+ bIsStub = true, //TODO replace by aChips === undefined
51
+ oCachedRemoteErrorArgs,
52
+ sId,
53
+ oReadRegisteredChipsPromise, // see readRegisteredChips
54
+ aRegisteredChipIds = [],
55
+ that = this;
56
+
57
+ // BEWARE: constructor code below!
58
+
59
+ // "private" methods ---------------------------------------------------------
60
+ /**
61
+ * Makes sure the given page is not just a stub.
62
+ *
63
+ * @private
64
+ */
65
+ function checkStub () {
66
+ if (bIsStub) {
67
+ throw new SrvcError(that + ": page is just a stub", "Page");
68
+ }
69
+ }
70
+
71
+ /**
72
+ * Makes sure that not only the catalog's ID is known, but at least its alter ego.
73
+ *
74
+ * @private
75
+ */
76
+ function checkAlterEgo () {
77
+ if (!oAlterEgo) {
78
+ throw new SrvcError(that + ": catalog is just an ID", "Catalog");
79
+ }
80
+ }
81
+
82
+ /**
83
+ * Releases all resources associated with this catalog. Call this method just before you stop
84
+ * using it.
85
+ *
86
+ * @private
87
+ */
88
+ this.exit = function () {
89
+ var sToString = that.toString();
90
+
91
+ //TODO exit() catalog's CHIPs?! what about oReadRegisteredChipsPromise then?
92
+ if (oCatalogPage) {
93
+ oCatalogPage.exit(); //TODO make Page#exit also remove its API?! cf. below
94
+ }
95
+
96
+ // reset to initial state, but leave ID intact!
97
+ oAlterEgo = undefined;
98
+ vCatalogData = undefined;
99
+ aChips = [];
100
+ bIsStub = true;
101
+ oReadPromise = undefined;
102
+ oReadRegisteredChipsPromise = undefined;
103
+ aRegisteredChipIds = [];
104
+
105
+ // delete methods on deleted catalog to prevent wrong behavior
106
+ Object.keys(that).forEach(function (sFunctionName) {
107
+ if (!/getCatalogData|getId|isStub|toString/.test(sFunctionName)) {
108
+ delete that[sFunctionName];
109
+ }
110
+ });
111
+
112
+ oFactory.forgetCatalog(that);
113
+
114
+ Log.debug("Exited: " + sToString, null, "Catalog");
115
+ };
116
+
117
+ /*
118
+ * Gets this catalog's remote base URL.
119
+ * @returns {string}
120
+ * @private
121
+ */
122
+ this.getRemoteBaseUrl = function () {
123
+ return that.addSystemToServiceUrl(oAlterEgo.type === "H"
124
+ ? "/sap/hba/apps/kpi/s/odata/hana_chip_catalog.xsodata/"
125
+ : oAlterEgo.baseUrl);
126
+ };
127
+
128
+ /*
129
+ * Gets the remote catalog service.
130
+ *
131
+ * @returns {sap.ushell_abap.pbServices.ui2.RemoteCatalogService}
132
+ * @private
133
+ */
134
+ this.getRemoteCatalogService = function () {
135
+ return oFactory.getRemoteCatalogService(oAlterEgo) || {
136
+ readChips: function (sBaseUrl, sCatalogId, aChipIds, fnSuccess, fnFailure) {
137
+ Log.error("Catalog '" + oAlterEgo.id + "', type '" + oAlterEgo.type
138
+ + "' not supported", null, "Catalog");
139
+ // fake an empty response to make the catalog valid
140
+ // When created with alterEgo, we're still synchronous, so make it async
141
+ Utils.callHandler(fnSuccess.bind(null, { results: [] }), undefined, /*async=*/true);
142
+ }
143
+ };
144
+ };
145
+
146
+ /**
147
+ * Success handler for loading a catalog.
148
+ *
149
+ * @private
150
+ */
151
+ function initialize () {
152
+ var i, n,
153
+ aResults;
154
+
155
+ Log.debug("Loaded: " + that, null, "Catalog");
156
+ if (oAlterEgo.Chips) {
157
+ // fallback for HANA
158
+ aResults = oAlterEgo.Chips.results || oAlterEgo.Chips;
159
+ // remove relations and store catalog representation
160
+ delete oAlterEgo.Chips;
161
+
162
+ // create CHIP stubs
163
+ aChips = [];
164
+ for (i = 0, n = aResults.length; i < n; i += 1) {
165
+ aChips[i] = oFactory.createChip(aResults[i]);
166
+ }
167
+ bIsStub = false;
168
+ Log.debug("Initialized: " + that, null, "Catalog");
169
+ }
170
+
171
+ delete oAlterEgo.CatalogPage;
172
+ }
173
+
174
+ /**
175
+ * Loads the catalog from the page building service, including its title and its contained
176
+ * CHIPs (at least as stubs).
177
+ *
178
+ * If the catalog is a remote catalog, an attempt to load its chips is made.
179
+ * In this case, if the loading fails, the catalog is fully initialized ( with an empty chips collection ) and
180
+ * returned as 2nd argument of the reject handler (note that it is no longer a stub!)
181
+ *
182
+ * @param {function ()} fnSuccess
183
+ * no-args success handler
184
+ * @param {function (string, object=)} [fnFailure]
185
+ * error handler taking an error message and, since version 1.28.6, an
186
+ * optional object containing the complete error information as delivered
187
+ * by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
188
+ * for more details.
189
+ * Default: see {@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}
190
+ *
191
+ * @private
192
+ */
193
+ this.read = function (bRefresh, fnSuccess, fnFailure) {
194
+ var oDeferred;
195
+
196
+ /*
197
+ * @param {object} oResult
198
+ * the OData result from readCatalog
199
+ */
200
+ function onCatalogLoaded (oResult) {
201
+ oAlterEgo = oResult;
202
+ initialize();
203
+ oDeferred.resolve();
204
+ }
205
+
206
+ /*
207
+ * @param {object} oResult
208
+ * the OData result from readCatalogChips
209
+ */
210
+ function onChipsLoaded (oResult) {
211
+ oAlterEgo.Chips = oResult;
212
+ initialize();
213
+ oDeferred.resolve();
214
+ }
215
+
216
+ /*
217
+ * Processes the remote response from readCatalogChips.
218
+ * @param {object} oResult
219
+ * the OData result from readCatalogChips
220
+ */
221
+ function processRemoteResponse (oResult) {
222
+ oResult.results.forEach(function (oRawChip) {
223
+ oRawChip.remoteCatalogId = sId;
224
+ });
225
+ onChipsLoaded(oResult);
226
+ }
227
+
228
+ /*
229
+ * initialize the chip and reject the promise,
230
+ * called when subsequent loading from a remote catalog fails
231
+ * @param {string} sErrMsg
232
+ * an error message from a failure
233
+ * @param {object} [oErrDetails]
234
+ * (since version 1.28.6) an optional object containing the complete
235
+ * error information as
236
+ * delivered by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
237
+ * for more details.
238
+ */
239
+ function couldNotLoadRemoteChips () {
240
+ initialize(); // fail gracefully
241
+ oCachedRemoteErrorArgs = arguments;
242
+ oDeferred.reject.apply(this, arguments);
243
+ }
244
+ /*
245
+ * Processes the local response from readCatalog. Passes it on to initialize or requests the
246
+ * CHIPS from the remote server.
247
+ * @param {object} oResult
248
+ * the OData result from the readCatalog
249
+ */
250
+ function processLocalResponse (oResult) {
251
+ var sRemoteBaseUrl;
252
+ if (oResult.remoteId) { //TODO || oResult.type === "REMOTE"
253
+ oAlterEgo = oResult;
254
+ try {
255
+ sRemoteBaseUrl = that.getRemoteBaseUrl();
256
+ } catch (e) {
257
+ couldNotLoadRemoteChips(e.toString());
258
+ return;
259
+ }
260
+ that.getRemoteCatalogService().readChips(sRemoteBaseUrl, oAlterEgo.remoteId, undefined,
261
+ processRemoteResponse, couldNotLoadRemoteChips);
262
+ } else if (oAlterEgo && bRefresh) {
263
+ onChipsLoaded(oResult.Chips);
264
+ } else {
265
+ onCatalogLoaded(oResult);
266
+ }
267
+ }
268
+
269
+ if (!oReadPromise || oReadPromise.state() !== "pending") {
270
+ oDeferred = new jQuery.Deferred();
271
+ oReadPromise = oDeferred.promise();
272
+ if (!oAlterEgo || (bRefresh && !oAlterEgo.remoteId)) {
273
+ // read the local catalog if it is unknown yet or if refreshing a non-remote catalog
274
+ oFactory.getPageBuildingService().readCatalog(sId, processLocalResponse,
275
+ oDeferred.reject.bind(oDeferred));
276
+ } else {
277
+ processLocalResponse.bind(this)(oAlterEgo);
278
+ }
279
+ }
280
+ fnFailure = fnFailure || oFactory.getPageBuildingService().getDefaultErrorHandler();
281
+ //TODO this needs "sap.ushell_abap.pbServices.ui2.utils" which is never required!
282
+ oReadPromise.done(Utils.callHandler.bind(null, fnSuccess, fnFailure));
283
+ oReadPromise.fail(fnFailure);
284
+ };
285
+
286
+ // "public" methods ----------------------------------------------------------
287
+
288
+ /**
289
+ * Makes the given server-relative service URL point to the system given as parameter
290
+ * <code>sSystem</code> or to the system from which the catalog
291
+ * loaded its CHIPs if <code>sSystem</code> is empty.
292
+ * <em>Server-relative URL</em> means a URL starting with exactly one "/" (also known as
293
+ * absolute-path URL).
294
+ * <p>
295
+ *
296
+ * The system is added via segment parameter <code>o</code> to the last URL segment of the
297
+ * service URL. It is also possible to make this function put the system to a different
298
+ * URL path segment of the service URL by specifying the empty segment parameter
299
+ * <code>o</code>. If both <code>sSystem</code> is empty and the catalog is a local
300
+ * catalog, no system is added and the empty segment parameter <code>o</code> is removed.
301
+ * <br/>
302
+ * <b>Example 1:</b> <code>/sap/opu/odata/MyService/?p1=v1</code> is converted to
303
+ * <code>/sap/opu/odata/MyService;o=SYS/?p1=v1</code> if the catalog is a remote catalog with
304
+ * system ID &quot;SYS&quot;.
305
+ * However it remains unchanged if the catalog is not remote <em>and</em>
306
+ * the parameter <code>sSystem</code> is empty.<br/>
307
+ * <b>Example 2:</b> <code>/sap/opu/odata/MyService;o=/MyEntities/$count?p1=v1</code> is
308
+ * converted to <code>/sap/opu/odata/MyService;o=sid(SYS.123)/MyEntities/$count?p1=v1</code> if
309
+ * parameter <code>sSystem</code> is set to &quot;sid(SYS.123)&quot;</code>.
310
+ *
311
+ * The URL is in no way normalized.
312
+ *
313
+ * @private
314
+ * @param {string} sServiceUrl
315
+ * a server-relative service URL (to be used when addressing the system directly)
316
+ * @param {string} [sSystem]
317
+ * a system specification like <code>SYS</code> or <code>sid(SYS.123)</code>; if empty the
318
+ * system from which the catalog loaded its CHIPs is used
319
+ * @returns {string}
320
+ * the service URL pointing to the system specified in parameter <code>sSystem</code> or to
321
+ * the catalog's system
322
+ * @throws Error if the URL is not server-relative (such as <code>./something</code>,
323
+ * <code>http://foo.bar/something</code>, ...)
324
+ */
325
+ this.addSystemToServiceUrl = function (sServiceUrl, sSystem) {
326
+ /*jslint regexp:true */
327
+ if (sServiceUrl.indexOf("/") !== 0 || sServiceUrl.indexOf("//") === 0) {
328
+ throw new SrvcError("addSystemToServiceUrl: Invalid URL: " + sServiceUrl,
329
+ "Catalog");
330
+ }
331
+ sSystem = sSystem || this.getSystemAlias();
332
+ //eslint-disable-next-line
333
+ if (/^[^?]*(;o=([\/;?]|$))/.test(sServiceUrl)) {
334
+ // URL with ";o=" *not* followed by system: insert system
335
+ //eslint-disable-next-line
336
+ sServiceUrl = sServiceUrl.replace(/;o=([\/;?]|$)/, (sSystem ? ";o=" + sSystem : "") + "$1");
337
+ //eslint-disable-next-line
338
+ } else if (!/^[^?]*;o=/.test(sServiceUrl) && sSystem) {
339
+ // URL without ";o=": append system
340
+ sServiceUrl = sServiceUrl.replace(/(\/[^?]*?)(\/$|$|(\/?\?.*))/,
341
+ "$1;o=" + sSystem + "$2");
342
+ }
343
+ if (sap.ui) {
344
+ sap.ui.getCore().getEventBus().publish("sap.ushell.Container",
345
+ "addRemoteSystemForServiceUrl", sServiceUrl); //{ sValue : sServiceUrl }
346
+ }
347
+ return sServiceUrl;
348
+ };
349
+
350
+ /**
351
+ * Creates a new catalog in the backend as a clone of this catalog, using the given domain ID.
352
+ * All copied catalog CHIPs are references (see {@link sap.ushell_abap.pbServices.ui2.Chip#isReference})
353
+ * until they are changed (copy on write).
354
+ * Changes to the original CHIPs will be visible in the catalog copy after the next read.
355
+ * The success handler is called as soon as the clone has been created and the new
356
+ * <code>sap.ushell_abap.pbServices.ui2.Catalog</code> object is not a stub anymore. Access the
357
+ * <code>sap.ushell_abap.pbServices.ui2.Catalog</code> instance passed to the success callback in order to learn
358
+ * the resulting ID!
359
+ * <p>
360
+ * Can be called no matter whether this catalog is still a stub. For remote catalogs where
361
+ * only the ID is known, this method currently fails!
362
+ *
363
+ * @param {string} sNewDomainId
364
+ * the new catalog's domain-specific ID which must not contain a colon
365
+ * @param {string} [sNewTitle]
366
+ * the new catalog's title; if <code>undefined</code>, this catalog's title will be used
367
+ * @param {function (sap.ushell_abap.pbServices.ui2.Catalog)} fnSuccess
368
+ * success handler for asynchronous creation
369
+ * @param {function (string, sap.ushell_abap.pbServices.ui2.Catalog=, object=)} fnFailure
370
+ * error handler, taking an error message, an optional {@link sap.ushell_abap.pbServices.ui2.Catalog}
371
+ * instance and, since version 1.28.6, an optional object containing the
372
+ * complete error information.<br />
373
+ * See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
374
+ * for more details about the complete error information parameter.
375
+ *
376
+ * @see #getCatalogPage
377
+ * @since 1.19.1
378
+ */
379
+ this.clone = function (sNewDomainId, sNewTitle, fnSuccess, fnFailure) {
380
+ var oCatalogData,
381
+ /*
382
+ * keeps calls to failure handler consistent with failure handler calls
383
+ * in sap.ushell_abap.pbServices.ui2.Factory#createNewCatalog
384
+ */
385
+ fnFailureWrapper = function (sErrorMessage, oMaybeErrorInformation) {
386
+ return fnFailure(sErrorMessage, undefined,
387
+ oMaybeErrorInformation);
388
+ };
389
+
390
+ if (oAlterEgo && oAlterEgo.type === "REMOTE") {
391
+ oCatalogData = this.getCatalogData();
392
+ delete oCatalogData.id;
393
+ oCatalogData.domainId = sNewDomainId;
394
+ if (sNewTitle !== undefined) {
395
+ oCatalogData.title = sNewTitle;
396
+ }
397
+ oFactory.createNewCatalog(oCatalogData, fnSuccess, fnFailure);
398
+ } else {
399
+ oFactory.getPageBuildingService().cloneCatalog(this.getId(), sNewDomainId, sNewTitle,
400
+ function (oRawCatalog) {
401
+ // Note: Chips relation is deferred, Catalog cannot handle this, thus use ID only!
402
+ oFactory.createCatalog(oRawCatalog.id, fnSuccess, fnFailureWrapper);
403
+ }, fnFailureWrapper);
404
+ }
405
+ };
406
+
407
+ /**
408
+ * Returns all of this catalog's properties or <code>undefined</code> if only the catalog's ID
409
+ * is known.
410
+ *
411
+ * @returns {object}
412
+ * all of this catalog's properties, e.g.
413
+ * <pre>
414
+ * {
415
+ * baseUrl: "/sap/hba/apps/kpi/s/odata/hana_chip_catalog.xsodata/",
416
+ * domainId: "Z_REMOTE_HANA_CATALOG",
417
+ * remoteId: "HANA_CATALOG",
418
+ * systemAlias: "sanssouci",
419
+ * title: "Remote HANA catalog",
420
+ * type: "REMOTE"
421
+ * }
422
+ * </pre>
423
+ * @since 1.19.1
424
+ *
425
+ * @see #update
426
+ * @see sap.ushell_abap.pbServices.ui2.Factory#createNewCatalog
427
+ */
428
+ this.getCatalogData = function () {
429
+ /*jslint nomen:true */
430
+ var oCatalogData;
431
+
432
+ if (!oAlterEgo) {
433
+ return undefined; // only ID is known!
434
+ }
435
+
436
+ oCatalogData = JSON.parse(JSON.stringify(oAlterEgo));
437
+ delete oCatalogData.__metadata;
438
+ return oCatalogData;
439
+ };
440
+
441
+ /**
442
+ * Returns this catalog's corresponding catalog page (typically a stub only), if any
443
+ * (see {@link sap.ushell_abap.pbServices.ui2.Factory#createNewPageBasedCatalog}).
444
+ * This method is intended to be called in a design time use case only.
445
+ * <p>
446
+ * Catalog pages are an easy way to modify catalogs. A catalog based on a catalog page is not
447
+ * only represented by a {@link sap.ushell_abap.pbServices.ui2.Catalog}, but also by a {@link sap.ushell_abap.pbServices.ui2.Page}.
448
+ * This means that you can use the {@link sap.ushell_abap.pbServices.ui2.Page} and
449
+ * {@link sap.ushell_abap.pbServices.ui2.ChipInstance} APIs to modify the catalog.
450
+ * For example, you can add a new {@link sap.ushell_abap.pbServices.ui2.Chip} as a
451
+ * {@link sap.ushell_abap.pbServices.ui2.ChipInstance} using the
452
+ * {@link sap.ushell_abap.pbServices.ui2.Page#createNewPageBasedCatalog} method.
453
+ * <p>
454
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
455
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData})!
456
+ *
457
+ * @returns {sap.ushell_abap.pbServices.ui2.Page}
458
+ * this catalog's corresponding catalog page, or <code>undefined</code> if this catalog is
459
+ * not based on a catalog page
460
+ * @since 1.19.1
461
+ */
462
+ this.getCatalogPage = function () {
463
+ checkAlterEgo();
464
+ if (oAlterEgo.type !== "P" && oAlterEgo.type !== "CATALOG_PAGE") {
465
+ return undefined; // this catalog is not based on a catalog page
466
+ }
467
+
468
+ if (!oCatalogPage) {
469
+ oCatalogPage = oFactory.createPage(sId);
470
+ }
471
+ return oCatalogPage;
472
+ };
473
+
474
+ /**
475
+ * Returns this catalog's CHIPs (typically stubs only). Can be called only if the catalog
476
+ * itself is not a stub anymore.
477
+ *
478
+ * @returns {sap.ushell_abap.pbServices.ui2.Chip[]}
479
+ * this catalog's CHIPs
480
+ * @since 1.2.0
481
+ *
482
+ * @see #isStub
483
+ */
484
+ this.getChips = function () {
485
+ if (bIsStub) {
486
+ throw new SrvcError(that + ": catalog is just a stub", "Catalog");
487
+ }
488
+ return aChips.slice();
489
+ };
490
+
491
+ /**
492
+ * Returns this catalog's domain ID which represents the catalog ID without any type-specific
493
+ * prefixes (like "X-SAP-REMOTE:"). The domain ID is better human-readable than the ID (see
494
+ * {@link #getId()}). Returns <code>undefined</code> as long as only the ID of this catalog
495
+ * is known.
496
+ *
497
+ * @returns {string}
498
+ * this catalog's domain ID
499
+ * @since 1.19.1
500
+ *
501
+ * @see sap.ushell_abap.pbServices.ui2.Factory#createNewPageBasedCatalog
502
+ * @see sap.ushell_abap.pbServices.ui2.PageBuildingService#createPageBasedCatalog
503
+ */
504
+ this.getDomainId = function () {
505
+ return oAlterEgo && oAlterEgo.domainId;
506
+ };
507
+
508
+ /**
509
+ * Returns this catalog's technical ID. In contrast to {@link #getDomainId} this method returns
510
+ * the ID including type-specific prefixes (like "X-SAP-REMOTE:"). Those should not be
511
+ * displayed on a UI, for example.
512
+ *
513
+ * @returns {string}
514
+ * this catalog's technical ID including type-specific prefixes (like "X-SAP-REMOTE:")
515
+ * @since 1.2.0
516
+ */
517
+ this.getId = function () {
518
+ return sId;
519
+ };
520
+
521
+ /**
522
+ * Returns this catalog's system alias.
523
+ *
524
+ * @returns {string}
525
+ * this catalog's system alias
526
+ * @private
527
+ */
528
+ this.getSystemAlias = function () {
529
+ return (oAlterEgo && oAlterEgo.systemAlias) || undefined;
530
+ };
531
+
532
+ /**
533
+ * Returns this catalog's title.
534
+ * <p>
535
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
536
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData})!
537
+ *
538
+ * @returns {string}
539
+ * this catalog's title
540
+ * @since 1.2.0
541
+ *
542
+ * @see #isStub
543
+ */
544
+ this.getTitle = function () {
545
+ checkAlterEgo();
546
+ return oAlterEgo.title;
547
+ };
548
+
549
+ /**
550
+ * Returns this catalog's type.
551
+ * <p>
552
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
553
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData})!
554
+ *
555
+ * @returns {string}
556
+ * this catalog's type
557
+ * @since 1.16.4
558
+ */
559
+ this.getType = function () {
560
+ checkAlterEgo();
561
+ return oAlterEgo && oAlterEgo.type;
562
+ };
563
+
564
+ /**
565
+ * Tells whether this catalog is marked as outdated. For a catalog based on a catalog page
566
+ * (see {@link #getCatalogPage}), this means that the catalog page is marked as outdated
567
+ * (see {@link sap.ushell_abap.pbServices.ui2.Page#isOutdated}).
568
+ * <p>
569
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
570
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData})!
571
+ *
572
+ * @returns {boolean}
573
+ * whether this catalog is marked as outdated
574
+ * @since 1.19.1
575
+ */
576
+ this.isOutdated = function () {
577
+ checkAlterEgo();
578
+
579
+ // Note: no use calling getCatalogPage(), it could only create a new stub
580
+ return (oCatalogPage && !oCatalogPage.isStub() && oCatalogPage.isOutdated())
581
+ || oAlterEgo.outdated === "X";
582
+ };
583
+
584
+ /**
585
+ * Tells whether this catalog is readOnly.
586
+ * <p>
587
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
588
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData})!
589
+ *
590
+ * @returns {boolean}
591
+ * true if this catalog is in read only mode
592
+ * @since 1.32.0
593
+ */
594
+ this.isReadOnly = function () {
595
+ checkStub();
596
+ return oAlterEgo.isReadOnly === "X";
597
+ };
598
+
599
+ /**
600
+ * Tells whether this catalog is still only a stub and does not yet know its CHIPs or title.
601
+ *
602
+ * @returns {boolean}
603
+ * whether this catalog is still only a stub
604
+ * @since 1.2.0
605
+ *
606
+ * @see #load
607
+ */
608
+ this.isStub = function () {
609
+ return bIsStub;
610
+ };
611
+
612
+ /**
613
+ * In case of a remote catalog which failed for some reason to read its CHIPs
614
+ * (see {@link #readChips}), this method can be used to retrieve the original failure
615
+ * handler arguments. This is needed because of the graceful degradation (the catalog
616
+ * keeps usable and simply behaves as if it would be empty).
617
+ * Will be reset on call of {@link #update}.
618
+ *
619
+ * @returns {arguments}
620
+ * the arguments as originally received by the {@link #readChips} failure handler
621
+ * @since 1.34.0
622
+ *
623
+ * @see #readChips
624
+ */
625
+ this.getCachedRemoteFailureArguments = function () {
626
+ return oCachedRemoteErrorArgs;
627
+ };
628
+
629
+ /**
630
+ * Loads the catalog from the page building service, including its title and its contained CHIPs
631
+ * (at least as stubs). Must not be called twice! If needed, call <code>refresh()</code>.
632
+ *
633
+ * @param {function ()} fnSuccess
634
+ * no-args success handler
635
+ * @param {function (string, object=)} [fnFailure]
636
+ * error handler taking an error message and, since version 1.28.6, an
637
+ * optional object containing the complete error information as delivered
638
+ * by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
639
+ * for more details.
640
+ * Default: see {@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}
641
+ * @since 1.2.0
642
+ *
643
+ * @see #isStub
644
+ * @see #refresh
645
+ */
646
+ this.load = function (fnSuccess, fnFailure) {
647
+ if (!bIsStub) {
648
+ throw new SrvcError("Catalog is not a stub anymore", "Catalog");
649
+ }
650
+ this.read(false, fnSuccess, fnFailure);
651
+ };
652
+
653
+ /**
654
+ * Reads all CHIPs into the factory's CHIP cache. The catalog itself remains unchanged. This
655
+ * method may be called even if the catalog is a stub.
656
+ *
657
+ * @param {string[]} aChipIds
658
+ * the IDs of the CHIPs to be read.
659
+ * @param {function ()} fnSuccess
660
+ * no-args success handler
661
+ * @param {function (string, object=)} [fnFailure]
662
+ * error handler taking an error message and, since version 1.28.6, an
663
+ * optional object containing the complete error information as delivered
664
+ * by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
665
+ * for more details. Please see also {@link #getCachedRemoteFailureArguments}.
666
+ * Default: see {@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}
667
+ * @since 1.16.4
668
+ *
669
+ * @see #getCachedRemoteFailureArguments
670
+ */
671
+ this.readChips = function (aChipIds, fnSuccess, fnFailure) {
672
+ function createChips (oRawData) {
673
+ oRawData.results.forEach(function (oRawChipData) {
674
+ oFactory.createChip(oRawChipData);
675
+ });
676
+ //TODO this needs "utils" which is never required!
677
+ Utils.callHandler(fnSuccess, fnFailure);
678
+ }
679
+
680
+ function createRemoteChips (oRawData) {
681
+ // add remoteCatalogId to each CHIP
682
+ oRawData.results.forEach(function (oRawChipData) {
683
+ oRawChipData.remoteCatalogId = sId;
684
+ });
685
+ createChips(oRawData);
686
+ }
687
+
688
+ function requestChips (oResult) {
689
+ oAlterEgo = oResult;
690
+ if (oAlterEgo.remoteId) {
691
+ this.getRemoteCatalogService().readChips(this.getRemoteBaseUrl(), oAlterEgo.remoteId, aChipIds,
692
+ createRemoteChips, fnFailure);
693
+ } else {
694
+ oFactory.getPageBuildingService().readCatalogChips(sId, aChipIds, createChips, fnFailure);
695
+ }
696
+ }
697
+
698
+ if (!oAlterEgo) {
699
+ // ensure that we have the alter ego to know type and remoteId, but do not load CHIPs
700
+ oFactory.getPageBuildingService().readCatalog(sId, requestChips.bind(this), fnFailure, true);
701
+ } else {
702
+ requestChips.bind(this)(oAlterEgo);
703
+ }
704
+ };
705
+
706
+ /**
707
+ * Reads all registered CHIPs using {@link #readChips}. The catalog itself remains unchanged.
708
+ * This method may be called even if the catalog is a stub.
709
+ * @param {function ()} fnSuccess
710
+ * no-args success handler
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 sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
715
+ * for more details.
716
+ * Default: see {@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}
717
+ * @since 1.19.0
718
+ * @private
719
+
720
+ * @see #readChips
721
+ * @see #registerChip
722
+ */
723
+ this.readRegisteredChips = function (fnSuccess, fnFailure) {
724
+ function start () {
725
+ var oDeferred = new jQuery.Deferred(),
726
+ aChipIds = aRegisteredChipIds;
727
+
728
+ aRegisteredChipIds = [];
729
+ if (aChipIds.length) {
730
+ that.readChips(aChipIds, oDeferred.resolve.bind(oDeferred),
731
+ oDeferred.reject.bind(oDeferred));
732
+ } else {
733
+ oDeferred.resolve();
734
+ }
735
+ return oDeferred.promise();
736
+ }
737
+
738
+ if (!oReadRegisteredChipsPromise || oReadRegisteredChipsPromise.state() !== "pending") {
739
+ oReadRegisteredChipsPromise = start();
740
+ }
741
+ fnFailure = fnFailure || oFactory.getPageBuildingService().getDefaultErrorHandler();
742
+ //TODO this needs "utils" which is never required!
743
+ oReadRegisteredChipsPromise.fail(fnFailure)
744
+ .done(Utils.callHandler.bind(null, fnSuccess, fnFailure));
745
+ };
746
+
747
+ /**
748
+ * Refreshes the catalog's CHIPs by reading them (again) from the backend. The catalog may be a
749
+ * stub before refresh (since 1.19.0), but is not a stub anymore once refresh succeeds.
750
+ * <p>
751
+ * When a catalog is still a stub, <code>refresh</code> is the same as <code>load</code>. When
752
+ * the catalog has been loaded before, <code>refresh</code> fetches only the CHIPs.
753
+ *
754
+ * @param {function ()} fnSuccess
755
+ * no-args success handler
756
+ * @param {function (string, object=)} [fnFailure]
757
+ * error handler taking an error message and, since version 1.28.6, an
758
+ * optional object containing the complete error information as delivered
759
+ * by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
760
+ * for more details.
761
+ * Default: see {@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}
762
+ * @since 1.11.0
763
+ *
764
+ * @see #load
765
+ */
766
+ this.refresh = function (fnSuccess, fnFailure) {
767
+ this.read(true, fnSuccess, fnFailure);
768
+ };
769
+
770
+ /**
771
+ * Registers a CHIP to be read later via {@link #readRegisteredChips}.
772
+ *
773
+ * @param {sap.ushell_abap.pbServices.ui2.Chip} oChip
774
+ * the CHIP to be registered
775
+ * @since 1.19.0
776
+ * @private
777
+ */
778
+ this.registerChip = function (oChip) {
779
+ if (oReadRegisteredChipsPromise && oReadRegisteredChipsPromise.state() === "pending") {
780
+ throw new SrvcError(
781
+ "Invalid state: registerChip while readRegisteredChips pending",
782
+ "Catalog"
783
+ );
784
+ }
785
+ aRegisteredChipIds.push(oChip.getId());
786
+ };
787
+
788
+ /**
789
+ * Removes this catalog by deleting it within the page building service. Also deletes the
790
+ * corresponding catalog page, if applicable (see {@link #getCatalogPage} and
791
+ * {@link sap.ushell_abap.pbServices.ui2.Factory#createNewPageBasedCatalog}).
792
+ * <p>
793
+ * <b>BEWARE:</b> Do not continue to use this object afterwards!
794
+ * <p>
795
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
796
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData}) or if the
797
+ * catalog is being refreshed currently (see {@link #refresh})!
798
+ *
799
+ * @param {function ()} [fnSuccess]
800
+ * no-args success handler
801
+ * @param {function (string, object=)} [fnFailure]
802
+ * error handler taking an error message and, since version 1.28.6, an
803
+ * optional object containing the complete error information as delivered
804
+ * by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
805
+ * for more details.
806
+ * If not given
807
+ * <code>{@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}</code> is used
808
+ * @since 1.19.1
809
+ */
810
+ this.remove = function (fnSuccess, fnFailure) {
811
+ checkAlterEgo();
812
+ if (oReadPromise && oReadPromise.state() === "pending") {
813
+ throw new SrvcError("Catalog is being refreshed: " + this,
814
+ "Catalog");
815
+ }
816
+
817
+ Log.debug("Removing: " + this, null, "Catalog");
818
+ oFactory.getPageBuildingService().deleteCatalog(oAlterEgo, function () {
819
+ this.exit();
820
+ fnSuccess();
821
+ }.bind(this), fnFailure);
822
+ };
823
+
824
+ /**
825
+ * Returns this catalog's string representation.
826
+ *
827
+ * @param {boolean} [bVerbose=false]
828
+ * flag whether to show all properties
829
+ * @returns {string}
830
+ * this catalog's string representation
831
+ * @since 1.2.0
832
+ */
833
+ this.toString = function (bVerbose) {
834
+ var aResult = ['Catalog({sId:"', sId, '"', ",bIsStub:", bIsStub];
835
+ if (bVerbose) {
836
+ aResult.push(",oAlterEgo:", JSON.stringify(oAlterEgo),
837
+ ",oFactory:", oFactory.toString(bVerbose),
838
+ ",aChips:", JSON.stringify(aChips)
839
+ );
840
+ }
841
+ aResult.push("})");
842
+ return aResult.join("");
843
+ };
844
+
845
+ /**
846
+ * Updates one or more properties of this catalog in the backend based on the given raw data.
847
+ * Properties which are not given keep their current value. Keys cannot be updated this way!
848
+ * Note that for a catalog based on a catalog page ({@link #getCatalogPage}), the "title"
849
+ * property is shared between the catalog and its corresponding catalog page!
850
+ * <p>
851
+ * Can safely be called if the catalog itself is not a stub anymore ({@link #isStub}). Must
852
+ * not be called if only the catalog's ID is known (see {@link #getCatalogData})!
853
+ * <p>
854
+ * The catalog becomes a stub immediately. As soon as the update succeeds, the catalog is
855
+ * loaded automatically and only after that, the success handler is called.
856
+ * It is not wise to keep references to old CHIPs loaded from this catalog before an update
857
+ * that changes the catalog's "identity", e.g. the "remoteId" property of a remote catalog.
858
+ *
859
+ * @param {object} oCatalogData
860
+ * any subset of the catalog's properties, e.g.
861
+ * <pre>
862
+ * {
863
+ * baseUrl: "/sap/hba/apps/kpi/s/odata/hana_chip_catalog.xsodata/",
864
+ * domainId: "Z_REMOTE_HANA_CATALOG",
865
+ * remoteId: "HANA_CATALOG",
866
+ * systemAlias: "sanssouci",
867
+ * title: "Remote HANA catalog",
868
+ * type: "REMOTE"
869
+ * }
870
+ * </pre>
871
+ * @param {function ()} fnSuccess
872
+ * no-args success handler
873
+ * @param {function (string, object=)} [fnFailure]
874
+ * error handler taking an error message and, since version 1.28.6, an
875
+ * optional object containing the complete error information as delivered
876
+ * by the ODataService. See fnFailure parameter of {@link sap.ushell_abap.pbServices.ui2.ODataWrapper#onError}
877
+ * for more details.
878
+ * Default: see {@link sap.ushell_abap.pbServices.ui2.ODataService#getDefaultErrorHandler}
879
+ * @throws Error when trying to update the "__metadata" property.
880
+ * @since 1.19.1
881
+ *
882
+ * @see #getCatalogData
883
+ */
884
+ this.update = function (oCatalogData, fnSuccess, fnFailure) {
885
+ var oNewAlterEgo;
886
+
887
+ checkAlterEgo();
888
+ if (Object.hasOwnProperty.call(oCatalogData, "__metadata")) {
889
+ // ODataWrapper#update() relies on __metadata!
890
+ throw new SrvcError("Unsupported __metadata update", "Catalog");
891
+ }
892
+ oNewAlterEgo = JSON.parse(JSON.stringify(oAlterEgo));
893
+ Object.keys(oCatalogData).forEach(function (sName) {
894
+ oNewAlterEgo[sName] = oCatalogData[sName];
895
+ });
896
+
897
+ bIsStub = true;
898
+ oCachedRemoteErrorArgs = undefined;
899
+
900
+ oFactory.getPageBuildingService().updateCatalog(oNewAlterEgo, function () {
901
+ oAlterEgo = oNewAlterEgo; // update head data
902
+ this.read(true, fnSuccess, fnFailure); // if this fails, we are stuck with a stub!
903
+ }.bind(this), function () {
904
+ bIsStub = false; // update failed, e.g. wrong properties --> no change to catalog!
905
+ fnFailure = fnFailure || oFactory.getPageBuildingService().getDefaultErrorHandler();
906
+ fnFailure.apply(null, arguments); // forward call
907
+ });
908
+ };
909
+
910
+ // constructor code -------------------------------------------------------
911
+ if (typeof vCatalogData === "object") {
912
+ // direct creation
913
+ sId = vCatalogData.id;
914
+ // Robustness: we prefer remoteId over Chips in case there is both
915
+ if (vCatalogData.remoteId) {
916
+ delete vCatalogData.Chips;
917
+ }
918
+ oAlterEgo = vCatalogData;
919
+ initialize();
920
+ } else if (typeof vCatalogData === "string") {
921
+ sId = vCatalogData;
922
+ }
923
+ if (!sId) {
924
+ throw new SrvcError("Missing ID", "Catalog");
925
+ }
926
+ Log.debug("Created: " + this, null, "Catalog");
927
+ };
928
+
929
+ return Catalog;
930
+ }, true);