diff --git a/src/sap.ui.core/src/sap/ui/core/Component.js b/src/sap.ui.core/src/sap/ui/core/Component.js index f0c629e97121..f3fe6dbb8741 100644 --- a/src/sap.ui.core/src/sap/ui/core/Component.js +++ b/src/sap.ui.core/src/sap/ui/core/Component.js @@ -930,10 +930,18 @@ sap.ui.define([ * @private */ Component.prototype._initComponentModels = function(mModels, mDataSources, mCacheTokens) { + var sComponentName = this.getManifestObject().getComponentName(); - var mAllModelConfigurations = Component._createManifestModelConfigurations({ + var mAllModelConfigs = Component._findManifestModelClasses({ models: mModels, dataSources: mDataSources, + componentName: sComponentName + }); + Component._loadManifestModelClasses(mAllModelConfigs, sComponentName); + + var mAllModelConfigurations = Component._createManifestModelConfigurations({ + models: mAllModelConfigs, + dataSources: mDataSources, component: this, mergeParent: true, cacheTokens: mCacheTokens, @@ -954,7 +962,7 @@ sap.ui.define([ } // create all models which are not created, yet. - var mCreatedModels = Component._createManifestModels(mModelConfigurations, this.toString()); + var mCreatedModels = Component._createManifestModels(mModelConfigurations, sComponentName); for (sModelName in mCreatedModels) { // keep the model instance to be able to destroy the created models on component destroy this._mManifestModels[sModelName] = mCreatedModels[sModelName]; @@ -1429,6 +1437,102 @@ sap.ui.define([ }; + Component._findManifestModelClasses = function(mOptions) { + if (!mOptions.models) { + // skipping model creation because of missing sap.ui5 models manifest entry + return null; + } + + var mConfig = { + + // ui5 model definitions + models: mOptions.models, + + // optional dataSources from "sap.app" manifest + dataSources: mOptions.dataSources || {}, + + // to identify where the dataSources/models have been originally defined + origin: { + dataSources: {}, + models: {} + } + }; + + var sLogComponentName = mOptions.componentName; + var mModelConfigurations = {}; + + // create a model for each ["sap.ui5"]["models"] entry + for (var sModelName in mConfig.models) { + + var oModelConfig = mConfig.models[sModelName]; + + // normalize dataSource shorthand, e.g. + // "myModel": "myDataSource" => "myModel": { dataSource: "myDataSource" } + if (typeof oModelConfig === 'string') { + oModelConfig = { + dataSource: oModelConfig + }; + } + + // check for referenced dataSource entry and read out settings/uri/type + // if not already provided in model config + if (oModelConfig.dataSource) { + + var oDataSource = mConfig.dataSources && mConfig.dataSources[oModelConfig.dataSource]; + if (typeof oDataSource === 'object') { + + // default type is OData + if (oDataSource.type === undefined) { + oDataSource.type = 'OData'; + } + + var sODataVersion; + + // read out type and translate to model class + // (only if no model type was set to allow overriding) + if (!oModelConfig.type) { + switch (oDataSource.type) { + case 'OData': + sODataVersion = oDataSource.settings && oDataSource.settings.odataVersion; + if (sODataVersion === "4.0") { + oModelConfig.type = 'sap.ui.model.odata.v4.ODataModel'; + } else if (!sODataVersion || sODataVersion === "2.0") { + // 2.0 is the default in case no version is provided + oModelConfig.type = 'sap.ui.model.odata.v2.ODataModel'; + } else { + Log.error('Component Manifest: Provided OData version "' + sODataVersion + '" in ' + + 'dataSource "' + oModelConfig.dataSource + '" for model "' + sModelName + '" is unknown. ' + + 'Falling back to default model type "sap.ui.model.odata.v2.ODataModel".', + '["sap.app"]["dataSources"]["' + oModelConfig.dataSource + '"]', sLogComponentName); + oModelConfig.type = 'sap.ui.model.odata.v2.ODataModel'; + } + break; + case 'JSON': + oModelConfig.type = 'sap.ui.model.json.JSONModel'; + break; + case 'XML': + oModelConfig.type = 'sap.ui.model.xml.XMLModel'; + break; + default: + // for custom dataSource types, the class should already be specified in the sap.ui5 models config + } + } + } + } + + // model type is required! + if (!oModelConfig.type) { + Log.error("Component Manifest: Missing \"type\" for model \"" + sModelName + "\"", "[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", sLogComponentName); + continue; + } + + // Add final configuration to result map + mModelConfigurations[sModelName] = oModelConfig; + } + + return mModelConfigurations; + }; + /** * Creates model configurations by processing "/sap.app/dataSources" and "/sap.ui5/models" manifest entries. * Result can be handed over to {@link sap.ui.core.Component._createManifestModels} in order to create instances. @@ -1449,7 +1553,7 @@ sap.ui.define([ var oManifest = mOptions.manifest || oComponent.getManifestObject(); var bMergeParent = mOptions.mergeParent; var mCacheTokens = mOptions.cacheTokens || {}; - var sLogComponentName = oComponent ? oComponent.toString() : oManifest.getComponentName(); + var sLogComponentName = oComponent ? oComponent.getMetadata().getComponentName() : oManifest.getComponentName(); var oConfig = sap.ui.getCore().getConfiguration(); var aActiveTerminologies = mOptions.activeTerminologies; @@ -1495,6 +1599,22 @@ sap.ui.define([ for (var sModelName in mConfig.models) { var oModelConfig = mConfig.models[sModelName]; + var fnClass = sap.ui.require(oModelConfig.type.replace(/\./g, "/")); + if (!fnClass) { + fnClass = ObjectPath.get(oModelConfig.type); + } + // class could not be loaded by _loadManifestModelClasses + if (!fnClass) { + Log.error("Component Manifest: Class \"" + oModelConfig.type + "\" for model \"" + sModelName + "\" could not be found", "[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", sLogComponentName); + continue; + } + var oClassMetadata = fnClass.getMetadata(); + + var bIsV1Model = oClassMetadata.isA("sap.ui.model.odata.ODataModel"); + var bIsV2Model = oClassMetadata.isA("sap.ui.model.odata.v2.ODataModel"); + var bIsV4Model = oClassMetadata.isA("sap.ui.model.odata.v4.ODataModel"); + var bIsResourceModel = oClassMetadata.isA("sap.ui.model.resource.ResourceModel"); + var bIsDataSourceUri = false; var mMetadataUrlParams = null; @@ -1518,42 +1638,8 @@ sap.ui.define([ oDataSource.type = 'OData'; } - var sODataVersion; - - // read out type and translate to model class - // (only if no model type was set to allow overriding) - if (!oModelConfig.type) { - switch (oDataSource.type) { - case 'OData': - sODataVersion = oDataSource.settings && oDataSource.settings.odataVersion; - if (sODataVersion === "4.0") { - oModelConfig.type = 'sap.ui.model.odata.v4.ODataModel'; - } else if (!sODataVersion || sODataVersion === "2.0") { - // 2.0 is the default in case no version is provided - oModelConfig.type = 'sap.ui.model.odata.v2.ODataModel'; - } else { - Log.error('Component Manifest: Provided OData version "' + sODataVersion + '" in ' + - 'dataSource "' + oModelConfig.dataSource + '" for model "' + sModelName + '" is unknown. ' + - 'Falling back to default model type "sap.ui.model.odata.v2.ODataModel".', - '["sap.app"]["dataSources"]["' + oModelConfig.dataSource + '"]', sLogComponentName); - oModelConfig.type = 'sap.ui.model.odata.v2.ODataModel'; - } - break; - case 'JSON': - oModelConfig.type = 'sap.ui.model.json.JSONModel'; - break; - case 'XML': - oModelConfig.type = 'sap.ui.model.xml.XMLModel'; - break; - default: - // for custom dataSource types, the class should already be specified in the sap.ui5 models config - } - } - // pass OData service version (e.g. "2.0"), if specified, to the OData V4 model - if (oModelConfig.type === 'sap.ui.model.odata.v4.ODataModel' - && oDataSource.settings - && oDataSource.settings.odataVersion) { + if (bIsV4Model && oDataSource.settings && oDataSource.settings.odataVersion) { oModelConfig.settings = oModelConfig.settings || {}; oModelConfig.settings.odataVersion = oDataSource.settings.odataVersion; } @@ -1598,20 +1684,16 @@ sap.ui.define([ var oAnnotationUri = new URI(oAnnotation.uri); - if (oModelConfig.type === 'sap.ui.model.odata.v2.ODataModel' || - oModelConfig.type === 'sap.ui.model.odata.v4.ODataModel') { + if (bIsV2Model || bIsV4Model) { + /* eslint-disable no-loop-func */ + ["sap-language", "sap-client"].forEach(function(sName) { + if (!oAnnotationUri.hasQuery(sName) && oConfig.getSAPParam(sName)) { + oAnnotationUri.setQuery(sName, oConfig.getSAPParam(sName)); + } + }); + /* eslint-enable no-loop-func */ var sCacheTokenForAnnotation = mCacheTokens.dataSources && mCacheTokens.dataSources[oAnnotation.uri]; - if (sCacheTokenForAnnotation || oModelConfig.type === 'sap.ui.model.odata.v2.ODataModel') { - /* eslint-disable no-loop-func */ - ["sap-language", "sap-client"].forEach(function(sName) { - if (!oAnnotationUri.hasQuery(sName) && oConfig.getSAPParam(sName)) { - oAnnotationUri.setQuery(sName, oConfig.getSAPParam(sName)); - } - }); - /* eslint-enable no-loop-func */ - } - if (sCacheTokenForAnnotation) { Component._applyCacheToken(oAnnotationUri, { cacheToken: sCacheTokenForAnnotation, @@ -1638,24 +1720,16 @@ sap.ui.define([ } } - // model type is required! - if (!oModelConfig.type) { - Log.error("Component Manifest: Missing \"type\" for model \"" + sModelName + "\"", "[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", sLogComponentName); - continue; - } - // set mode of old ODataModel to "json" (default is xml). // as the automatic model creation is a new feature, this is not incompatible here - if (oModelConfig.type === 'sap.ui.model.odata.ODataModel' && - (!oModelConfig.settings || oModelConfig.settings.json === undefined)) { + if (bIsV1Model && (!oModelConfig.settings || oModelConfig.settings.json === undefined)) { // do not overwrite the flag if it was explicitly defined! - oModelConfig.settings = oModelConfig.settings || {}; oModelConfig.settings.json = true; } // Check resource models for bundleUrl configuration - if (oModelConfig.type === "sap.ui.model.resource.ResourceModel") { + if (bIsResourceModel) { if (oModelConfig.uri && oModelConfig.settings && oModelConfig.settings.bundleUrl) { Log.warning("Defining both model uri and bundleUrl is not supported. Only model uri will be resolved."); } @@ -1683,8 +1757,7 @@ sap.ui.define([ if (oModelConfig.dataSource) { addSapParams(oUri); - if (oModelConfig.type === 'sap.ui.model.odata.v2.ODataModel' || - oModelConfig.type === 'sap.ui.model.odata.v4.ODataModel') { + if (bIsV2Model || bIsV4Model) { var oModelDataSource = mConfig.dataSources && mConfig.dataSources[oModelConfig.dataSource]; var sCacheToken = mCacheTokens.dataSources && mCacheTokens.dataSources[oModelDataSource.uri]; @@ -1695,7 +1768,7 @@ sap.ui.define([ && !oUri.hasQuery('sap-language') && oConfig.getSAPParam('sap-language'); - if ((bNeedsLanguage && oModelConfig.type === 'sap.ui.model.odata.v2.ODataModel') || sCacheToken) { + if (bNeedsLanguage || sCacheToken) { // Lazy initialize settings and metadataUrlParams objects oModelConfig.settings = oModelConfig.settings || {}; mMetadataUrlParams = oModelConfig.settings.metadataUrlParams = oModelConfig.settings.metadataUrlParams || {}; @@ -1723,17 +1796,12 @@ sap.ui.define([ // set model specific "uri" property names which should be used to map "uri" to model specific constructor // (only if it wasn't specified before) if (oModelConfig.uriSettingName === undefined) { - switch (oModelConfig.type) { - case 'sap.ui.model.odata.ODataModel': - case 'sap.ui.model.odata.v2.ODataModel': - case 'sap.ui.model.odata.v4.ODataModel': - oModelConfig.uriSettingName = 'serviceUrl'; - break; - case 'sap.ui.model.resource.ResourceModel': - oModelConfig.uriSettingName = 'bundleUrl'; - break; - default: - // default 'undefined' is already set in this case + if (bIsV1Model || bIsV2Model || bIsV4Model) { + oModelConfig.uriSettingName = 'serviceUrl'; + } else if (bIsResourceModel) { + oModelConfig.uriSettingName = 'bundleUrl'; + } else { + // default 'undefined' is already set in this case } } @@ -1754,9 +1822,9 @@ sap.ui.define([ // lazy load the ODataUtils if systemParameter is given var bAddOrigin = false; var ODataUtils; - if (sSystemParameter && ["sap.ui.model.odata.ODataModel", "sap.ui.model.odata.v2.ODataModel"].indexOf(oModelConfig.type) != -1) { + if (sSystemParameter && (bIsV1Model || bIsV2Model)) { bAddOrigin = true; - ODataUtils = sap.ui.requireSync("sap/ui/model/odata/ODataUtils"); + ODataUtils = sap.ui.require("sap/ui/model/odata/ODataUtils"); } // include "uri" property in "settings" object, depending on "uriSettingName" @@ -1813,7 +1881,7 @@ sap.ui.define([ // resolve the bundleUrl of the enhancing resource bundle relative to // the component (default) or relative to manifest, e.g.: // bundleUrlRelativeTo: 'component|manifest' - if (oModelConfig.type === 'sap.ui.model.resource.ResourceModel' && oModelConfig.settings) { + if (bIsResourceModel && oModelConfig.settings) { if (aActiveTerminologies) { oModelConfig.settings.activeTerminologies = aActiveTerminologies; } @@ -1840,6 +1908,21 @@ sap.ui.define([ return mModelConfigurations; }; + Component._loadManifestModelClasses = function(mModelConfigurations, sLogComponentName) { + for (var sModelName in mModelConfigurations) { + var oModelConfig = mModelConfigurations[sModelName]; + + // load model class and log error message if it couldn't be loaded. + // error gets caught to continue creating the other models and not breaking the execution here + try { + sap.ui.requireSync(oModelConfig.type.replace(/\./g, "/")); + } catch (oError) { + Log.error("Component Manifest: Class \"" + oModelConfig.type + "\" for model \"" + sModelName + "\" could not be loaded. " + oError, "[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", sLogComponentName); + continue; + } + } + }; + /** * Creates model instances using a configuration provided by {@link sap.ui.core.Component._createManifestModelConfigurations}. * @@ -1853,24 +1936,9 @@ sap.ui.define([ for (var sModelName in mModelConfigurations) { var oModelConfig = mModelConfigurations[sModelName]; - // load model class and log error message if it couldn't be loaded. - // error gets caught to continue creating the other models and not breaking the execution here - try { - sap.ui.requireSync(oModelConfig.type.replace(/\./g, "/")); - } catch (oError) { - Log.error("Component Manifest: Class \"" + oModelConfig.type + "\" for model \"" + sModelName + "\" could not be loaded. " + oError, "[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", sLogComponentName); - continue; - } - - // TODO: We don't use the return value of sap.ui.requireSync here yet. // The tests for the Model creation make use of a constructor stub, // and this only works from the global namespace export. var fnModelClass = ObjectPath.get(oModelConfig.type); - if (!fnModelClass) { - // this could be the case if the required module doesn't register itself in the defined namespace - Log.error("Component Manifest: Class \"" + oModelConfig.type + "\" for model \"" + sModelName + "\" could not be found", "[\"sap.ui5\"][\"models\"][\"" + sModelName + "\"]", sLogComponentName); - continue; - } // create arguments array with leading "null" value so that it can be passed to the apply function var aArgs = [null].concat(oModelConfig.settings || []); @@ -1907,7 +1975,7 @@ sap.ui.define([ * @param {string[]} [aActiveTerminologies] optional list of active terminologies * @returns {object} object with two maps, see above */ - function getPreloadModelConfigsFromManifest(oManifest, oComponentData, mCacheTokens, aActiveTerminologies) { + function getPreloadModelConfigsFromManifest(oManifest) { var mModelConfigs = { afterManifest: {}, afterPreload: {} @@ -1916,14 +1984,11 @@ sap.ui.define([ // deep clone is needed as manifest only returns a read-only copy (frozen object) var oManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources")); var oManifestModels = merge({}, oManifest.getEntry("/sap.ui5/models")); - - var mAllModelConfigurations = Component._createManifestModelConfigurations({ + var sComponentName = oManifest.getComponentName(); + var mAllModelConfigurations = Component._findManifestModelClasses({ models: oManifestModels, dataSources: oManifestDataSources, - manifest: oManifest, - componentData: oComponentData, - cacheTokens: mCacheTokens, - activeTerminologies: aActiveTerminologies + componentName: sComponentName }); // Read internal URI parameter to enable model preload for testing purposes @@ -1942,14 +2007,13 @@ sap.ui.define([ if (!mModelConfig.preload && aPreloadModels && aPreloadModels.indexOf(sModelName) > -1 ) { mModelConfig.preload = true; Log.warning("FOR TESTING ONLY!!! Activating preload for model \"" + sModelName + "\" (" + mModelConfig.type + ")", - oManifest.getComponentName(), "sap.ui.core.Component"); + sComponentName, "sap.ui.core.Component"); } // ResourceModels with async=false should be always loaded beforehand to get rid of sync requests under the hood (regardless of the "preload" flag) if (mModelConfig.type === "sap.ui.model.resource.ResourceModel" && - Array.isArray(mModelConfig.settings) && - mModelConfig.settings.length > 0 && - mModelConfig.settings[0].async !== true + (!mModelConfig.settings || + mModelConfig.settings.async !== true) ) { // Use separate config object for ResourceModels as the resourceBundle might be // part of the Component-preload which isn't available when the regular "preloaded"-models are created @@ -1958,11 +2022,14 @@ sap.ui.define([ // Only create models: // - which are flagged for preload (mModelConfig.preload) or configured via internal URI param (see above) // - in case the model class is already loaded (otherwise log a warning) + // We check for the moduleState here instead of a simple sap.ui.require probing, because it captures the following cases: + // - modules defined in a preload (via predefine) are "available, but not executed" + // - modules which are already loaded/executed if (sap.ui.loader._.getModuleState(mModelConfig.type.replace(/\./g, "/") + ".js")) { mModelConfigs.afterManifest[sModelName] = mModelConfig; } else { Log.warning("Can not preload model \"" + sModelName + "\" as required class has not been loaded: \"" + mModelConfig.type + "\"", - oManifest.getComponentName(), "sap.ui.core.Component"); + sComponentName, "sap.ui.core.Component"); } } @@ -2653,7 +2720,7 @@ sap.ui.define([ sManifestUrl, oManifest, mModels, - mModelConfigs, + mPreloadModelConfigs, fnCallLoadComponentCallback; function createSanitizedManifest( oRawManifestJSON, mOptions ) { @@ -3060,14 +3127,26 @@ sap.ui.define([ // create "afterPreload" models in parallel to loading the component preload (below) if (mOptions.createModels) { collect(oManifest.then(function(oManifest) { + var sComponentName = oManifest.getComponentName(); // Calculate configurations of preloaded models once the manifest is available - mModelConfigs = getPreloadModelConfigsFromManifest(oManifest, oConfig.componentData, hints.cacheTokens, aActiveTerminologies); + mPreloadModelConfigs = getPreloadModelConfigsFromManifest(oManifest); - return oManifest; - }).then(function(oManifest) { // Create preloaded models directly after the manifest has been loaded - if (Object.keys(mModelConfigs.afterManifest).length > 0) { - mModels = Component._createManifestModels(mModelConfigs.afterManifest, oManifest.getComponentName()); + if (Object.keys(mPreloadModelConfigs.afterManifest).length > 0) { + Component._loadManifestModelClasses(mPreloadModelConfigs.afterManifest, sComponentName); + + // deep clone is needed as manifest only returns a read-only copy (frozen object) + var oManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources")); + var mAllModelConfigurations = Component._createManifestModelConfigurations({ + models: mPreloadModelConfigs.afterManifest, + dataSources: oManifestDataSources, + manifest: oManifest, + componentData: oConfig.componentData, + cacheTokens: hints.cacheTokens, + activeTerminologies: aActiveTerminologies + }); + + mModels = Component._createManifestModels(mAllModelConfigurations, sComponentName); } return oManifest; @@ -3096,7 +3175,7 @@ sap.ui.define([ return null; } - var aResourceModelNames = Object.keys(mModelConfigs.afterPreload); + var aResourceModelNames = Object.keys(mPreloadModelConfigs.afterPreload); if (aResourceModelNames.length === 0) { return null; @@ -3111,8 +3190,20 @@ sap.ui.define([ resolve(ResourceModel); }, reject); }).then(function(ResourceModel) { + + // deep clone is needed as manifest only returns a read-only copy (frozen object) + var oManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources")); + var mAfterPreloadModelConfigurations = Component._createManifestModelConfigurations({ + models: mPreloadModelConfigs.afterPreload, + dataSources: oManifestDataSources, + manifest: oManifest, + componentData: oConfig.componentData, + cacheTokens: hints.cacheTokens, + activeTerminologies: aActiveTerminologies + }); + function loadResourceBundle(sModelName) { - var mModelConfig = mModelConfigs.afterPreload[sModelName]; + var mModelConfig = mAfterPreloadModelConfigurations[sModelName]; if (Array.isArray(mModelConfig.settings) && mModelConfig.settings.length > 0) { var mModelSettings = mModelConfig.settings[0]; // first argument is the config map @@ -3143,19 +3234,19 @@ sap.ui.define([ // If the resource bundle can't be loaded, the resource model will be skipped. // But once the component instance gets created, the model will be tried to created again. - delete mModelConfigs.afterPreload[sModelName]; + delete mAfterPreloadModelConfigurations[sModelName]; }); } else { // Can't load bundle as no settings are defined. - // Should not happen as those models won't be part of "mModelConfigs.afterPreload" + // Should not happen as those models won't be part of "afterPreload" return Promise.resolve(); } } // Load all ResourceBundles for all models in parallel return Promise.all(aResourceModelNames.map(loadResourceBundle)).then(function() { - if (Object.keys(mModelConfigs.afterPreload).length > 0) { - var mResourceModels = Component._createManifestModels(mModelConfigs.afterPreload, oManifest.getComponentName()); + if (Object.keys(mAfterPreloadModelConfigurations).length > 0) { + var mResourceModels = Component._createManifestModels(mAfterPreloadModelConfigurations, oManifest.getComponentName()); if (!mModels) { mModels = {}; } @@ -3331,12 +3422,10 @@ sap.ui.define([ // lookup model classes var mManifestModels = merge({}, oManifest.getEntry("/sap.ui5/models")); var mManifestDataSources = merge({}, oManifest.getEntry("/sap.app/dataSources")); - var mAllModelConfigurations = Component._createManifestModelConfigurations({ + var mAllModelConfigurations = Component._findManifestModelClasses({ models: mManifestModels, dataSources: mManifestDataSources, - manifest: oManifest, - cacheTokens: hints.cacheTokens, - activeTerminologies: aActiveTerminologies + componentName: oManifest.getComponentName() }); for (var mModelName in mAllModelConfigurations) { if (!mAllModelConfigurations.hasOwnProperty(mModelName)) { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/DataAggregation/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/DataAggregation/SandboxModel.js index 1c0aede590db..93f8229ddafc 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/DataAggregation/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/DataAggregation/SandboxModel.js @@ -13,7 +13,7 @@ sap.ui.define([ // Note: DO NOT reuse the same source file with a different $top if that leads to a short read! var oMockData = { mFixture : { - "$metadata" : { + "$metadata?sap-language=EN" : { source : "metadata.xml" }, "BusinessPartners?$apply=concat(aggregate(SalesAmountLocalCurrency,LocalCurrency),groupby((Country_Code,Country),aggregate(SalesAmountLocalCurrency,LocalCurrency))/orderby(Country%20desc)/concat(aggregate($count%20as%20UI5__count),top(4)))" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FieldGroups/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FieldGroups/SandboxModel.js index 0ba53eb363b8..19ff207ff3d0 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FieldGroups/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FieldGroups/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata" : { + "$metadata?sap-language=EN" : { source : "metadata.xml" }, "ContactList(42010aef-0de5-1eea-af8f-5bce865f0879)?$select=ContactGUID,EmailAddress,FirstName,LastName" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FlexibleColumnLayout/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FlexibleColumnLayout/SandboxModel.js index 25d6d4a26338..1d08b7aa6c8b 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FlexibleColumnLayout/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/FlexibleColumnLayout/SandboxModel.js @@ -13,7 +13,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata" : { + "$metadata?sap-language=EN" : { source : "metadata.xml" }, "SalesOrderList?$count=true&$filter=SalesOrderID%20ge%20'0500000000'%20and%20LifecycleStatus%20eq%20'N'&$select=CurrencyCode,GrossAmount,Note,SalesOrderID&$expand=SO_2_BP($select=BusinessPartnerID,CompanyName)&$skip=0&$top=5" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/LateProperties/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/LateProperties/SandboxModel.js index 630eac77bdae..caa7c8211a98 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/LateProperties/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/LateProperties/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata?custom-option=value" : { + "$metadata?custom-option=value&sap-language=EN" : { source : "metadata.xml" }, "SalesOrderList?custom-option=value&$select=BuyerID,SalesOrderID&$expand=SO_2_BP($select=BusinessPartnerID,CompanyName)&$skip=0&$top=5" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBinding/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBinding/SandboxModel.js index 3b56bde43325..0fea346e7e77 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBinding/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBinding/SandboxModel.js @@ -21,9 +21,9 @@ sap.ui.define([ "GetEmployeeMaxAge()" : { message : {"value" : 56} }, - "$metadata" : {source : "metadata.xml"}, - "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_product/0001/$metadata" : {source : "metadata_product.xml"}, - "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_supplier/0001/$metadata" : {source : "metadata_supplier.xml"}, + "$metadata?sap-language=EN" : {source : "metadata.xml"}, + "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_product/0001/$metadata?sap-language=EN" : {source : "metadata_product.xml"}, + "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_supplier/0001/$metadata?sap-language=EN" : {source : "metadata_supplier.xml"}, "TEAMS?$expand=TEAM_2_EMPLOYEES($expand=EMPLOYEE_2_EQUIPMENTS($expand=EQUIPMENT_2_PRODUCT($expand=PRODUCT_2_CATEGORY,PRODUCT_2_SUPPLIER));$orderby=LOCATION/City/CITYNAME),TEAM_2_MANAGER&$skip=0&$top=100" : { source : "TEAMS.json" }, diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/SandboxModel.js index 7af92f300911..6d6600ee2df8 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ListBindingTemplate/SandboxModel.js @@ -13,11 +13,11 @@ sap.ui.define([ var oMockData = { mFixture : { "localAnnotations.xml" : {source : "localAnnotations.xml"}, - "$metadata" : {source : "metadata.xml"}, - "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_product/0001/$metadata" : { + "$metadata?sap-language=EN" : {source : "metadata.xml"}, + "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_product/0001/$metadata?sap-language=EN" : { source : "metadata_product.xml" }, - "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_supplier/0001/$metadata" : { + "/sap/opu/odata4/IWBEP/TEA/default/iwbep/tea_busi_supplier/0001/$metadata?sap-language=EN" : { source : "metadata_supplier.xml" }, "Equipments?$select=Category,EmployeeId,ID,Name&$expand=EQUIPMENT_2_PRODUCT($select=ID,Name;$expand=PRODUCT_2_CATEGORY($select=CategoryIdentifier,CategoryName),PRODUCT_2_SUPPLIER($select=SUPPLIER_ID,Supplier_Name))&$skip=0&$top=5" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Products/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Products/SandboxModel.js index 88c9ec3d8289..413304d96887 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Products/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Products/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata?custom-option=value" : { + "$metadata?custom-option=value&sap-language=EN" : { source : "metadata.xml" }, "/sap/opu/odata4/sap/zui5_testv4/default/iwbep/common/0001/$metadata" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V2/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V2/SandboxModel.js index 2771e1f27f3b..0964a04f08ae 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V2/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V2/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata" : { + "$metadata?sap-language=EN" : { source : "metadataV2.xml" }, "SEPM_C_SLSORDER_TP_100?$inlinecount=allpages&$expand=to_Item&$filter=SalesOrder%20ge%20'500000000'&$select=Customer,OverallStatus,SalesOrder,SalesOrderUUID,to_Item/GrossAmount,to_Item/Product,to_Item/SalesOrder,to_Item/SalesOrderItem,to_Item/SalesOrderItemUUID,to_Item/SalesOrderUUID&$skip=0&$top=5" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V4/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V4/SandboxModel.js index 5de8b841079e..f83bd51b5c34 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V4/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrderTP100_V4/SandboxModel.js @@ -12,10 +12,10 @@ sap.ui.define([ var oMockData = { mFixture : { - "/sap/opu/odata4/sap/sepm_odata_ref/sadl/sap/sepm_c_slsorder_tp_100/0001/$metadata" : { + "/sap/opu/odata4/sap/sepm_odata_ref/sadl/sap/sepm_c_slsorder_tp_100/0001/$metadata?sap-language=EN" : { source : "metadataV4.xml" }, - "/sap/opu/odata4/sap/sepm_odata_ref/sadl/sap/sepm_c_slsorderitem_tp_100/0001/$metadata" : { + "/sap/opu/odata4/sap/sepm_odata_ref/sadl/sap/sepm_c_slsorderitem_tp_100/0001/$metadata?sap-language=EN" : { source : "metadataV4_item.xml" }, "SEPM_C_SLSORDER_TP_100?$count=true&$expand=_Item($select=GrossAmount,Product,SalesOrder,SalesOrderItem,SalesOrderItemUUID,SalesOrderUUID)&$select=Customer,OverallStatus,SalesOrder,SalesOrderUUID&$skip=0&$top=5" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/SandboxModel.js index d8d9b641fc9a..adb5771f79e8 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrders/SandboxModel.js @@ -14,7 +14,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata?custom-option=value" : {source : "metadata.xml"}, + "$metadata?custom-option=value&sap-language=EN" : {source : "metadata.xml"}, "BusinessPartnerList?custom-option=value&$orderby=CompanyName&$filter=BusinessPartnerRole%20eq%20'01'&$select=BusinessPartnerID,CompanyName&$skip=0&$top=100" : { source : "BusinessPartnerList.json" }, diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/SandboxModel.js index 89219e8b5082..d8aa7e3a35f3 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/SalesOrdersTemplate/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata" : {source : "metadata.xml"}, + "$metadata?sap-language=EN" : {source : "metadata.xml"}, "BusinessPartnerList?$skip=0&$top=5" : {source : "BusinessPartnerList.json"}, "/sap/opu/odata4/sap/zui5_testv4/f4/sap/h_tcurc-sh/0001;ps=%27default-zui5_epm_sample-0002%27;va=%27com.sap.gateway.default.zui5_epm_sample.v0002.ET-BUSINESSPARTNER.CURRENCY_CODE%27/$metadata" : {source : "metadata_tcurc.xml"}, diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ServerDrivenPaging/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ServerDrivenPaging/SandboxModel.js index 2517400d85b8..32f3e9a604c0 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ServerDrivenPaging/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/ServerDrivenPaging/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata?custom-option=value" : { + "$metadata?custom-option=value&sap-language=EN" : { source : "metadata.xml" }, "BusinessPartnerList?custom-option=value&$filter=BusinessPartnerID%20lt%20'0100000030'&$select=BusinessPartnerID,CompanyName&$skip=0&$top=21" : { diff --git a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Sticky/SandboxModel.js b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Sticky/SandboxModel.js index 67b7b74704c0..e254ead9fa33 100644 --- a/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Sticky/SandboxModel.js +++ b/src/sap.ui.core/test/sap/ui/core/demokit/sample/odata/v4/Sticky/SandboxModel.js @@ -12,7 +12,7 @@ sap.ui.define([ var oMockData = { mFixture : { - "$metadata" : { + "$metadata?sap-language=EN" : { source : "metadata.xml" }, "GET Sticky?$count=true&$select=Content,Id&$skip=0&$top=5" : { diff --git a/src/sap.ui.core/test/sap/ui/core/qunit/component/Models.qunit.js b/src/sap.ui.core/test/sap/ui/core/qunit/component/Models.qunit.js index 3ee76248511f..f4a2e01091db 100644 --- a/src/sap.ui.core/test/sap/ui/core/qunit/component/Models.qunit.js +++ b/src/sap.ui.core/test/sap/ui/core/qunit/component/Models.qunit.js @@ -103,9 +103,9 @@ sap.ui.define([ } }, assertModelFromManifest: function(assert, options) { - + var sComponentName = "sap.ui.core.test.component.models"; var oManifest = new sap.ui.core.Manifest(options.manifest, { - componentName: "sap.ui.core.test.component.models", + componentName: sComponentName, baseUrl: "./path/to/manifest/manifest.json", process: false }); @@ -114,9 +114,18 @@ sap.ui.define([ var oManifestDataSources = jQuery.extend(true, {}, oManifest.getEntry("/sap.app/dataSources")); var oManifestModels = jQuery.extend(true, {}, oManifest.getEntry("/sap.ui5/models")); + // 1. provide all model configs with a 'type' + var mAllModelConfigs = Component._findManifestModelClasses({ + models: oManifestModels, + dataSources: oManifestDataSources, + componentName: sComponentName + }); + // 2. make sure all model classes are loaded + Component._loadManifestModelClasses(mAllModelConfigs, sComponentName); + var oModelConfigurations = Component._createManifestModelConfigurations({ dataSources: oManifestDataSources, - models: oManifestModels, + models: mAllModelConfigs, manifest: oManifest, cacheTokens: options.cacheTokens }); @@ -264,6 +273,7 @@ sap.ui.define([ sinon.assert.calledWithExactly(this.modelSpy.odataV4, { odataVersion: "4.0", serviceUrl: '/path/to/odata/service/?sap-client=foo&sap-server=bar', + metadataUrlParams: {"sap-language": "EN"}, synchronizationMode: "None" }); @@ -340,15 +350,15 @@ sap.ui.define([ // jQuery.sap.log.error - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"type\" for model \"no-model-type\"", "[\"sap.ui5\"][\"models\"][\"no-model-type\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, sinon.match("Class \"sap.ui.not.defined.Model\" for model \"missing-model-class\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"missing-model-class\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Class \"sap.ui.test.v2models.parent.ModelNotDefined\" for model \"model-not-found\" could not be found", "[\"sap.ui5\"][\"models\"][\"model-not-found\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: ODataAnnotation \"undefined\" for dataSource \"odata-invalid-annotations\" could not be found in manifest", "[\"sap.app\"][\"dataSources\"][\"undefined\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"uri\" for ODataAnnotation \"annotation-without-uri\"", "[\"sap.app\"][\"dataSources\"][\"annotation-without-uri\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"json\" was expected to have type \"ODataAnnotation\" but was \"JSON\"", "[\"sap.app\"][\"dataSources\"][\"json\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"invalid\" for model \"dataSource-invalid\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"invalid\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"does-not-exist\" for model \"dataSource-not-found\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"does-not-exist\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Provided OData version \"3.0\" in dataSource \"unknown-odataVersion\" for model \"v2-ODataModel-unknown-odataVersion\" is unknown. Falling back to default model type \"sap.ui.model.odata.v2.ODataModel\".", "[\"sap.app\"][\"dataSources\"][\"unknown-odataVersion\"]", this.oComponent.toString()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"type\" for model \"no-model-type\"", "[\"sap.ui5\"][\"models\"][\"no-model-type\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, sinon.match("Class \"sap.ui.not.defined.Model\" for model \"missing-model-class\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"missing-model-class\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Class \"sap.ui.test.v2models.parent.ModelNotDefined\" for model \"model-not-found\" could not be found", "[\"sap.ui5\"][\"models\"][\"model-not-found\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: ODataAnnotation \"undefined\" for dataSource \"odata-invalid-annotations\" could not be found in manifest", "[\"sap.app\"][\"dataSources\"][\"undefined\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"uri\" for ODataAnnotation \"annotation-without-uri\"", "[\"sap.app\"][\"dataSources\"][\"annotation-without-uri\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"json\" was expected to have type \"ODataAnnotation\" but was \"JSON\"", "[\"sap.app\"][\"dataSources\"][\"json\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"invalid\" for model \"dataSource-invalid\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"invalid\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"does-not-exist\" for model \"dataSource-not-found\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"does-not-exist\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Provided OData version \"3.0\" in dataSource \"unknown-odataVersion\" for model \"v2-ODataModel-unknown-odataVersion\" is unknown. Falling back to default model type \"sap.ui.model.odata.v2.ODataModel\".", "[\"sap.app\"][\"dataSources\"][\"unknown-odataVersion\"]", this.oComponent.getMetadata().getComponentName()); // check if models are set on component (and save them internally) @@ -894,15 +904,15 @@ sap.ui.define([ // jQuery.sap.log.error - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"type\" for model \"no-model-type\"", "[\"sap.ui5\"][\"models\"][\"no-model-type\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, sinon.match("Class \"sap.ui.not.defined.Model\" for model \"missing-model-class\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"missing-model-class\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Class \"sap.ui.test.v2models.parent.ModelNotDefined\" for model \"model-not-found\" could not be found", "[\"sap.ui5\"][\"models\"][\"model-not-found\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: ODataAnnotation \"undefined\" for dataSource \"odata-invalid-annotations\" could not be found in manifest", "[\"sap.app\"][\"dataSources\"][\"undefined\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"uri\" for ODataAnnotation \"annotation-without-uri\"", "[\"sap.app\"][\"dataSources\"][\"annotation-without-uri\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"json\" was expected to have type \"ODataAnnotation\" but was \"JSON\"", "[\"sap.app\"][\"dataSources\"][\"json\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"invalid\" for model \"dataSource-invalid\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"invalid\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"does-not-exist\" for model \"dataSource-not-found\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"does-not-exist\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Provided OData version \"3.0\" in dataSource \"unknown-odataVersion\" for model \"v2-ODataModel-unknown-odataVersion\" is unknown. Falling back to default model type \"sap.ui.model.odata.v2.ODataModel\".", "[\"sap.app\"][\"dataSources\"][\"unknown-odataVersion\"]", this.oComponent.toString()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"type\" for model \"no-model-type\"", "[\"sap.ui5\"][\"models\"][\"no-model-type\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, sinon.match("Class \"sap.ui.not.defined.Model\" for model \"missing-model-class\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"missing-model-class\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Class \"sap.ui.test.v2models.parent.ModelNotDefined\" for model \"model-not-found\" could not be found", "[\"sap.ui5\"][\"models\"][\"model-not-found\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: ODataAnnotation \"undefined\" for dataSource \"odata-invalid-annotations\" could not be found in manifest", "[\"sap.app\"][\"dataSources\"][\"undefined\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"uri\" for ODataAnnotation \"annotation-without-uri\"", "[\"sap.app\"][\"dataSources\"][\"annotation-without-uri\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"json\" was expected to have type \"ODataAnnotation\" but was \"JSON\"", "[\"sap.app\"][\"dataSources\"][\"json\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"invalid\" for model \"dataSource-invalid\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"invalid\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"does-not-exist\" for model \"dataSource-not-found\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"does-not-exist\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Provided OData version \"3.0\" in dataSource \"unknown-odataVersion\" for model \"v2-ODataModel-unknown-odataVersion\" is unknown. Falling back to default model type \"sap.ui.model.odata.v2.ODataModel\".", "[\"sap.app\"][\"dataSources\"][\"unknown-odataVersion\"]", this.oComponent.getMetadata().getComponentName()); // check if models are set on component (and save them internally) @@ -1142,6 +1152,7 @@ sap.ui.define([ sinon.assert.callCount(this.modelSpy.odataV4, 1); sinon.assert.calledWithExactly(this.modelSpy.odataV4, { serviceUrl: '/path/to/odata/service/', + metadataUrlParams: {"sap-language": "EN"}, autoExpandSelect: false, odataVersion: "2.0", operationMode: "Server", @@ -1171,6 +1182,7 @@ sap.ui.define([ sinon.assert.callCount(this.modelSpy.odataV4, 1); sinon.assert.calledWithExactly(this.modelSpy.odataV4, { serviceUrl: '/path/to/odata/service/', + metadataUrlParams: {"sap-language": "EN"}, autoExpandSelect: false, odataVersion: "foo", operationMode: "Server", @@ -1336,15 +1348,15 @@ sap.ui.define([ // jQuery.sap.log.error - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"type\" for model \"no-model-type\"", "[\"sap.ui5\"][\"models\"][\"no-model-type\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, sinon.match("Class \"sap.ui.not.defined.Model\" for model \"missing-model-class\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"missing-model-class\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Class \"sap.ui.test.v2models.parent.ModelNotDefined\" for model \"model-not-found\" could not be found", "[\"sap.ui5\"][\"models\"][\"model-not-found\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: ODataAnnotation \"undefined\" for dataSource \"odata-invalid-annotations\" could not be found in manifest", "[\"sap.app\"][\"dataSources\"][\"undefined\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"uri\" for ODataAnnotation \"annotation-without-uri\"", "[\"sap.app\"][\"dataSources\"][\"annotation-without-uri\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"json\" was expected to have type \"ODataAnnotation\" but was \"JSON\"", "[\"sap.app\"][\"dataSources\"][\"json\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"invalid\" for model \"dataSource-invalid\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"invalid\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"does-not-exist\" for model \"dataSource-not-found\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"does-not-exist\"]", this.oComponent.toString()); - sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Provided OData version \"3.0\" in dataSource \"unknown-odataVersion\" for model \"v2-ODataModel-unknown-odataVersion\" is unknown. Falling back to default model type \"sap.ui.model.odata.v2.ODataModel\".", "[\"sap.app\"][\"dataSources\"][\"unknown-odataVersion\"]", this.oComponent.toString()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"type\" for model \"no-model-type\"", "[\"sap.ui5\"][\"models\"][\"no-model-type\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, sinon.match("Class \"sap.ui.not.defined.Model\" for model \"missing-model-class\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"missing-model-class\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Class \"sap.ui.test.v2models.parent.ModelNotDefined\" for model \"model-not-found\" could not be found", "[\"sap.ui5\"][\"models\"][\"model-not-found\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: ODataAnnotation \"undefined\" for dataSource \"odata-invalid-annotations\" could not be found in manifest", "[\"sap.app\"][\"dataSources\"][\"undefined\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Missing \"uri\" for ODataAnnotation \"annotation-without-uri\"", "[\"sap.app\"][\"dataSources\"][\"annotation-without-uri\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"json\" was expected to have type \"ODataAnnotation\" but was \"JSON\"", "[\"sap.app\"][\"dataSources\"][\"json\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"invalid\" for model \"dataSource-invalid\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"invalid\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: dataSource \"does-not-exist\" for model \"dataSource-not-found\" not found or invalid", "[\"sap.app\"][\"dataSources\"][\"does-not-exist\"]", this.oComponent.getMetadata().getComponentName()); + sinon.assert.calledWithExactly(this.oLogSpy, "Component Manifest: Provided OData version \"3.0\" in dataSource \"unknown-odataVersion\" for model \"v2-ODataModel-unknown-odataVersion\" is unknown. Falling back to default model type \"sap.ui.model.odata.v2.ODataModel\".", "[\"sap.app\"][\"dataSources\"][\"unknown-odataVersion\"]", this.oComponent.getMetadata().getComponentName()); // check if models are set on component (and save them internally) @@ -1607,7 +1619,7 @@ sap.ui.define([ sinon.assert.calledWithExactly(this.oLogErrorSpy, sinon.match("Component Manifest: Class \"sap.ui.sample.model.MyModel\" for model \"class-not-loaded\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"class-not-loaded\"]", - this.oComponent.toString()); + this.oComponent.getMetadata().getComponentName()); assert.ok(this.oComponent.getMetadata() instanceof sap.ui.core.UIComponentMetadata, "The metadata is instance of UIComponentMetadata"); assert.ok(this.oComponent.getManifest(), "Manifest is available"); @@ -1727,7 +1739,7 @@ sap.ui.define([ sinon.assert.calledWithExactly(this.oLogErrorSpy, sinon.match("Component Manifest: Class \"sap.ui.sample.model.MyModel\" for model \"class-not-loaded\" could not be loaded."), "[\"sap.ui5\"][\"models\"][\"class-not-loaded\"]", - this.oComponent.toString()); + this.oComponent.getMetadata().getComponentName()); assert.ok(this.oComponent.getMetadata() instanceof sap.ui.core.UIComponentMetadata, "The metadata is instance of UIComponentMetadata"); assert.ok(this.oComponent.getManifest(), "Manifest is available"); diff --git a/src/sap.ui.core/test/sap/ui/core/qunit/component/testdata/v2models/parent/Component.js b/src/sap.ui.core/test/sap/ui/core/qunit/component/testdata/v2models/parent/Component.js index 89cf67b89d31..e85727da8f8e 100644 --- a/src/sap.ui.core/test/sap/ui/core/qunit/component/testdata/v2models/parent/Component.js +++ b/src/sap.ui.core/test/sap/ui/core/qunit/component/testdata/v2models/parent/Component.js @@ -337,9 +337,11 @@ sap.ui.define(["sap/ui/core/UIComponent"], function(UIComponent) { "type": "sap.ui.test.v2models.parent.ModelNotDefined" }, "dataSource-not-found": { + "type": "sap.ui.model.odata.v2.ODataModel", "dataSource": "does-not-exist" }, "dataSource-invalid": { + "type": "sap.ui.model.odata.v2.ODataModel", "dataSource": "invalid" }