/*!
* Copyright (c) 2009 Francesco Mele jsbeans@francescomele.com
*
* This Software is licenced under the LGPL Licence (GNU Lesser General
* Public License).
* In addition to the LGPL Licence the Software is subject to the
* following conditions:
*
* i every modification must be public and comunicated to the Author
* ii every "jsbean" added to this library must be self consistent
* except for the dependence from jsbeans-x.x.x.js
* iii copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/**
* A collection of utilities for managing javascript Objects both custom or native.
* @namespace jsbeans
* @class Object
* @static
*/
jsbeans.Object = {
/**
* Intercepts a method and invokes a handler <strong>before</strong> its execution.<br/>
* Arguments remains untouched for the original method, while the {@param} <code class="param">handler</code> takes {@param} <code class="param">args</code>.
* @method before
* @param instance {Object} the variable containing the reference to the instance of an Object
* @param name {String} the name of the method to be wrapped
* @param handler {Function} the function fired before method named as <code class="param">name</code>
* @param [args] {Object} optional arguments for the <code class="param">handler</code>
* @static
*/
before: function(instance, name, handler) {
if (typeof instance[name] != "undefined") {
var original = instance[name];
var args;
if (typeof arguments[3] != "undefined") {
args = [];
for (var i = 3, arg; arg = arguments[i]; i++) {
args.push(arg);
}
}
instance[name] = function() {
if (arguments.length > 0) {
var originalArgs = [];
for (var i = 0, arg; arg = arguments[i]; i++) {
originalArgs.push(arg);
}
}
handler.apply(null, args);
original.apply(instance, originalArgs);
};
}
},
/**
* Intercepts a method and invokes a handler <strong>instead of</strong> its execution.<br/>
* The {@param} <code class="param">handler</code> takes {@param} <code class="param">args</code> as arguments.
* @method override
* @param instance {Object} the variable containing the reference to the instance of an Object
* @param name {String} the name of the method to be overridden
* @param handler {Function} the function fired instead method named as <code class="param">name</code>
* @param [args] {Object} optional arguments for the <code class="param">handler</code>
* @static
*/
override: function(instance, name, handler) {
if (typeof instance[name] != "undefined") {
var args;
if (typeof arguments[3] != "undefined") {
args = [];
for (var i = 3, arg; arg = arguments[i]; i++) {
args.push(arg);
}
}
instance[name] = function() {
handler.apply(null, args);
};
}
},
/**
* Intercepts a method and invokes a handler <strong>after</strong> its execution.<br/>
* Arguments remains untouched for the original method, while the {@param} <code class="param">handler</code> takes {@param} <code class="param">args</code>.
* @method after
* @param instance {Object} the variable containing the reference to the instance of an Object
* @param name {String} the name of the method to be wrapped
* @param handler {Function} the function fired after method named as <code class="param">name</code>
* @param [args] {Object} optional arguments for the <code class="param">handler</code>
* @static
*/
after: function(instance, name, handler) {
if (typeof instance[name] != "undefined") {
var original = instance[name];
var args;
if (typeof arguments[3] != "undefined") {
args = [];
for (var i = 3, arg; arg = arguments[i]; i++) {
args.push(arg);
}
}
instance[name] = function() {
if (arguments.length > 0) {
var originalArgs = [];
for (var i = 0, arg; arg = arguments[i]; i++) {
originalArgs.push(arg);
}
}
original.apply(instance, originalArgs);
handler.apply(null, args);
};
}
},
/**
* Intercepts an error thrown by a method and invokes a handler <strong>after</strong> its execution.<br/>
* Arguments remains untouched for the original method, while the {@param} <code class="param">handler</code> takes {@param} <code class="param">args</code>.
* @method afterThrowing
* @param instance {Object} the variable containing the reference to the instance of an Object
* @param name {String} the name of the method to be wrapped
* @param handler {Function} the function fired after method named as <code class="param">name</code> has thrown an error
* @param [args] {Object} optional arguments for the <code class="param">handler</code>
* @static
*/
afterThrowing: function(instance, name, handler) {
if (typeof instance[name] != "undefined") {
var original = instance[name];
var args;
if (typeof arguments[3] != "undefined") {
args = [];
for (var i = 3, arg; arg = arguments[i]; i++) {
args.push(arg);
}
}
instance[name] = function() {
if (arguments.length > 0) {
var originalArgs = [];
for (var i = 0, arg; arg = arguments[i]; i++) {
originalArgs.push(arg);
}
}
try {
original.apply(instance, originalArgs);
}
catch(e) {
handler.apply(null, args);
}
};
}
},
/**
* Returns false at first <code>undefined</code> Object passed as argument.<br/>
* For a deeper check against <code>undefined</code> <strong>and</strong> <code>null</code> use <code class="methd">isDefOrNull</code>
* @method isDefined
* @param arguments {Object} Uses the native <code>arguments</code> list.
* @return {boolean} false if at least one argument is <code>undefined</code> checked with native <code>typeof</code> operator. If no argument is passed it returns true.
* @static
*/
isDefined: function() {
for (var i = 0, arg; arg = arguments[i]; i++) {
if (typeof arg == "undefined") {
return false;
}
}
return true;
},
/**
* Shorten alias for <code class="methd">isDefined</code>
* @method isDef
* @static
* @see jsbeans.Object.isDefined
*/
isDef: function() {
return jsbeans.Object.isDefined(arguments);
},
/**
* Returns false at first <code>undefined</code> or <code>null</code> Object passed as argument.<br/>
* If no arguments is passed it returns false
* @method isDefinedOrNull
* @param arguments {Object} Uses the native <code>arguments</code> list.
* @return {boolean} false if at least one argument is <code>undefined</code> (checked with native <code>typeof</code> operator) or <code>null</code>. If no argument is passed it returns false.
* @static
*/
isDefinedOrNull: function() {
if (arguments.length == 0) {
return false;
}
for (var i = 0, arg; arg = arguments[i]; i++) {
if (typeof arg == "undefined" || arg == null) {
return false;
}
}
return true;
},
/**
* Shorten alias for <code class="methd">isDefinedOrNull</code>
* @method isDefOrNull
* @static
* @see jsbeans.Object.isDefinedOrNull
*/
isDefOrNull: function() {
if (arguments.length == 0) {
return false;
}
return jsbeans.Object.isDefinedOrNull(arguments);
}
};