<commit_before>/**
 *
 * @class ModelFactory
 * @module
 * @static
 */
var ModelFactory = {
    /**
     * Takes the given model description along with the origin (JSON) object
     * and returns the populated model.
     *
     * @method populate
     * @param {ModelDescription|Object}     modelDescription        The particular model description object.
     * @param {JSON|Object}                 origin                  The particular JSON origin.
     * @returns {Object}
     */
    populate: function (modelDescription, origin) {
        var keys = Object.keys(modelDescription),
            namespaceExtractor = this._extractNamespace,
            preparedOrigin = {},
            parsedOutput = {},
            computedProperties = [];

        if (modelDescription.hasOwnProperty('namespace')) {
            preparedOrigin = namespaceExtractor(origin, modelDescription.namespace);
        } else {
            preparedOrigin = origin;
        }

        keys.forEach(function (key) {
            var value = modelDescription[key],
                includeProperty = true,
                parsedValue;

            if (typeof value === 'function') {
                // keep computed properties to evaluate them after the ordinary properties has been evaluated.
                // the evaluated properties will be accessible within the property function
                computedProperties.push(key);

            } else {
                includeProperty = key.indexOf('serializable') < 0 && key.indexOf('namespace') < 0;
                if (includeProperty) {
                    if (preparedOrigin.hasOwnProperty(value)) {
                        parsedValue = preparedOrigin[value];
                    } else {
                        parsedValue = namespaceExtractor(preparedOrigin, value);
                    }
                }
                if (includeProperty) {
                    parsedOutput[key] = parsedValue;
                }
            }
        });

        computedProperties.forEach(function (key) {
            var fn = modelDescription[key];
            parsedOutput[key] = fn.call(preparedOrigin, preparedOrigin, namespaceExtractor);
        });

        return parsedOutput;
    },

    /**
     * Takes the given origin (JSON/Object) and namespace and returns
     * the namespaced/reduced object.
     *
     * @param origin
     * @param namespace
     * @returns {*}
     * @private
     */
    _extractNamespace: function (origin, namespace) {
        var namespacedOrigin = null;

        if (typeof namespace === 'string' && namespace.indexOf('.') > -1) {
            var splittedNamespace = namespace.split('.'),
                nestedOrigin = Object.create(origin);

            splittedNamespace.forEach(function getNamespaceExtractedOrigin(namespaceKey) {
                nestedOrigin = nestedOrigin[namespaceKey];
            });

            namespacedOrigin = nestedOrigin;
        } else {
            namespacedOrigin = origin[namespace];
        }

        return namespacedOrigin;
    }
};

module.exports = ModelFactory;<commit_msg>ModelFactory works with prepared origin where possible.<commit_after>/**
 *
 * @class ModelFactory
 * @module
 * @static
 */
var ModelFactory = {
    /**
     * Takes the given model description along with the origin (JSON) object
     * and returns the populated model.
     *
     * @method populate
     * @param {ModelDescription|Object}     modelDescription        The particular model description object.
     * @param {JSON|Object}                 origin                  The particular JSON origin.
     * @returns {Object}
     */
    populate: function (modelDescription, origin) {
        var keys = Object.keys(modelDescription),
            namespaceExtractor = this._extractNamespace,
            preparedOrigin = {},
            parsedOutput = {},
            computedProperties = [];

        if (modelDescription.hasOwnProperty('namespace')) {
            preparedOrigin = namespaceExtractor(origin, modelDescription.namespace);
        } else {
            preparedOrigin = origin;
        }

        keys.forEach(function (key) {
            var value = modelDescription[key],
                includeProperty = true,
                parsedValue;

            if (typeof value === 'function') {
                // keep computed properties to evaluate them after the ordinary properties has been evaluated.
                // the evaluated properties will be accessible within the property function
                computedProperties.push(key);

            } else {
                includeProperty = key.indexOf('serializable') < 0 && key.indexOf('namespace') < 0;
                if (includeProperty) {
                    if (preparedOrigin.hasOwnProperty(value)) {
                        parsedValue = preparedOrigin[value];
                    } else {
                        parsedValue = namespaceExtractor(preparedOrigin, value);
                    }
                }
                if (includeProperty) {
                    parsedOutput[key] = parsedValue;
                }
            }
        });

        computedProperties.forEach(function (key) {
            var fn = modelDescription[key];
            parsedOutput[key] = fn.call(preparedOrigin, preparedOrigin, namespaceExtractor);
        });

        return parsedOutput;
    },

    /**
     * Takes the given origin (JSON/Object) and namespace and returns
     * the namespaced/reduced object.
     *
     * @param {Object}          origin              The JSON origin.
     * @param {String}          namespace           The model-description namespace.
     * @returns {Object}
     * @private
     */
    _extractNamespace: function (origin, namespace) {
        var namespacedOrigin = null;

        if (typeof namespace === 'string' && namespace.indexOf('.') > -1) {
            var splittedNamespace = namespace.split('.'),
                nestedOrigin = Object.create(origin);

            splittedNamespace.forEach(function getNamespaceExtractedOrigin(namespaceKey) {
                nestedOrigin = nestedOrigin[namespaceKey];
            });

            namespacedOrigin = nestedOrigin;
        } else {
            namespacedOrigin = origin[namespace];
        }

        return namespacedOrigin;
    }
};

module.exports = ModelFactory;
{'fraction_non_alphanumeric': 0.09115323854660348, 'fraction_numerical': 0.0009478672985781991, 'mean_word_length': 1.7889867841409692, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4085134', 'n_tokens_mistral': 1473, 'n_tokens_neox': 1409, 'n_words': 370}