@openui5/sap.ui.core 1.111.2 → 1.112.2

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 (274) hide show
  1. package/.dtsgenrc +38 -0
  2. package/package.json +1 -1
  3. package/src/jquery.sap.global.js +4 -1
  4. package/src/jquery.sap.properties.js +1 -1
  5. package/src/jquery.sap.resources.js +1 -1
  6. package/src/jquery.sap.script.js +1 -1
  7. package/src/jquery.sap.storage.js +3 -3
  8. package/src/sap/base/util/deepClone.js +4 -0
  9. package/src/sap/base/util/restricted/_CancelablePromise.js +1 -1
  10. package/src/sap/base/util/restricted/_castArray.js +1 -1
  11. package/src/sap/base/util/restricted/_compact.js +1 -1
  12. package/src/sap/base/util/restricted/_curry.js +1 -1
  13. package/src/sap/base/util/restricted/_debounce.js +1 -1
  14. package/src/sap/base/util/restricted/_difference.js +1 -1
  15. package/src/sap/base/util/restricted/_differenceBy.js +1 -1
  16. package/src/sap/base/util/restricted/_differenceWith.js +1 -1
  17. package/src/sap/base/util/restricted/_flatMap.js +1 -1
  18. package/src/sap/base/util/restricted/_flatMapDeep.js +1 -1
  19. package/src/sap/base/util/restricted/_flatMapDepth.js +1 -1
  20. package/src/sap/base/util/restricted/_flatten.js +1 -1
  21. package/src/sap/base/util/restricted/_flattenDeep.js +1 -1
  22. package/src/sap/base/util/restricted/_flattenDepth.js +1 -1
  23. package/src/sap/base/util/restricted/_intersection.js +1 -1
  24. package/src/sap/base/util/restricted/_intersectionBy.js +1 -1
  25. package/src/sap/base/util/restricted/_intersectionWith.js +1 -1
  26. package/src/sap/base/util/restricted/_isEqual.js +1 -1
  27. package/src/sap/base/util/restricted/_isEqualWith.js +1 -1
  28. package/src/sap/base/util/restricted/_isNil.js +1 -1
  29. package/src/sap/base/util/restricted/_max.js +1 -1
  30. package/src/sap/base/util/restricted/_merge.js +1 -1
  31. package/src/sap/base/util/restricted/_mergeWith.js +1 -1
  32. package/src/sap/base/util/restricted/_min.js +1 -1
  33. package/src/sap/base/util/restricted/_omit.js +1 -1
  34. package/src/sap/base/util/restricted/_pick.js +1 -1
  35. package/src/sap/base/util/restricted/_pickBy.js +1 -1
  36. package/src/sap/base/util/restricted/_throttle.js +1 -1
  37. package/src/sap/base/util/restricted/_toArray.js +1 -1
  38. package/src/sap/base/util/restricted/_union.js +1 -1
  39. package/src/sap/base/util/restricted/_unionBy.js +1 -1
  40. package/src/sap/base/util/restricted/_unionWith.js +1 -1
  41. package/src/sap/base/util/restricted/_uniq.js +1 -1
  42. package/src/sap/base/util/restricted/_uniqBy.js +1 -1
  43. package/src/sap/base/util/restricted/_uniqWith.js +1 -1
  44. package/src/sap/base/util/restricted/_without.js +1 -1
  45. package/src/sap/base/util/restricted/_xor.js +1 -1
  46. package/src/sap/base/util/restricted/_xorBy.js +1 -1
  47. package/src/sap/base/util/restricted/_xorWith.js +1 -1
  48. package/src/sap/base/util/restricted/_zipObject.js +1 -1
  49. package/src/sap/base/util/restricted/_zipObjectDeep.js +1 -1
  50. package/src/sap/ui/Device.js +3 -3
  51. package/src/sap/ui/Global.js +4 -4
  52. package/src/sap/ui/VersionInfo.js +14 -0
  53. package/src/sap/ui/base/Event.js +1 -1
  54. package/src/sap/ui/base/EventProvider.js +1 -1
  55. package/src/sap/ui/base/Interface.js +1 -1
  56. package/src/sap/ui/base/ManagedObject.js +1 -1
  57. package/src/sap/ui/base/ManagedObjectMetadata.js +1 -1
  58. package/src/sap/ui/base/Metadata.js +1 -1
  59. package/src/sap/ui/base/Object.js +1 -1
  60. package/src/sap/ui/base/ObjectPool.js +1 -1
  61. package/src/sap/ui/core/.library +4 -4
  62. package/src/sap/ui/core/BusyIndicator.js +1 -1
  63. package/src/sap/ui/core/Component.js +3 -3
  64. package/src/sap/ui/core/ComponentContainer.js +1 -1
  65. package/src/sap/ui/core/ComponentMetadata.js +1 -1
  66. package/src/sap/ui/core/ComponentSupport.js +1 -1
  67. package/src/sap/ui/core/Configuration.js +14 -2
  68. package/src/sap/ui/core/Control.js +1 -1
  69. package/src/sap/ui/core/Core.js +17 -8
  70. package/src/sap/ui/core/CustomData.js +1 -1
  71. package/src/sap/ui/core/DeclarativeSupport.js +1 -1
  72. package/src/sap/ui/core/Element.js +1 -1
  73. package/src/sap/ui/core/ElementMetadata.js +1 -1
  74. package/src/sap/ui/core/EnabledPropagator.js +1 -1
  75. package/src/sap/ui/core/EventBus.js +1 -1
  76. package/src/sap/ui/core/Fragment.js +1 -1
  77. package/src/sap/ui/core/HTML.js +1 -1
  78. package/src/sap/ui/core/History.js +1 -1
  79. package/src/sap/ui/core/Icon.js +1 -1
  80. package/src/sap/ui/core/IndicationColorSupport.js +1 -1
  81. package/src/sap/ui/core/IntervalTrigger.js +1 -1
  82. package/src/sap/ui/core/InvisibleMessage.js +1 -1
  83. package/src/sap/ui/core/InvisibleRenderer.js +1 -1
  84. package/src/sap/ui/core/InvisibleText.js +1 -1
  85. package/src/sap/ui/core/Item.js +1 -1
  86. package/src/sap/ui/core/LabelEnablement.js +1 -1
  87. package/src/sap/ui/core/LayoutData.js +1 -1
  88. package/src/sap/ui/core/Lib.js +40 -28
  89. package/src/sap/ui/core/ListItem.js +1 -1
  90. package/src/sap/ui/core/LocalBusyIndicator.js +1 -1
  91. package/src/sap/ui/core/Locale.js +1 -1
  92. package/src/sap/ui/core/LocaleData.js +1 -1
  93. package/src/sap/ui/core/Manifest.js +1 -1
  94. package/src/sap/ui/core/Message.js +1 -1
  95. package/src/sap/ui/core/RenderManager.js +1 -1
  96. package/src/sap/ui/core/Renderer.js +1 -1
  97. package/src/sap/ui/core/ResizeHandler.js +1 -1
  98. package/src/sap/ui/core/ScrollBar.js +1 -1
  99. package/src/sap/ui/core/SeparatorItem.js +1 -1
  100. package/src/sap/ui/core/Title.js +1 -1
  101. package/src/sap/ui/core/TooltipBase.js +1 -1
  102. package/src/sap/ui/core/UIArea.js +1 -1
  103. package/src/sap/ui/core/UIComponent.js +1 -1
  104. package/src/sap/ui/core/UIComponentMetadata.js +1 -1
  105. package/src/sap/ui/core/ValueStateSupport.js +1 -1
  106. package/src/sap/ui/core/VariantLayoutData.js +1 -1
  107. package/src/sap/ui/core/XMLComposite.js +1 -1
  108. package/src/sap/ui/core/XMLCompositeMetadata.js +1 -1
  109. package/src/sap/ui/core/_IconRegistry.js +19 -4
  110. package/src/sap/ui/core/date/Islamic.js +1 -0
  111. package/src/sap/ui/core/date/UI5Date.js +25 -5
  112. package/src/sap/ui/core/date/UniversalDate.js +2 -0
  113. package/src/sap/ui/core/date/UniversalDateUtils.js +1 -2
  114. package/src/sap/ui/core/delegate/ItemNavigation.js +1 -1
  115. package/src/sap/ui/core/delegate/ScrollEnablement.js +1 -1
  116. package/src/sap/ui/core/dnd/DragDropBase.js +1 -1
  117. package/src/sap/ui/core/dnd/DragDropInfo.js +1 -1
  118. package/src/sap/ui/core/dnd/DragInfo.js +1 -1
  119. package/src/sap/ui/core/dnd/DropInfo.js +1 -1
  120. package/src/sap/ui/core/format/DateFormat.js +13 -15
  121. package/src/sap/ui/core/format/NumberFormat.js +6 -4
  122. package/src/sap/ui/core/format/TimezoneUtil.js +21 -17
  123. package/src/sap/ui/core/hyphenation/Hyphenation.js +3 -3
  124. package/src/sap/ui/core/library.js +3 -3
  125. package/src/sap/ui/core/message/ControlMessageProcessor.js +1 -1
  126. package/src/sap/ui/core/message/Message.js +1 -1
  127. package/src/sap/ui/core/message/MessageManager.js +1 -1
  128. package/src/sap/ui/core/message/MessageParser.js +1 -1
  129. package/src/sap/ui/core/message/MessageProcessor.js +1 -1
  130. package/src/sap/ui/core/mvc/Controller.js +1 -1
  131. package/src/sap/ui/core/mvc/ControllerExtension.js +1 -1
  132. package/src/sap/ui/core/mvc/ControllerMetadata.js +4 -3
  133. package/src/sap/ui/core/mvc/HTMLView.js +1 -1
  134. package/src/sap/ui/core/mvc/JSONView.js +1 -1
  135. package/src/sap/ui/core/mvc/JSView.js +1 -1
  136. package/src/sap/ui/core/mvc/TemplateView.js +1 -1
  137. package/src/sap/ui/core/mvc/View.js +13 -9
  138. package/src/sap/ui/core/mvc/XMLView.js +1 -1
  139. package/src/sap/ui/core/plugin/DeclarativeSupport.js +1 -1
  140. package/src/sap/ui/core/plugin/LessSupport.js +1 -1
  141. package/src/sap/ui/core/plugin/TemplatingSupport.js +1 -1
  142. package/src/sap/ui/core/postmessage/Bus.js +1 -1
  143. package/src/sap/ui/core/postmessage/confirmationDialog.js +1 -1
  144. package/src/sap/ui/core/search/OpenSearchProvider.js +1 -1
  145. package/src/sap/ui/core/search/SearchProvider.js +1 -1
  146. package/src/sap/ui/core/service/Service.js +1 -1
  147. package/src/sap/ui/core/service/ServiceFactory.js +1 -1
  148. package/src/sap/ui/core/service/ServiceFactoryRegistry.js +1 -1
  149. package/src/sap/ui/core/support/Plugin.js +1 -1
  150. package/src/sap/ui/core/support/Support.js +1 -1
  151. package/src/sap/ui/core/support/plugins/ControlTree.js +1 -1
  152. package/src/sap/ui/core/support/plugins/Interaction.js +1 -1
  153. package/src/sap/ui/core/support/plugins/LocalStorage.js +1 -1
  154. package/src/sap/ui/core/support/plugins/Performance.js +1 -1
  155. package/src/sap/ui/core/support/plugins/Selector.js +1 -1
  156. package/src/sap/ui/core/support/plugins/TechInfo.js +1 -1
  157. package/src/sap/ui/core/support/plugins/Trace.js +1 -1
  158. package/src/sap/ui/core/support/plugins/ViewInfo.js +1 -1
  159. package/src/sap/ui/core/themes/base/fonts/SAP-icons.ttf +0 -0
  160. package/src/sap/ui/core/themes/base/fonts/SAP-icons.woff2 +0 -0
  161. package/src/sap/ui/core/theming/ThemeManager.js +11 -2
  162. package/src/sap/ui/core/tmpl/DOMAttribute.js +1 -1
  163. package/src/sap/ui/core/tmpl/DOMElement.js +1 -1
  164. package/src/sap/ui/core/tmpl/HandlebarsTemplate.js +1 -1
  165. package/src/sap/ui/core/tmpl/Template.js +1 -1
  166. package/src/sap/ui/core/tmpl/TemplateControl.js +1 -1
  167. package/src/sap/ui/core/util/AsyncHintsHelper.js +1 -1
  168. package/src/sap/ui/core/util/Export.js +1 -1
  169. package/src/sap/ui/core/util/ExportCell.js +1 -1
  170. package/src/sap/ui/core/util/ExportColumn.js +1 -1
  171. package/src/sap/ui/core/util/ExportRow.js +1 -1
  172. package/src/sap/ui/core/util/ExportType.js +1 -1
  173. package/src/sap/ui/core/util/ExportTypeCSV.js +1 -1
  174. package/src/sap/ui/core/util/File.js +1 -1
  175. package/src/sap/ui/core/util/LibraryInfo.js +1 -1
  176. package/src/sap/ui/core/util/MockServer.js +1 -1
  177. package/src/sap/ui/core/util/PasteHelper.js +1 -1
  178. package/src/sap/ui/core/util/serializer/HTMLViewSerializer.js +1 -1
  179. package/src/sap/ui/core/util/serializer/Serializer.js +1 -1
  180. package/src/sap/ui/core/util/serializer/ViewSerializer.js +3 -3
  181. package/src/sap/ui/core/util/serializer/XMLViewSerializer.js +1 -1
  182. package/src/sap/ui/core/util/serializer/delegate/Delegate.js +1 -1
  183. package/src/sap/ui/core/util/serializer/delegate/HTML.js +1 -1
  184. package/src/sap/ui/core/util/serializer/delegate/XML.js +1 -1
  185. package/src/sap/ui/core/ws/ReadyState.js +1 -1
  186. package/src/sap/ui/core/ws/SapPcpWebSocket.js +1 -1
  187. package/src/sap/ui/core/ws/WebSocket.js +2 -2
  188. package/src/sap/ui/debug/ControlTree.js +1 -1
  189. package/src/sap/ui/debug/DebugEnv.js +1 -1
  190. package/src/sap/ui/debug/PropertyList.js +1 -1
  191. package/src/sap/ui/model/ClientModel.js +1 -1
  192. package/src/sap/ui/model/CompositeDataState.js +1 -1
  193. package/src/sap/ui/model/CompositeType.js +1 -1
  194. package/src/sap/ui/model/DataState.js +1 -1
  195. package/src/sap/ui/model/MetaModel.js +1 -1
  196. package/src/sap/ui/model/Model.js +1 -1
  197. package/src/sap/ui/model/SelectionModel.js +1 -1
  198. package/src/sap/ui/model/SimpleType.js +1 -1
  199. package/src/sap/ui/model/TreeAutoExpandMode.js +1 -1
  200. package/src/sap/ui/model/Type.js +1 -1
  201. package/src/sap/ui/model/json/JSONModel.js +1 -1
  202. package/src/sap/ui/model/message/MessageModel.js +1 -1
  203. package/src/sap/ui/model/odata/ODataAnnotations.js +1 -1
  204. package/src/sap/ui/model/odata/ODataMessageParser.js +1 -1
  205. package/src/sap/ui/model/odata/ODataMetaModel.js +4 -3
  206. package/src/sap/ui/model/odata/ODataMetadata.js +1 -1
  207. package/src/sap/ui/model/odata/ODataModel.js +1 -1
  208. package/src/sap/ui/model/odata/ODataUtils.js +5 -2
  209. package/src/sap/ui/model/odata/_ODataMetaModelUtils.js +62 -24
  210. package/src/sap/ui/model/odata/type/Boolean.js +1 -1
  211. package/src/sap/ui/model/odata/type/Byte.js +1 -1
  212. package/src/sap/ui/model/odata/type/Currency.js +1 -1
  213. package/src/sap/ui/model/odata/type/Date.js +1 -1
  214. package/src/sap/ui/model/odata/type/DateTime.js +1 -1
  215. package/src/sap/ui/model/odata/type/DateTimeBase.js +3 -2
  216. package/src/sap/ui/model/odata/type/DateTimeOffset.js +1 -1
  217. package/src/sap/ui/model/odata/type/DateTimeWithTimezone.js +2 -1
  218. package/src/sap/ui/model/odata/type/Decimal.js +1 -1
  219. package/src/sap/ui/model/odata/type/Double.js +1 -1
  220. package/src/sap/ui/model/odata/type/Guid.js +1 -1
  221. package/src/sap/ui/model/odata/type/Int.js +1 -1
  222. package/src/sap/ui/model/odata/type/Int16.js +1 -1
  223. package/src/sap/ui/model/odata/type/Int32.js +1 -1
  224. package/src/sap/ui/model/odata/type/Int64.js +1 -1
  225. package/src/sap/ui/model/odata/type/ODataType.js +1 -1
  226. package/src/sap/ui/model/odata/type/Raw.js +1 -1
  227. package/src/sap/ui/model/odata/type/SByte.js +1 -1
  228. package/src/sap/ui/model/odata/type/Single.js +1 -1
  229. package/src/sap/ui/model/odata/type/Stream.js +1 -1
  230. package/src/sap/ui/model/odata/type/String.js +1 -1
  231. package/src/sap/ui/model/odata/type/Time.js +2 -1
  232. package/src/sap/ui/model/odata/type/TimeOfDay.js +1 -1
  233. package/src/sap/ui/model/odata/type/Unit.js +1 -1
  234. package/src/sap/ui/model/odata/v2/Context.js +1 -1
  235. package/src/sap/ui/model/odata/v2/ODataAnnotations.js +2 -1
  236. package/src/sap/ui/model/odata/v2/ODataListBinding.js +4 -1
  237. package/src/sap/ui/model/odata/v2/ODataModel.js +127 -65
  238. package/src/sap/ui/model/odata/v2/ODataTreeBinding.js +1 -1
  239. package/src/sap/ui/model/odata/v4/Context.js +50 -14
  240. package/src/sap/ui/model/odata/v4/ODataBinding.js +83 -14
  241. package/src/sap/ui/model/odata/v4/ODataContextBinding.js +2 -4
  242. package/src/sap/ui/model/odata/v4/ODataListBinding.js +89 -12
  243. package/src/sap/ui/model/odata/v4/ODataMetaModel.js +3 -2
  244. package/src/sap/ui/model/odata/v4/ODataModel.js +5 -4
  245. package/src/sap/ui/model/odata/v4/ODataParentBinding.js +14 -3
  246. package/src/sap/ui/model/odata/v4/ODataPropertyBinding.js +9 -1
  247. package/src/sap/ui/model/odata/v4/lib/_AggregationCache.js +63 -62
  248. package/src/sap/ui/model/odata/v4/lib/_AggregationHelper.js +32 -7
  249. package/src/sap/ui/model/odata/v4/lib/_Cache.js +212 -15
  250. package/src/sap/ui/model/odata/v4/lib/_Helper.js +71 -29
  251. package/src/sap/ui/model/resource/ResourceModel.js +1 -1
  252. package/src/sap/ui/model/type/Boolean.js +1 -1
  253. package/src/sap/ui/model/type/Currency.js +1 -1
  254. package/src/sap/ui/model/type/Date.js +4 -3
  255. package/src/sap/ui/model/type/DateInterval.js +9 -8
  256. package/src/sap/ui/model/type/DateTime.js +1 -1
  257. package/src/sap/ui/model/type/DateTimeInterval.js +1 -1
  258. package/src/sap/ui/model/type/FileSize.js +1 -1
  259. package/src/sap/ui/model/type/Float.js +1 -1
  260. package/src/sap/ui/model/type/Integer.js +1 -1
  261. package/src/sap/ui/model/type/String.js +1 -1
  262. package/src/sap/ui/model/type/Time.js +1 -1
  263. package/src/sap/ui/model/type/TimeInterval.js +1 -1
  264. package/src/sap/ui/model/type/Unit.js +1 -1
  265. package/src/sap/ui/model/xml/XMLModel.js +1 -1
  266. package/src/sap/ui/qunit/QUnitUtils.js +6 -4
  267. package/src/sap/ui/qunit/utils/ControlIterator.js +1 -1
  268. package/src/sap/ui/qunit/utils/MemoryLeakCheck.js +1 -1
  269. package/src/sap/ui/test/Opa5.js +4 -4
  270. package/src/sap/ui/test/generic/TestBase.js +14 -4
  271. package/src/sap/ui/thirdparty/jquery-mobile-custom.js +10 -4
  272. package/src/sap/ui/thirdparty/qunit-2.js +4 -1
  273. package/src/sap/ui/thirdparty/qunit.js +41 -11
  274. package/src/sap/ui/util/Storage.js +1 -1
@@ -211,14 +211,8 @@ sap.ui.define([
211
211
  * @see sap.ui.model.odata.v4.lib._CollectionCache#requestSideEffects
212
212
  */
213
213
  _AggregationCache.prototype.beforeUpdateSelected = function (sPredicate, oNewValue) {
214
- var oElement = this.aElements.$byPredicate[sPredicate],
215
- sNodeProperty = this.oAggregation.$NodeProperty;
216
-
217
- if (oElement[sNodeProperty] !== oNewValue[sNodeProperty]) {
218
- throw new Error("Unexpected structural change: " + sNodeProperty
219
- + " from " + JSON.stringify(oElement[sNodeProperty])
220
- + " to " + JSON.stringify(oNewValue[sNodeProperty]));
221
- }
214
+ _AggregationHelper.checkNodeProperty(this.aElements.$byPredicate[sPredicate], oNewValue,
215
+ this.oAggregation.$NodeProperty, true);
222
216
  };
223
217
 
224
218
  /**
@@ -383,12 +377,12 @@ sap.ui.define([
383
377
 
384
378
  iCount = aSpliced.length;
385
379
  this.aElements.$count = aElements.$count + iCount;
386
- aSpliced.forEach(function (oElement, i) {
380
+ aSpliced.forEach(function (oElement) {
387
381
  var sPredicate = _Helper.getPrivateAnnotation(oElement, "predicate");
388
382
 
389
383
  if (!_Helper.hasPrivateAnnotation(oElement, "placeholder")) {
390
384
  if (bStale) {
391
- that.replaceByPlaceholder(iIndex + i, oElement, sPredicate);
385
+ that.turnIntoPlaceholder(oElement, sPredicate);
392
386
  } else {
393
387
  that.aElements.$byPredicate[sPredicate] = oElement;
394
388
  if (_Helper.hasPrivateAnnotation(oElement, "expanding")) {
@@ -617,7 +611,7 @@ sap.ui.define([
617
611
 
618
612
  /**
619
613
  * Determines the list of elements determined by the given predicates. All other elements are
620
- * replaced by placeholders (lazily).
614
+ * turned into placeholders (lazily).
621
615
  *
622
616
  * @param {string[]} aPredicates
623
617
  * The key predicates of the elements to request side effects for
@@ -636,7 +630,7 @@ sap.ui.define([
636
630
  mPredicates[sPredicate] = true;
637
631
  });
638
632
 
639
- return this.aElements.filter(function (oElement, i) {
633
+ return this.aElements.filter(function (oElement) {
640
634
  var sPredicate = _Helper.getPrivateAnnotation(oElement, "predicate");
641
635
 
642
636
  if (mPredicates[sPredicate]) {
@@ -644,7 +638,7 @@ sap.ui.define([
644
638
  return true; // keep and request
645
639
  }
646
640
 
647
- that.replaceByPlaceholder(i, oElement, sPredicate);
641
+ that.turnIntoPlaceholder(oElement, sPredicate);
648
642
  });
649
643
  };
650
644
 
@@ -783,19 +777,28 @@ sap.ui.define([
783
777
  * @private
784
778
  */
785
779
  _AggregationCache.prototype.readCount = function (oGroupLock) {
786
- var fnResolve = this.oCountPromise && this.oCountPromise.$resolve,
787
- sResourcePath = this.sResourcePath + "/$count",
788
- sSeparator = "?";
780
+ var mQueryOptions,
781
+ fnResolve = this.oCountPromise && this.oCountPromise.$resolve,
782
+ sResourcePath;
789
783
 
790
784
  if (fnResolve) {
791
785
  delete this.oCountPromise.$resolve;
792
- if (this.mQueryOptions.$filter) {
793
- sResourcePath += "?$filter=" + this.mQueryOptions.$filter;
794
- sSeparator = "&";
795
- }
786
+
787
+ mQueryOptions = Object.assign({}, this.mQueryOptions);
788
+ // // drop collection related system query options (except $filter,$search)
789
+ delete mQueryOptions.$apply;
790
+ delete mQueryOptions.$count;
791
+ // keep mQueryOptions.$filter;
792
+ delete mQueryOptions.$expand;
793
+ delete mQueryOptions.$orderby;
796
794
  if (this.oAggregation.search) {
797
- sResourcePath += sSeparator + "$search=" + this.oAggregation.search;
795
+ // Note: A recursive hierarchy cannot be combined with "$search"
796
+ mQueryOptions.$search = this.oAggregation.search;
798
797
  }
798
+ delete mQueryOptions.$select;
799
+ // Note: sMetaPath only needed for $filter by V42, but V42 cannot work here!
800
+ sResourcePath = this.sResourcePath + "/$count"
801
+ + this.oRequestor.buildQueryString(/*sMetaPath*/null, mQueryOptions);
799
802
 
800
803
  return this.oRequestor.request("GET", sResourcePath, oGroupLock.getUnlockedCopy())
801
804
  .then(fnResolve); // Note: $count is already of type number here
@@ -964,51 +967,41 @@ sap.ui.define([
964
967
  _AggregationCache.prototype.refreshKeptElements = function () {};
965
968
 
966
969
  /**
967
- * Replaces the given element, which is at the given position and has the given predicate, with
968
- * a placeholder which keeps all private annotations plus the hierarchy node value. The original
969
- * element is removed from its corresponding cache and must not be used any longer.
970
+ * Returns the cache's URL.
971
+ *
972
+ * @returns {string} The URL
973
+ *
974
+ * @public
975
+ * @see sap.ui.model.odata.v4.lib._AggregationCache#getDownloadUrl
976
+ */
977
+ // @override sap.ui.model.odata.v4.lib._Cache#toString
978
+ _AggregationCache.prototype.toString = function () {
979
+ return this.sDownloadUrl;
980
+ };
981
+
982
+ /**
983
+ * Turns the given element, which has the given predicate, into a placeholder which keeps all
984
+ * private annotations plus the hierarchy node value. The original element is removed from its
985
+ * corresponding cache and must not be used any longer.
970
986
  *
971
- * @param {number} iIndex - Its index
972
987
  * @param {object} oElement - An element
973
988
  * @param {string} sPredicate - Its predicate
974
989
  *
975
990
  * @private
976
991
  */
977
- _AggregationCache.prototype.replaceByPlaceholder = function (iIndex, oElement, sPredicate) {
978
- var sNodeProperty = this.oAggregation.$NodeProperty,
979
- oPlaceholder;
980
-
992
+ _AggregationCache.prototype.turnIntoPlaceholder = function (oElement, sPredicate) {
981
993
  if (_Helper.hasPrivateAnnotation(oElement, "placeholder")) {
982
994
  return;
983
995
  }
984
996
 
997
+ _Helper.setPrivateAnnotation(oElement, "placeholder", 1); // not an initial placeholder
985
998
  _AggregationHelper.markSplicedStale(oElement);
986
- this.aElements[iIndex] = oPlaceholder = {
987
- "@$ui5._" : Object.assign(oElement["@$ui5._"], {placeholder : true}),
988
- "@$ui5.node.isExpanded" : oElement["@$ui5.node.isExpanded"],
989
- "@$ui5.node.level" : oElement["@$ui5.node.level"]
990
- };
991
- oPlaceholder[sNodeProperty] = oElement[sNodeProperty];
992
999
  delete this.aElements.$byPredicate[sPredicate];
993
-
994
1000
  // drop original element from its cache's collection
995
1001
  _Helper.getPrivateAnnotation(oElement, "parent")
996
1002
  .drop(_Helper.getPrivateAnnotation(oElement, "index"), sPredicate);
997
1003
  };
998
1004
 
999
- /**
1000
- * Returns the cache's URL.
1001
- *
1002
- * @returns {string} The URL
1003
- *
1004
- * @public
1005
- * @see sap.ui.model.odata.v4.lib._AggregationCache#getDownloadUrl
1006
- */
1007
- // @override sap.ui.model.odata.v4.lib._Cache#toString
1008
- _AggregationCache.prototype.toString = function () {
1009
- return this.sDownloadUrl;
1010
- };
1011
-
1012
1005
  //*********************************************************************************************
1013
1006
  // "static" functions
1014
1007
  //*********************************************************************************************
@@ -1099,11 +1092,10 @@ sap.ui.define([
1099
1092
  // @override sap.ui.model.odata.v4.lib._Cache#calculateKeyPredicate
1100
1093
  _AggregationCache.calculateKeyPredicateRH = function (oGroupNode, oAggregation, oElement,
1101
1094
  mTypeForMetaPath, sMetaPath) {
1102
- var sDistanceFromRootProperty = oAggregation.$DistanceFromRootProperty,
1103
- sDrillStateProperty = oAggregation.$DrillStateProperty,
1095
+ var sDistanceFromRoot,
1104
1096
  bIsExpanded,
1105
1097
  iLevel = 1,
1106
- sLimitedDescendantCountProperty = oAggregation.$LimitedDescendantCountProperty,
1098
+ sLimitedDescendantCount,
1107
1099
  sPredicate;
1108
1100
 
1109
1101
  if (!(sMetaPath in mTypeForMetaPath)) {
@@ -1116,7 +1108,7 @@ sap.ui.define([
1116
1108
  return sPredicate;
1117
1109
  }
1118
1110
 
1119
- switch (oElement[sDrillStateProperty]) {
1111
+ switch (_Helper.drillDown(oElement, oAggregation.$DrillStateProperty)) {
1120
1112
  case "expanded":
1121
1113
  bIsExpanded = true;
1122
1114
  break;
@@ -1130,21 +1122,30 @@ sap.ui.define([
1130
1122
  default: // "leaf"
1131
1123
  // bIsExpanded = undefined;
1132
1124
  }
1125
+ _Helper.deleteProperty(oElement, oAggregation.$DrillStateProperty);
1133
1126
  if (oGroupNode) {
1134
1127
  iLevel = oGroupNode["@$ui5.node.level"] + 1;
1135
- } else if (oElement[sDistanceFromRootProperty]) { // Edm.Int64
1136
- iLevel = parseInt(oElement[sDistanceFromRootProperty]) + 1;
1128
+ } else {
1129
+ sDistanceFromRoot = _Helper.drillDown(oElement, oAggregation.$DistanceFromRootProperty);
1130
+ if (sDistanceFromRoot) { // Edm.Int64
1131
+ _Helper.deleteProperty(oElement, oAggregation.$DistanceFromRootProperty);
1132
+ iLevel = parseInt(sDistanceFromRoot) + 1;
1133
+ }
1137
1134
  }
1138
1135
  // set the node values
1139
1136
  _AggregationHelper.setAnnotations(oElement, bIsExpanded, /*bIsTotal*/undefined, iLevel);
1140
- if (oElement[sLimitedDescendantCountProperty]
1141
- && oElement[sLimitedDescendantCountProperty] !== "0") { // Edm.Int64
1142
- _Helper.setPrivateAnnotation(oElement, "descendants",
1143
- parseInt(oElement[sLimitedDescendantCountProperty]));
1137
+
1138
+ if (oAggregation.$LimitedDescendantCountProperty) {
1139
+ sLimitedDescendantCount
1140
+ = _Helper.drillDown(oElement, oAggregation.$LimitedDescendantCountProperty);
1141
+ if (sLimitedDescendantCount) {
1142
+ _Helper.deleteProperty(oElement, oAggregation.$LimitedDescendantCountProperty);
1143
+ if (sLimitedDescendantCount !== "0") { // Edm.Int64
1144
+ _Helper.setPrivateAnnotation(oElement, "descendants",
1145
+ parseInt(sLimitedDescendantCount));
1146
+ }
1147
+ }
1144
1148
  }
1145
- delete oElement[sDistanceFromRootProperty];
1146
- delete oElement[sDrillStateProperty];
1147
- delete oElement[sLimitedDescendantCountProperty];
1148
1149
 
1149
1150
  return sPredicate;
1150
1151
  };
@@ -165,20 +165,20 @@ sap.ui.define([
165
165
  throw new Error("Unexpected structural change: " + sAnnotation);
166
166
  }
167
167
  });
168
- if (sNodeProperty in oPlaceholder
169
- && oPlaceholder[sNodeProperty] !== oElement[sNodeProperty]) {
170
- throw new Error("Unexpected structural change: " + sNodeProperty
171
- + " from " + JSON.stringify(oPlaceholder[sNodeProperty])
172
- + " to " + JSON.stringify(oElement[sNodeProperty]));
168
+ if (sNodeProperty) {
169
+ _AggregationHelper.checkNodeProperty(oPlaceholder, oElement, sNodeProperty);
173
170
  }
174
171
 
175
172
  _Helper.copyPrivateAnnotation(oPlaceholder, "spliced", oElement);
176
- if ("@$ui5.node.isExpanded" in oPlaceholder) {
173
+ if (_Helper.getPrivateAnnotation(oPlaceholder, "placeholder") === 1) {
177
174
  if ((oPlaceholder["@$ui5.node.isExpanded"] === undefined)
178
175
  !== (oElement["@$ui5.node.isExpanded"] === undefined)) {
179
176
  throw new Error("Not a leaf anymore (or vice versa)");
180
177
  }
181
- oElement["@$ui5.node.isExpanded"] = oPlaceholder["@$ui5.node.isExpanded"];
178
+ if (oPlaceholder["@$ui5.node.isExpanded"] !== undefined) {
179
+ // restore previous expansion state
180
+ oElement["@$ui5.node.isExpanded"] = oPlaceholder["@$ui5.node.isExpanded"];
181
+ }
182
182
  }
183
183
  },
184
184
 
@@ -535,6 +535,31 @@ sap.ui.define([
535
535
  return mQueryOptions;
536
536
  },
537
537
 
538
+ /**
539
+ * Checks that the NodeProperty ("the hierarchy node value") has not changed.
540
+ *
541
+ * @param {object} oOld
542
+ * The old node object
543
+ * @param {object} oNew
544
+ * The new node object
545
+ * @param {string} sNodeProperty
546
+ * The path to the property which provides the hierarchy node value
547
+ * @param {boolean} [bMandatory]
548
+ * Whether a hierarchy node value is mandatory for the old node object (else it may be
549
+ * missing because old node object is just a placeholder)
550
+ * @throws {Error} In case of a structural change
551
+ */
552
+ checkNodeProperty : function (oOld, oNew, sNodeProperty, bMandatory) {
553
+ var vNewNodeID = _Helper.drillDown(oNew, sNodeProperty),
554
+ vOldNodeID = _Helper.drillDown(oOld, sNodeProperty);
555
+
556
+ if ((bMandatory || vOldNodeID !== undefined) && vOldNodeID !== vNewNodeID) {
557
+ throw new Error("Unexpected structural change: " + sNodeProperty
558
+ + " from " + JSON.stringify(vOldNodeID)
559
+ + " to " + JSON.stringify(vNewNodeID));
560
+ }
561
+ },
562
+
538
563
  /**
539
564
  * Checks that the given value is of the given type. If <code>vType</code> is a string, then
540
565
  * <code>typeof vValue === vType<code> must hold. If <code>vType</code> is an array (of
@@ -341,6 +341,49 @@ sap.ui.define([
341
341
  this.oPendingRequestsPromise.$count += 1;
342
342
  };
343
343
 
344
+ /**
345
+ * Adds a collection below a transient element.
346
+ *
347
+ * @param {string} sPath
348
+ * The collection path
349
+ * @param {string[]} [aSelect]
350
+ * The binding's $select if it would create a cache; later used for updateSelected (either
351
+ * taking this aSelect or calculating it from the path)
352
+ * @returns {object[]}
353
+ * The elements collection (either from the initial data or empty)
354
+ * @throws {Error} If the cache is shared
355
+ *
356
+ * @public
357
+ */
358
+ _Cache.prototype.addTransientCollection = function (sPath, aSelect) {
359
+ var aElements,
360
+ aSegments = sPath.split("/"),
361
+ sName = aSegments.pop(),
362
+ oParent = this.fetchValue(_GroupLock.$cached, aSegments.join("/")).getResult(),
363
+ oPostBody = _Helper.getPrivateAnnotation(oParent, "postBody"),
364
+ that = this;
365
+
366
+ this.checkSharedRequest();
367
+ if (sName in oParent) {
368
+ throw new Error("Deep create with initial data is not supported yet");
369
+ }
370
+ aElements = oParent[sName] = [];
371
+ aElements.$count = aElements.$created = 0;
372
+ aElements.$byPredicate = {};
373
+ // allow creating on demand when there is a create in the child list
374
+ aElements.$postBodyCollection = function () {
375
+ aElements.$postBodyCollection = oPostBody[sName] = [];
376
+ };
377
+ aElements.$select = aSelect;
378
+ // add the collection type to mTypeForMetaPath
379
+ this.fetchTypes().then(function (mTypeForMetaPath) {
380
+ that.oRequestor.fetchType(mTypeForMetaPath,
381
+ that.sMetaPath + "/" + _Helper.getMetaPath(sPath));
382
+ });
383
+
384
+ return aElements;
385
+ };
386
+
344
387
  /**
345
388
  * Adjusts the indexes in the collection.
346
389
  *
@@ -407,6 +450,31 @@ sap.ui.define([
407
450
  return sPredicate;
408
451
  };
409
452
 
453
+ /**
454
+ * Cancels all nested creates within the given element.
455
+ *
456
+ * @param {object} oElement - The entity data in the cache
457
+ * @param {string} sPostPath - The request path of the POST request
458
+ * @param {string} sGroupId - The group ID of the POST request
459
+ *
460
+ * @private
461
+ */
462
+ _Cache.prototype.cancelNestedCreates = function (oElement, sPostPath, sGroupId) {
463
+ Object.keys(oElement).forEach(function (sKey) {
464
+ var oError,
465
+ vProperty = oElement[sKey];
466
+
467
+ if (vProperty && vProperty.$postBodyCollection) {
468
+ oError = new Error("Deep create of " + sKey + " canceled with POST " + sPostPath
469
+ + "; group: " + sGroupId);
470
+ oError.canceled = true;
471
+ vProperty.forEach(function (oChildElement) {
472
+ _Helper.getPrivateAnnotation(oChildElement, "reject")(oError);
473
+ });
474
+ }
475
+ });
476
+ };
477
+
410
478
  /**
411
479
  * Throws an error if the cache shares requests.
412
480
  *
@@ -483,11 +551,15 @@ sap.ui.define([
483
551
  return true;
484
552
  }
485
553
 
554
+ that.cancelNestedCreates(oEntityData, oPostPathPromise.getResult(),
555
+ oGroupLock.getGroupId());
486
556
  _Helper.removeByPath(that.mPostRequests, sPath, oEntityData);
487
557
  aCollection.splice(iIndex, 1);
488
558
  aCollection.$created -= 1;
489
559
  if (!oEntityData["@$ui5.context.isInactive"]) {
490
- that.iActiveElements -= 1;
560
+ if (!sPath) {
561
+ that.iActiveElements -= 1;
562
+ }
491
563
  addToCount(that.mChangeListeners, sPath, aCollection, -1);
492
564
  }
493
565
  delete aCollection.$byPredicate[sTransientPredicate];
@@ -516,6 +588,7 @@ sap.ui.define([
516
588
  ]).then(function (aResult) {
517
589
  var oCreatedEntity = aResult[0],
518
590
  sPredicate,
591
+ sResultingPath,
519
592
  aSelect;
520
593
 
521
594
  _Helper.deletePrivateAnnotation(oEntityData, "postBody");
@@ -538,13 +611,18 @@ sap.ui.define([
538
611
  // contexts still use the transient predicate to access the data
539
612
  } // else: transient element was not kept by #reset, leave it like that!
540
613
  }
541
- // update the cache with the POST response (note that a deep create is not supported
542
- // because updateSelected does not handle key predicates, ETags and $count)
543
- aSelect = _Helper.getQueryOptionsForPath(that.mQueryOptions, sPath).$select;
544
- _Helper.updateSelected(that.mChangeListeners,
545
- _Helper.buildPath(sPath, sPredicate || sTransientPredicate), oEntityData,
614
+ // update the cache with the POST response
615
+ aSelect = _Helper.getQueryOptionsForPath(
616
+ that.mLateQueryOptions || that.mQueryOptions, sPath
617
+ ).$select;
618
+ sResultingPath = _Helper.buildPath(sPath, sPredicate || sTransientPredicate);
619
+ // update selected properties (incl. single-valued navigation properties), ETags,
620
+ // and predicates
621
+ _Helper.updateSelected(that.mChangeListeners, sResultingPath, oEntityData,
546
622
  oCreatedEntity, aSelect, /*fnCheckKeyPredicate*/ undefined,
547
623
  /*bOkIfMissing*/ true);
624
+ // update properties from collections in a deep create
625
+ that.updateNestedCreates(sResultingPath, oEntityData, oCreatedEntity);
548
626
 
549
627
  that.removePendingRequest();
550
628
  fnResolve(true);
@@ -597,7 +675,9 @@ sap.ui.define([
597
675
  _Helper.publicClone(oEntityData, true));
598
676
  oEntityData["@$ui5.context.isInactive"] = true;
599
677
  } else {
600
- this.iActiveElements += 1;
678
+ if (!sPath) {
679
+ this.iActiveElements += 1;
680
+ }
601
681
  addToCount(this.mChangeListeners, sPath, aCollection, 1);
602
682
  }
603
683
 
@@ -611,6 +691,19 @@ sap.ui.define([
611
691
  aCollection.$byPredicate = aCollection.$byPredicate || {};
612
692
  aCollection.$byPredicate[sTransientPredicate] = oEntityData;
613
693
  that.adjustIndexes(sPath, aCollection, 0, 1, 0, true);
694
+ if (aCollection.$postBodyCollection) { // within a deep create
695
+ if (typeof aCollection.$postBodyCollection === "function") {
696
+ aCollection.$postBodyCollection(); // creation on demand
697
+ }
698
+ _Helper.setPrivateAnnotation(oEntityData, "transient", sGroupId);
699
+ if (bAtEndOfCreated) {
700
+ aCollection.$postBodyCollection.push(oPostBody);
701
+ } else {
702
+ aCollection.$postBodyCollection.unshift(oPostBody);
703
+ }
704
+ oGroupLock.unlock();
705
+ return _Helper.addDeepCreatePromise(oEntityData);
706
+ }
614
707
 
615
708
  return oPostPathPromise.then(function (sPostPath) {
616
709
  sPostPath += that.oRequestor.buildQueryString(that.sMetaPath, that.mQueryOptions, true);
@@ -973,7 +1066,8 @@ sap.ui.define([
973
1066
  throw new Error("GET " + sRequestPath + ": Key predicate changed from "
974
1067
  + sOldPredicate + " to " + sNewPredicate);
975
1068
  }
976
- // we expect the server to always or never send an ETag for this entity
1069
+ // only check for ETag change if the cache contains one; otherwise either the cache
1070
+ // element is empty (via #createEmptyElement) or the server did not send one last time
977
1071
  if (oResource["@odata.etag"] && oData["@odata.etag"] !== oResource["@odata.etag"]) {
978
1072
  throw new Error("GET " + sRequestPath + ": ETag changed");
979
1073
  }
@@ -1071,6 +1165,27 @@ sap.ui.define([
1071
1165
  * @public
1072
1166
  */
1073
1167
 
1168
+ /**
1169
+ * Returns the value at the given path and removes it from the cache.
1170
+ *
1171
+ * @param {string} sPath - The relative path of the property
1172
+ * @returns {any} The value
1173
+ * @throws {Error} If the cache is shared
1174
+ *
1175
+ * @public
1176
+ */
1177
+ _Cache.prototype.getAndRemoveValue = function (sPath) {
1178
+ var aSegments = sPath.split("/"),
1179
+ sName = aSegments.pop(),
1180
+ oParent = this.fetchValue(_GroupLock.$cached, aSegments.join("/")).getResult(),
1181
+ vValue = oParent[sName];
1182
+
1183
+ this.checkSharedRequest();
1184
+ delete oParent[sName];
1185
+
1186
+ return vValue;
1187
+ };
1188
+
1074
1189
  /**
1075
1190
  * Returns an array containing all current elements of a collection or single cache for the
1076
1191
  * given relative path; the array is annotated with the collection's $count. If there are
@@ -2203,6 +2318,60 @@ sap.ui.define([
2203
2318
  });
2204
2319
  };
2205
2320
 
2321
+ /**
2322
+ * Creates key predicates and updates listeners for nested entity collections after a deep
2323
+ * create.
2324
+ *
2325
+ * @param {string} sPath - The path of the created entity within the cache
2326
+ * @param {object} oEntity - The entity in the cache
2327
+ * @param {object} oCreatedEntity - The created entity from the response
2328
+ *
2329
+ * @private
2330
+ */
2331
+ _Cache.prototype.updateNestedCreates = function (sPath, oEntity, oCreatedEntity) {
2332
+ var that = this;
2333
+
2334
+ Object.keys(oEntity).forEach(function (sSegment) {
2335
+ var vCollection = oEntity[sSegment],
2336
+ sCollectionPath,
2337
+ aCreatedCollection,
2338
+ aSelect;
2339
+
2340
+ if (vCollection && vCollection.$postBodyCollection) {
2341
+ aCreatedCollection = oCreatedEntity[sSegment];
2342
+ if (aCreatedCollection) { // otherwise no create was called in nested list binding
2343
+ sCollectionPath = sPath + "/" + sSegment;
2344
+ aSelect = vCollection.$select
2345
+ || _Helper.getQueryOptionsForPath(that.mQueryOptions, sCollectionPath)
2346
+ .$select;
2347
+ aCreatedCollection.forEach(function (oCreatedChildEntity, i) {
2348
+ var oChildEntity = vCollection[i],
2349
+ sPredicate
2350
+ = _Helper.getPrivateAnnotation(oCreatedChildEntity, "predicate"),
2351
+ fnResolve = _Helper.getPrivateAnnotation(oChildEntity, "resolve"),
2352
+ sTransientPredicate = _Helper.getPrivateAnnotation(oChildEntity,
2353
+ "transientPredicate");
2354
+
2355
+ _Helper.updateTransientPaths(that.mChangeListeners, sTransientPredicate,
2356
+ sPredicate);
2357
+ vCollection.$byPredicate[sPredicate] = oChildEntity;
2358
+ _Helper.updateSelected(that.mChangeListeners, sCollectionPath + sPredicate,
2359
+ oChildEntity, oCreatedChildEntity, aSelect,
2360
+ /*fnCheckKeyPredicate*/undefined, true);
2361
+ _Helper.deletePrivateAnnotation(oChildEntity, "postBody");
2362
+ _Helper.deletePrivateAnnotation(oChildEntity, "reject");
2363
+ _Helper.deletePrivateAnnotation(oChildEntity, "resolve");
2364
+ _Helper.deletePrivateAnnotation(oChildEntity, "transient");
2365
+ delete oChildEntity["@$ui5.context.isTransient"];
2366
+ fnResolve(oChildEntity); // resolve the create promise
2367
+ });
2368
+ }
2369
+ delete vCollection.$postBodyCollection;
2370
+ delete vCollection.$select;
2371
+ }
2372
+ });
2373
+ };
2374
+
2206
2375
  /**
2207
2376
  * Processes the response from the server. All arrays are annotated by their length, influenced
2208
2377
  * by the annotations "@odata.count" and "@odata.nextLink". Recursively calculates the key
@@ -2868,7 +3037,9 @@ sap.ui.define([
2868
3037
  if (sPredicate) {
2869
3038
  oKeptElement = aElements.$byPredicate[sPredicate];
2870
3039
  if (oKeptElement) {
2871
- // we expect the server to always or never send an ETag for this entity
3040
+ // only check for ETag change if the cache contains one; otherwise either the
3041
+ // cache element is empty (via #createEmptyElement) or the server did not send
3042
+ // one last time
2872
3043
  if (!oKeptElement["@odata.etag"]
2873
3044
  || oElement["@odata.etag"] === oKeptElement["@odata.etag"]) {
2874
3045
  if (iCreated && aElements.lastIndexOf(oKeptElement, iCreated - 1) >= 0) {
@@ -3126,10 +3297,8 @@ sap.ui.define([
3126
3297
  }
3127
3298
 
3128
3299
  /*
3129
- * Tells whether a refresh is needed for the given predicate. Transient predicates,
3130
- * elements with pending changes, and empty elements just created via
3131
- * {@link sap.ui.model.odata.v4.ODataModel#getKeepAliveContext} but not yet read, need no
3132
- * refresh.
3300
+ * Tells whether a refresh is needed for the given predicate. Transient predicates and
3301
+ * elements with pending changes need no refresh.
3133
3302
  *
3134
3303
  * @param {string} sPredicate - A key predicate
3135
3304
  * @returns {boolean} - Whether a refresh is needed
@@ -3138,7 +3307,6 @@ sap.ui.define([
3138
3307
  var oElement = that.aElements.$byPredicate[sPredicate];
3139
3308
 
3140
3309
  return _Helper.getPrivateAnnotation(oElement, "predicate") === sPredicate
3141
- && Object.keys(oElement).length > 1 // entity has key properties
3142
3310
  && !that.hasPendingChangesForPath(sPredicate);
3143
3311
  }
3144
3312
 
@@ -3469,6 +3637,17 @@ sap.ui.define([
3469
3637
  this.oBackup = null;
3470
3638
  };
3471
3639
 
3640
+ /**
3641
+ * Sets the cache's elements to the given collection after a deep create.
3642
+ *
3643
+ * @param {object} aElements - The elements from the deep create
3644
+ */
3645
+ _CollectionCache.prototype.setPersistedCollection = function (aElements) {
3646
+ this.aElements = aElements;
3647
+ this.iActiveElements = aElements.$created;
3648
+ this.iLimit = aElements.length;
3649
+ };
3650
+
3472
3651
  //*********************************************************************************************
3473
3652
  // PropertyCache
3474
3653
  //*********************************************************************************************
@@ -3769,24 +3948,42 @@ sap.ui.define([
3769
3948
  ? {"If-Match" : bIgnoreETag && "@odata.etag" in oEntity ? "*" : oEntity}
3770
3949
  : {},
3771
3950
  sHttpMethod = "POST",
3951
+ oRequestLock,
3772
3952
  that = this;
3773
3953
 
3954
+ /*
3955
+ * Synchronous callback called when the request is put on the wire. Locks the group (for
3956
+ * bound actions) so that further requests created via {@link ODataModel#submitBatch} wait
3957
+ * until this request has returned.
3958
+ */
3959
+ function onSubmit() {
3960
+ oRequestLock = that.oRequestor.lockGroup(oGroupLock.getGroupId(), that, true);
3961
+ }
3962
+
3774
3963
  function post(oGroupLock0) {
3775
3964
  that.bPosting = true;
3776
3965
 
3777
3966
  // BEWARE! Avoid finally here! BCP: 2070200175
3778
3967
  return SyncPromise.all([
3779
3968
  that.oRequestor.request(sHttpMethod,
3780
- that.sResourcePath + that.sQueryString, oGroupLock0, mHeaders, oData),
3969
+ that.sResourcePath + that.sQueryString, oGroupLock0, mHeaders, oData,
3970
+ oEntity && onSubmit),
3781
3971
  that.fetchTypes()
3782
3972
  ]).then(function (aResult) {
3783
3973
  that.buildOriginalResourcePath(aResult[0], aResult[1], fnGetOriginalResourcePath);
3784
3974
  that.visitResponse(aResult[0], aResult[1]);
3785
3975
  that.bPosting = false;
3976
+ if (oRequestLock) {
3977
+ oRequestLock.unlock();
3978
+ }
3786
3979
 
3787
3980
  return aResult[0];
3788
3981
  }, function (oError) {
3789
3982
  that.bPosting = false;
3983
+ if (oRequestLock) {
3984
+ oRequestLock.unlock();
3985
+ oRequestLock = undefined; // in case we fail again before next submit
3986
+ }
3790
3987
  if (fnOnStrictHandlingFailed && oError.strictHandlingFailed) {
3791
3988
  return fnOnStrictHandlingFailed(oError).then(function (bConfirm) {
3792
3989
  var oCanceledError;