UNPKG

@openui5/sap.ui.core

Version:

OpenUI5 Core Library sap.ui.core

251 lines (224 loc) 8.29 kB
/*! * OpenUI5 * (c) Copyright 2009-2021 SAP SE or an SAP affiliate company. * Licensed under the Apache License, Version 2.0 - see LICENSE.txt. */ // Provides ControllerMetadata sap.ui.define([ 'sap/ui/base/Metadata', 'sap/base/util/merge', 'sap/ui/core/mvc/OverrideExecution', "sap/base/Log" ], function(Metadata, merge, OverrideExecution, Log) { "use strict"; /** * @alias sap.ui.core.mvc.ControllerMetadata * @extends sap.ui.base.Metadata * @private */ var ControllerMetadata = function(sClassName, oClassInfo) { // call super constructor Metadata.apply(this, arguments); // propagate static functions to subclasses of ControllerExtension if (this.isA("sap.ui.core.mvc.ControllerExtension") && this.getParent().getClass().override ) { this.getClass().override = this.getParent().getClass().override; } }; // chain the prototypes ControllerMetadata.prototype = Object.create(Metadata.prototype); ControllerMetadata.prototype.constructor = ControllerMetadata; ControllerMetadata.prototype.applySettings = function(oClassInfo) { // property 'override' needs to be handled separately and must not be attached to the prototype if (oClassInfo.override) { this._override = oClassInfo.override; delete oClassInfo.override; } Metadata.prototype.applySettings.call(this, oClassInfo); var oStaticInfo = oClassInfo.metadata; this._defaultLifecycleMethodMetadata = { "onInit": {"public": true, "final": false, "overrideExecution": OverrideExecution.After}, "onExit": {"public": true, "final": false, "overrideExecution": OverrideExecution.Before}, "onBeforeRendering": {"public": true, "final": false, "overrideExecution": OverrideExecution.Before}, "onAfterRendering": {"public": true, "final": false, "overrideExecution": OverrideExecution.After} }; var bIsExtension = this.isA("sap.ui.core.mvc.ControllerExtension"); var rPrivateCheck = /^_/; var bExtendsController = this._oParent.isA("sap.ui.core.mvc.Controller"); var bDefinesMethods = oClassInfo.metadata && oClassInfo.metadata.methods ? true : false; if (!bIsExtension) { /* * If methods are defined in metadata, only methods prefixed with '_' get private. * If not, we stay compatible and every method prefixed with '-' or 'on' gets private. */ if (bExtendsController && !bDefinesMethods) { rPrivateCheck = /^_|^on|^init$|^exit$/; } /* * extend method metadata: make lifecycle hooks public */ if (bExtendsController && bDefinesMethods) { merge(oStaticInfo.methods, this._defaultLifecycleMethodMetadata); } } //check public methods //in legacy scenarion the public methods defined in metadata must not be deleted if (bIsExtension || bDefinesMethods) { this._aPublicMethods = []; } this._mMethods = oStaticInfo.methods || {}; for ( var n in oClassInfo ) { if ( n !== "metadata" && n !== "constructor") { if (!n.match(rPrivateCheck)) { //final check if (bExtendsController && this._oParent && this._oParent.isMethodFinal(n)) { Log.error("Method: '" + n + "' of controller '" + this._oParent.getName() + "' is final and cannot be overridden by controller '" + this.getName() + "'"); delete this._oClass.prototype[n]; } // default metadata for methods if (!(n in this._mMethods) && typeof oClassInfo[n] === 'function') { // do not provide metadata for extension members if (!(oClassInfo[n].getMetadata && oClassInfo[n].getMetadata().isA("sap.ui.core.mvc.ControllerExtension"))) { this._mMethods[n] = {"public": true, "final": false}; } } } } } for (var m in this._mMethods) { if (this.isMethodPublic(m)) { this._aPublicMethods.push(m); } } }; /** * Called after new settings have been applied. * * Typically, this method is used to do some cleanup (e.g. uniqueness) * or to calculate an optimized version of some data. * @private * @since 1.3.1 */ ControllerMetadata.prototype.afterApplySettings = function() { Metadata.prototype.afterApplySettings.call(this); var bIsExtension = this.isA("sap.ui.core.mvc.ControllerExtension"); if (this._oParent) { var mParentMethods = this._oParent._mMethods ? this._oParent._mMethods : {}; //allow change of visibility but not the other attributes for (var sMethod in mParentMethods) { if (this._mMethods[sMethod] && !bIsExtension) { var bPublic = this._mMethods[sMethod].public; //copy parent method definition as final/overrideExecution should not be overridden this._mMethods[sMethod] = merge({}, mParentMethods[sMethod]); if (bPublic !== undefined) { this._mMethods[sMethod].public = bPublic; } if (!this.isMethodPublic(sMethod) && this._mMethods[sMethod].public !== mParentMethods[sMethod].public) { //if visibility changed to private delete from public methods this._aAllPublicMethods.splice(this._aAllPublicMethods.indexOf(sMethod), 1); } } else { this._mMethods[sMethod] = mParentMethods[sMethod]; } } } //flag each extension as final (but not the class ControllerExtension itself) if (this._oParent && this._oParent.isA("sap.ui.core.mvc.ControllerExtension")) { this._bFinal = true; } }; /** * Returns the Namespace for a ControllerExtension. The Namespace is * extracted from the ControllerExtensions name: * <pre> * name: my.name.space.Extension * namespace = my.name.space * </pre> * @return {string} The Namespace * @public */ ControllerMetadata.prototype.getNamespace = function() { var bIsAnonymous = this._sClassName.indexOf("anonymousExtension~") == 0; var sNamespace = bIsAnonymous ? this._oParent._sClassName : this._sClassName; return sNamespace.substr(0,sNamespace.lastIndexOf(".")); }; /** * Check if method is flagged as final. * * @param {string} sMethod Name of the method * @return {boolean} Whether the method is flagged as final or not */ ControllerMetadata.prototype.isMethodFinal = function(sMethod) { var oMethodMetadata = this._mMethods[sMethod]; return oMethodMetadata && oMethodMetadata.final; }; /** * Check if method is flagged as public. * * @param {string} sMethod Name of the method * @return {boolean} Whether the method is flagged as public or not */ ControllerMetadata.prototype.isMethodPublic = function(sMethod) { var oMethodMetadata = this._mMethods[sMethod]; return oMethodMetadata && oMethodMetadata.public; }; /** * Get all defined methods and their metadata. * * @return {Object<string,object>} A map containing all methods (key) and their metadata */ ControllerMetadata.prototype.getAllMethods = function() { return this._mMethods; }; /** * Returns the override execution strategy for the given method. * * @param {string} sMethod Name of the method * @return {sap.ui.core.mvc.OverrideExecution} The override execution strategy */ ControllerMetadata.prototype.getOverrideExecution = function(sMethod) { var oMethodMetadata = this._mMethods[sMethod]; var sOverrideExecution = OverrideExecution.Instead; if (oMethodMetadata) { sOverrideExecution = oMethodMetadata.overrideExecution; } return sOverrideExecution; }; /** * Returns the override definition of this extension. * * @return {object} The overrides * @private */ ControllerMetadata.prototype.getOverrides = function() { return this._override; }; /** * Returns the 'static' override definition registered by the override function for this extension * * @return {object} The static overrides * @private */ ControllerMetadata.prototype.getStaticOverrides = function() { return this._staticOverride; }; /** * Checks whether override definitions exists. * * @return {boolean} Whether override definitions exists * @private */ ControllerMetadata.prototype.hasOverrides = function() { return !!this._override || !!this._staticOverride; }; /** * Get configuration for extending lifecycle methods. * * @return {Object<string,object>} A map containing the lifecycle configuration metadata * @private */ ControllerMetadata.prototype.getLifecycleConfiguration = function() { return this._defaultLifecycleMethodMetadata; }; return ControllerMetadata; });