生成代码的代码 之 POJO生成器 之二 模板实现
在之前的一篇博客中,我们写了利用node.js来生成JAVA的POJO代码的方法。有评论说可以利用模板来做这件事。当时认为模板只能做简单的字符串替换,所以可能无法完成任务。但是,仔细的学习了一个模板 -- handlebars -- 之后,发现确实可以对内容做一些简单的修改。所以就用handlebars来重新实现 生成代码的代码 之 POJO生成器。
对需要生成的内容做点分析后发现,如果利用模板来实现,要生成的POJO类里面有两个地方需要对内容做修改,而不是简单的字符串替换。一个是在产生构造函数时,需要构造一个包含所有类成员变量的输入参数列表,第二是对于get/set函数,需要把变量的首字母大写。而handlebars提供了block helper,可以对内容做修改。所以,整体思路就是,定义两个block helper来对这两处做简单的内容修改,其他地方直接用模板。
最终的代码如下。可以看到,比上次的代码清晰多了。所以模板确实是个很好用的东西。
首先是模板
// ClassTemplate.java
package {{package}};
public class {{name}} {
{{#fields}}
private {{type}} {{name}};
{{/fields}}
public {{name}}() {
}
public {{name}}({{#compose fields}}{{type}} {{name}}{{/compose}}) {
{{#fields}}
this.{{name}} = {{name}};
{{/fields}}
}
{{#fields}}
public void set{{#uppercase}}{{name}}{{/uppercase}}({{type}} {{name}}) {
this.{{name}} = {{name}};
}
public {{type}} get{{#uppercase}}{{name}}{{/uppercase}}() {
return this.{{name}};
}
{{/fields}}
}
接下来是利用模板生成POJO类的node.js代码
// createpojo.js
var handlebars = require('handlebars');
var fs = require('fs');
var schema = require("./schema")
var templatefile = "ClassTemplate.java";
handlebars.registerHelper('uppercase', function(options) {
var name = options.fn(this);
var result = name.substring(0,1).toUpperCase() + name.substring(1);
return new handlebars.SafeString(result);
});
handlebars.registerHelper('compose', function(items, options) {
var assigns = items.map(function(i) {return options.fn(i);});
var result = assigns.join(", ");
return new handlebars.SafeString(result);
});
var source = fs.readFileSync(templatefile, "utf8");
var template = handlebars.compile(source);
schema.forEach(function(s) {
var result = template(s);
fs.writeFile(s.name + ".java", result, function(e){
if (e) {
console.log("error: " + s.name + " : " + e);
}
});
});
最后是个简单的数据文件
// schema.js
var schemas = [
{
"name": "TestClass",
"package": "com.example",
"fields": [
{"name": "name", "type": "String"},
{"name": "age", "type": "int"}
]
}
]
module.exports = schemas;
运行如下命令
node createpojo.js
之后,就可以得到TestClass的定义文件。如果在schema.js里面写多个类定义数据,这里就可以得到多个文件。每个类的定义对应一个文件。
// TestClass.java
package com.example;
public class TestClass {
private String name;
private int age;
public TestClass() {
}
public TestClass(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
采用模板的好处是,如果我们需要对最终生成的类定义做修改,只要不是很复杂的修改,直接改模板就可以,很方便。