/* Authors: * Petr Vobornik * * Copyright (C) 2012 Red Hat * see file 'COPYING' for use and warranty information * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ define(['dojo/_base/declare', 'dojo/_base/array', 'dojo/_base/lang', './construct', './Construct_registry', './Spec_mod' ], function(declare, array, lang, construct, Construct_registry, Spec_mod) { var undefined; /** * Builder * * Builds objects based on their specification. * @class _base.Builder */ var Builder = declare(null, { /** * Construct registry * @property {_base.Construct_registry} */ registry: null, /** * Specification modifier * @property {_base.Spec_mod} */ spec_mod: null, /** * Default factory * @property {Function|null} */ factory: null, /** * Default constructor * @property {Function|null} */ ctor: null, /** * Array of spec modifiers. * * Are applied before build on spec object. * * Spec modifier can be: * * - a function which is called before build * - takes params: spec, context * - returns spec * - an object which is mixed in into spec * - an object with properties for Spec_mod * * @property {Array|null} */ pre_ops: null, /** * Array of object modifiers. * * Object modifier is a function which is after build. * * - takes params: built object, spec, context * - returns object * @property {Array|null} */ post_ops: null, /** * Controls what builder do when spec is a string. Possible values: * * - 'type' * - 'property' * * ##Type * Spec is type. Queries registry for obtaining construction spec. * * ##Property * Spec is a property of spec, name of property is set in * `string_property`. This mode should be combined with default * factory or ctor otherwise the build will fail. * * @property {string} */ string_mode: 'type', /** * Property name for `string_mode` == `property` * @property {string} */ string_property: '', /** * Build object based on spec. * * @param {string|Function|Object|Array} spec Build spec * * - **String**: type name, queries registry * - **Function**: factory or ctor * - **Object**: spec object * - **Array**: array of spec objects * * Build control properties of spec object: * * - $ctor: Function * - $factory: Function * - $mixim_spec: boolean * - $type: string * - $pre_ops: [] * - $post_ops: [] * * All other properties will be passed to object construction method. * @param {Object} context build context * @param {Object} overrides * Builder default factory and ctor is overridden by those specified * in overrides when overrides are set. */ build: function(spec, context, overrides) { var f,c, pre, post; if (spec === undefined || spec === null) return null; if (!construct.is_spec(spec)) return spec; context = context || {}; // save if (overrides) { f = this.factory; c = this.ctor; pre = this.pre_ops; post = this.post_ops; if (typeof overrides === 'function') { if (construct.is_ctor(overrides)) { overrides = { $ctor: overrides }; } else { overrides = { $factory: overrides }; } } this.factory = overrides.$factory; this.ctor = overrides.$ctor; if (overrides.$pre_ops) this.pre_ops = overrides.$pre_ops; if (overrides.$post_ops) this.post_ops = overrides.$post_ops; } // build var objects; if (lang.isArray(spec)) { objects = []; for (var i=0; i