API Docs for:
Show:

File: lib\CodeGenerator.js

var fs = require('fs');
var path = require('path');

var _ = require('underscore');
var _s = require('underscore.string');
var ejs = require('ejs');

var dbc = require('happy.dbc').DesignByContract;
var FileSystemUtil = require('happy.util').FileSystemUtil;


/**
 * 代码生成器,根据ejs模板生成代码或代码文件。
 *
 * @class CodeGenerator
 * @extends Object
 * @constructor
 * @param {String} ejsTemplateFile 模板文件
 * @param {String} [encoding='utf8'] 文件编码
 * @example
        var CodeGenerator = require('code_generator');

        var ejsOptions = {
            user: {
                name: 'happy framework'
            }
        };

        var generator = new CodeGenerator('./templates/hello.ejs');

        var content = generator.generateToString(ejsOptions);
        console.log(content);

        generator.generateToTargetFile(ejsOptions);

        CodeGenerator.executeTemplateDirectory('./templates', ejsOptions);
 */
var CodeGenerator = function (ejsTemplateFile, encoding) {
    var me = this;
    dbc.mustBeDefined('ejsTemplateFile', ejsTemplateFile);

    _.extend(me, {
        ejsTemplateFile: ejsTemplateFile,
        encoding: (encoding || 'utf8'),
        defautEjsOptions: {
            _: require('underscore'),
            util: require('util'),
            filename: path.resolve(path.dirname(require.main.filename), './templates/ejs_cahce.ejs'),
        }
    });
};

module.exports = CodeGenerator;

/**
* @private
* @readOnly
* @property ejsTemplateFile
* @type String
*/

/**
* @private
* @readOnly
* @property encoding
* @default 'utf8'
* @type String
*/

/**
* @private
* @readOnly
* @property defautEjsOptions
* @type Object
*/


_.extend(CodeGenerator, {

    /**
     * 递归执行指定目录下的所有模板文件。
     * 
     * @static
     * @method executeTemplateDirectory
     * @param {String} ejsTemplateDirectory 模板目录
     * @param {Object} ejsOptions 执行模板的上下文对象
     * @param {String} [encoding='utf8'] 文件编码
     * @return
     * @example
        CodeGenerator.executeTemplateDirectory('./templates', ejsOptions);
     */
    executeTemplateDirectory: function (ejsTemplateDirectory, ejsOptions, encoding) {
        var me = this;
        dbc.mustBeDefined('ejsTemplateDirectory', ejsTemplateDirectory);
        dbc.mustBeDefined('ejsOptions', ejsOptions);

        FileSystemUtil.eachFileSync(ejsTemplateDirectory, function (filename) {
            return _s.endsWith(filename, '.ejs');
        }, function (filepath) {
            var generator = new CodeGenerator(filepath, encoding);
            generator.generateToTargetFile(ejsOptions);
        });
    }
});


_.extend(CodeGenerator.prototype, {

    /**
     * 生成为字符串。
     *
     * @method generateToString
     * @param {Object} ejsOptions 执行模板的上下文对象
     * @return
     * @example
        var content = generator.generateToString(ejsOptions);
        console.log(content);
     */
    generateToString: function (ejsOptions) {
        var me = this;
        dbc.mustBeDefined('ejsOptions', ejsOptions);

        var templateContent = fs.readFileSync(me.ejsTemplateFile, me.encoding);

        _.defaults(ejsOptions, me.defautEjsOptions);
        _.extend(ejsOptions, { _out: {} });

        return ejs.render(templateContent, ejsOptions);
    },

    /**
     * 生成为目标文件。
     *
     * @method generateToTargetFile
     * @param {Object} ejsOptions 执行模板的上下文对象
     * @param {String} [targetFile] 如果该参数为空,模板中必须包含如下代码:<% _out.targetFile  = './outputs/hello.generator.html'; %>
     * @param {Boolean} [cover=true] 如果目标文件已经存在,true 为覆盖,false为不覆盖。
     * @return
     * @example
        generator.generateToTargetFile(ejsOptions);
     */
    generateToTargetFile: function (ejsOptions, targetFile, cover) {
        var me = this;
        dbc.mustBeDefined('ejsOptions', ejsOptions);

        var outputContent = me.generateToString(ejsOptions);

        targetFile = targetFile || ejsOptions._out.targetFile;

        if (cover !== false) {
            cover = true;
        }
        if (ejsOptions._out.cover === false) {
            cover = false;
        }

        if (cover === false) {
            if (fs.existsSync(targetFile)) {
                console.log(targetFile + ' is exists!');
                return;
            }
        }

        FileSystemUtil.writeFileSync(targetFile, outputContent, me.encoding);

        console.log(targetFile + ' generate success!');
    },

    /**
     * 使模板的每次执行,都能访问到 defautEjsOptions 中的属性。
     *
     * @method setDefautEjsOptions
     * @param {Object} defautEjsOptions
     * @return
     */
    setDefautEjsOptions: function (defautEjsOptions) {
        var me = this;
        dbc.mustBeDefined('defautEjsOptions', defautEjsOptions);

        _.extend(me.defautEjsOptions, defautEjsOptions);
    }
});