GeoKnow/Jassa-Core

View on GitHub
lib/util/ObjectUtils.js

Summary

Maintainability
A
55 mins
Test Coverage
var isEqual = require('lodash.isequal');

var JsonUtils = require('./JsonUtils');

var ObjectUtils = {
    /**
     * Reference counting for keys
     *
     * @param obj
     * @param attr
     */
    alloc: function(obj, attr) {
        var result;

        if(!(attr in obj)) {
            result = obj[attr] = 1;
        } else {
            result = ++obj[attr];
        }

        return result;
    },

    free: function(obj, attr) {
        var result;

        if(attr in obj) {
            result = --obj[attr];
            if(result <= 0) {
                delete obj[attr];
            }
        } else {
            result = null;
        }

        return result;
    },

    isEmptyString: function(str) {
        var result = str == null || str.length === 0 || str.trim() === '';
        return result;
    },

    isObject: function(obj) {
        var type = typeof obj;
        return type === 'function' || type === 'object' && Boolean(obj);
    },

    isFunction: function(obj) {
        return typeof obj === 'function';
    },

    isString: function(obj) {
        return Object.prototype.toString.call(obj) === '[object String]';
    },

    extend: function(obj, source) {
        for (var prop in source) {
            if (hasOwnProperty.call(source, prop)) {
                obj[prop] = source[prop];
            }
        }
        return obj;
    },

    clear: function(obj) {
        for(var attr in obj) {
            if(obj.hasOwnProperty(attr)) {
                delete obj[attr];
            }
        }
    },


    isEqual: function(a, b) {
        var result;
        if (a && a.equals) {
            result = a.equals(b);
        } else if (b && b.equals) {
            result = b.equals(a);
        } else {
            result = isEqual(a, b);
        }

        return result;
    },

    defaultHashCode: function(a) {
        var result;
        if (a && a.hashCode) {
            result = a.hashCode();
        } else {
            result = ObjectUtils.hashCode(a);//a.toString();
        }

        return result;
    },

    /**
     * Used to turn copySubstitute into a clone method
     */
    identity: function(x) {
        return x;
    },

    // http://jsperf.com/hashing-strings
    hashCodeStr : function(str) {
        var res = 0,
        len = (str && str.length) ? str.length : 0;
        for (var i = 0; i < len; i++) {
            res = res * 31 + str.charCodeAt(i);
            res = res & res;
        }
        return res;
    },


    /**
     * Recursively iterate the object tree and use a .hashCode function if available
     * TODO Add support to exclude attributes
     */
    hashCode: function(obj, skipOnce) {

        var result = JsonUtils.stringifyCyclic(obj, function(key, val) {

            var r = null;

            if (!skipOnce && ObjectUtils.isObject(val)) {

                var hashFnName = null;
                ObjectUtils.defaultHashFnNames.some(function(name) {
                    if (ObjectUtils.isFunction(val[name])) {
                        hashFnName = name;
                        return true;
                    }
                });

                var fnHashCode = val[hashFnName];

                if (hashFnName && fnHashCode && ObjectUtils.isFunction(fnHashCode)) {
                    r = fnHashCode.apply(val);
                } else {
                    r = val;
                }

            } else {
                r = val;
            }

            if (skipOnce) {
                skipOnce = false;
            }

            return r;
        });

        return result;
    }
};

ObjectUtils.defaultHashFnNames = [
    'hashCode'
];

module.exports = ObjectUtils;