All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scout.util.defaultValues.js Maven / Gradle / Ivy

There is a newer version: 25.1.0-beta.0
Show newest version
/*******************************************************************************
 * Copyright (c) 2014-2015 BSI Business Systems Integration AG.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     BSI Business Systems Integration AG - initial API and implementation
 ******************************************************************************/
scout.defaultValues = {

  /**
   * map of "objectType" -> { defaultValuesObject }
   */
  _defaults: {},

  /**
   * map of "objectType" -> [ "objectType", "parentObjectType", ..., "topLevelObjectType" ]
   */
  _objectTypeHierarchyFlat: {},

  bootstrap: function() {
    var that = this;
    // Load default value configuration from server (and cache it)
    return $.ajax({
      async: true,
      type: 'GET',
      dataType: 'json',
      contentType: 'application/json; charset=UTF-8',
      cache: true,
      url: 'defaultValues',
      data: ''
    }).done(function(data) {
      that._loadDefaultsConfiguration(data);
    }).fail(function(jqXHR, textStatus, errorThrown) {
      throw new Error('Error while loading default values: ' + errorThrown);
    });
  },

  _loadDefaultsConfiguration: function(data) {
    // Store defaults
    this._objectTypeHierarchyFlat = {};
    this._defaults = data.defaults || {};

    // Generate object type hierarchy
    var objectTypeHierarchy = data.objectTypeHierarchy || {};
    this._generateObjectTypeHierarchyRec(objectTypeHierarchy, undefined, this._objectTypeHierarchyFlat);

    // For all object types in the defaults that don't have a hierarchy yet, add a dummy hierarchy with one element
    for (var objectType in this._defaults) {
      if (!this._objectTypeHierarchyFlat[objectType]) {
        this._objectTypeHierarchyFlat[objectType] = [objectType];
      }
    }
  },

  _generateObjectTypeHierarchyRec: function(json, currentParentObjectTypes, targetMap) {
    if (!json) {
      return;
    }
    if (!targetMap) {
      throw new Error('Argument \'targetMap\' must not be null');
    }
    for (var objectType in json) {
      var newCurrentParentObjectTypes = [objectType];
      if (currentParentObjectTypes) {
        newCurrentParentObjectTypes = newCurrentParentObjectTypes.concat(currentParentObjectTypes);
      }

      if (typeof json[objectType] === 'object') {
        this._generateObjectTypeHierarchyRec(json[objectType], newCurrentParentObjectTypes, targetMap);
      }

      // Store current result
      if (targetMap[objectType]) {
        throw new Error('Object type \'' + objectType + '\' has ambiguous parent object types.');
      }
      targetMap[objectType] = newCurrentParentObjectTypes;
    }
  },

  /**
   * Applies the defaults for the given object type to the given object. Properties
   * are only set if they don't exist yet. The argument 'objectType' is optional
   * if the object has a property of the same name. If the object is an array,
   * the defaults are applied to each of the elements.
   */
  applyTo: function(object, objectType) {
    if (Array.isArray(object)) {
      for (var i = 0; i < object.length; i++) {
        this.applyTo(object[i], objectType);
      }
    } else if (typeof object === 'object') {
      objectType = objectType || object.objectType;
      if (objectType) {
        this._applyToInternal(object, objectType);
      }
    }
  },

  _applyToInternal: function(object, objectType) {
    var objectTypeHierarchy = this._objectTypeHierarchyFlat[objectType];
    if (!objectTypeHierarchy) {
      // Remove model variant and try again
      objectType = objectType.replace(/\..*/, '');
      objectTypeHierarchy = this._objectTypeHierarchyFlat[objectType];
    }
    if (!objectTypeHierarchy) {
      // Unknown type, nothing to apply
      return;
    }
    for (var i = 0; i < objectTypeHierarchy.length; i++) {
      var t = objectTypeHierarchy[i];
      var defaults = this._defaults[t];
      this._extendWithDefaults(object, defaults);
    }
  },

  _extendWithDefaults: function(object, defaults) {
    if (object === undefined || defaults === undefined) {
      return;
    }
    for (var prop in defaults) {
      // Support for "pseudo" default values: If a property name in the default values definition
      // starts with a "~" character, the defined object will _not_ be applied as a default value
      // for a non-existing property, but inner properties of that object will be applied to an
      // existing object.
      var realProp = prop;
      if (scout.strings.startsWith(prop, '~')) {
        realProp = prop.substring(1);
      }
      // If property does not exist, set the default value and return.
      if (object[realProp] === undefined) {
        object[realProp] = scout.objects.valueCopy(defaults[realProp]);
      }
      // Special case: "default objects". If the property value is an object and default
      // value is also an object, extend the property value instead of replacing it.
      else if (scout.objects.isPlainObject(object[realProp]) && scout.objects.isPlainObject(defaults[prop])) {
        this._extendWithDefaults(object[realProp], defaults[prop]);
      }
      // Special case: "array of default objects": If the property value is an array of objects and
      // the default value is an object, extend each object in the array with the default value.
      else if (Array.isArray(object[realProp]) && scout.objects.isPlainObject(defaults[prop])) {
        var objectArray = object[realProp];
        for (var i = 0; i < objectArray.length; i++) {
          if (scout.objects.isPlainObject(objectArray[i])) {
            this._extendWithDefaults(objectArray[i], defaults[prop]);
          }
        }
      }
    }
  }

};




© 2015 - 2025 Weber Informatics LLC | Privacy Policy