JavaScript Extension Development API for Oracle Visual Builder Cloud Service - Classic Applications

Source: core/js/api/SharedObjectRegistry.js

define([
    'core/js/api/Logger'
], function (
    Logger
    ) {

    'use strict';

    /**
     * Registry containing global shared objects.
     *
     * @AbcsExtension stable
     * @exports core/js/api/SharedObjectRegistry
     * @private
     * @constructor
     * @singleton
     * @version 16.3.5
     */
    function SharedObjectRegistry () {
        AbcsLib.checkThis(this);
        AbcsLib.checkSingleton(SharedObjectRegistry);
        this._objects = {};
    }

    SharedObjectRegistry._LOGGER = Logger.get('core/js/api/SharedObjectRegistry');

    /**
     * Registers new shared object into Abcs environment.
     * <p>This method registers your custom shared object you want to
     * use globally from other places throughout Abcs (such as Custom code,
     * calculated Formulas or the Expression builder built into query filters).</p>
     * <p>Any shared object may be accessed via {@link module:api/js/System.getSharedObject System.getSharedObject}.</p>
     *
     * @AbcsExtension stable
     * @param {String} id <strong>unique</strong> shared object's identifier.
     * Should be prefixed with dot-separated package name to make it globally unique.
     * For example <code>org.my.mySharedObject</code>.
     * <p>It may derive from the id of a providing ABCS extension (or may be equal),
     * see {@link extensions.dt/js/spi/ExtensionManager ExtensionManager}.</p>
     * <p>The id cannot end with '.', i.e. the name of the shared object cannot be empty.</p>
     * @param {Object} sharedObject the object to register.
     * @param {String} [displayName=id] optional display name for the shared object.
     * The value will represent the object in various ABCS UIs. When not specified
     * part of the id will be used instead.
     * @returns {Boolean} <code>true</code> if the object was successfully registered,
     * <code>false</code> otherwise  (when for example another shared object is
     * already registered under the same id).
     * @throws {Error} when invalid id is passed or sharedObject is not provided.
     * @see {@link module:api/js/System.getSharedObject System.getSharedObject}
     * @version 16.3.5
     * @example <caption>Registering a simple shared object</caption>
     * // create a simple shared object
     * var currentTime = {
     *     getTime: function() {
     *         return new Date().toISOString();
     *     }
     * };
     * // register a shared object
     * sharedObjectRegistry.register('com.company.abcs.extensions.currentTime', currentTime);
     *
     * @example
     * <caption>Shows how to get a shared object and access its method.</caption>
     * // get the shared object
     * var myObject = Abcs.System().getSharedObject('com.company.abcs.extensions.currentTime');
     * // call shared object's method
     * var time = myObject.getTime();
     *
     * Abcs.UI().showNotification(Abcs.UI().Notification.create({
     *      message: 'It is ' + time
     * });
     */
    SharedObjectRegistry.prototype.register = function (id, sharedObject, displayName) {
        AbcsLib.checkParameterCount(arguments, 2, 1);
        AbcsLib.checkDefined(id, 'id');
        AbcsLib.checkDefined(sharedObject, 'sharedObject');
        SharedObjectRegistry._validateId(id);

        var existingObject = this._objects[id];
        if (existingObject && existingObject.object !== sharedObject) {
            SharedObjectRegistry._LOGGER.warn('Shared object with id "' + id + '" already exists');
            return false;
        }
        if (displayName) {
            AbcsLib.checkDataType(displayName, AbcsLib.Type.STRING);
        }
        this._objects[id] = new SharedObjectRegistry.SharedObject(id, sharedObject, displayName);
        return true;
    };

    /**
     * Removes previously registered shared object from the Abcs environment.
     *
     * @AbcsExtension stable
     * @returns {Boolean} truthy value if the object was successfully removed
     * @param {String} id shared object's identifier.
     * @version 16.3.5
     * @example <caption>Unregistering a shared object</caption>
     * sharedObjectRegistry.unregister('com.company.abcs.extensions.currentTime');
     */
    SharedObjectRegistry.prototype.unregister = function (id) {
        AbcsLib.checkDefined(id, 'id');
        var object = this._objects[id];
        if (object) {
            delete this._objects[id];
            return true;
        }
        return false;
    };

    /**
     * Returns shared object registered with the given id.
     * <p>Do not call this method directly, use
     * {@link module:api/js/System.getSharedObject System.getSharedObject}
     * instead.</p>
     *
     * @param {String} id registered object id.
     * @returns {Object} shared object previously registered with the given id.
     * @see {@link module:api/js/System.getSharedObject System.getSharedObject}
     */
    SharedObjectRegistry.prototype.getSharedObject = function (id) {
        var sharedObject = this._objects[id];
        return sharedObject && sharedObject._obj;
    };

    /**
     * Returns all shared objects flattened into an array along with their
     * description.
     *
     * @returns {core/js/api/SharedObjectRegistry.SharedObject[]} registered object descriptions
     */
    SharedObjectRegistry.prototype.getSharedObjectDescriptions = function () {
        var objects = this._objects;
        return Object.keys(objects).map(function (key) {
            return objects[key];
        });
    };

    SharedObjectRegistry._getName = function (id) {
        var segments = id.split('.');
        return segments[segments.length - 1];
    };

    SharedObjectRegistry._validateId = function (id) {
        var name = SharedObjectRegistry._getName(id);
        if (!name.length) {
            SharedObjectRegistry._invalidId(id, 'shared object name cannot be empty');
        }
    };

    SharedObjectRegistry._invalidId = function (id, description) {
        throw new Error('Invalid id: \'' + id + '\', ' + description);
    };

    var SharedObject = function (id, obj, displayName) {
        AbcsLib.checkThis(this);
        this._id = id;
        this._name = SharedObjectRegistry._getName(id);
        this._displayName = displayName || this._name;
        this._obj = obj;
    };

    /**
     * Returns name of the registered object. The name is just a part (the last
     * id segment) of its full id.
     */
    SharedObject.prototype.getName = function () {
        return this._name;
    };

    /**
     * Returns human readable display name of the shared object.
     *
     * When not specified, it defaults to {@link core/js/api/SharedObjectRegistry.SharedObject.getName SharedObject.getName}.
     */
    SharedObject.prototype.getDisplayName = function () {
        return this._displayName;
    };

    /**
     * Returns array of public instance fields of this object.
     * @returns {String[]} instance field names
     */
    SharedObject.prototype.getFields = function () {
        var fields = [];
        var obj = this._obj;
        if (typeof obj === 'object') {
            for (var f in obj) {
                if (!SharedObject._isPrivate(f) && typeof obj[f] !== 'function') {
                    fields.push(f);
                }
            }
        }
        fields.sort();
        return fields;
    };

    /**
     * Returns array of public instance methods of this object.
     * @returns {String[]} instance method names
     */
    SharedObject.prototype.getMethods = function () {
        var methods = [];
        var obj = this._obj;
        if (typeof obj === 'object') {
            for (var m in obj) {
                if (!SharedObject._isPrivate(m) && typeof obj[m] === 'function'
                        && obj[m] !== obj.constructor) {
                    methods.push(m);
                }
            }
        }
        methods.sort();
        return methods;
    };

    /**
     * Returns full id of the shared object.
     */
    SharedObject.prototype.getId = function () {
        return this._id;
    };

    SharedObject._isPrivate = function (fieldName) {
        return !fieldName || fieldName.charAt(0) === '_';
    };

    SharedObjectRegistry.SharedObject = SharedObject;

    return AbcsLib.initSingleton(SharedObjectRegistry);

});