生成代碼的代碼 之 POJO生成器


我們在寫Java代碼時候,有時候需要寫一些POJO類,也就是只有一些屬性和get, set方法的類。例如,在寫REST 服務時候,利用Jersery + Jackson,可以把輸入的JSON字符串自動轉換成一個POJO類,也可以自動把POJO類轉換成JSON字符串而輸出。在這樣的情況下,我們往往需要寫很多的POJO類,里面包含多個屬性和對應的get, set方法,寫起來比較麻煩。那么,我們有辦法能很快的寫出這些POJO類嗎。
實際上,這些POJO類的實質就是一個類名和幾個屬性的類型和名稱。既然如此,我們可以只提供這幾個信息,而通過一個程序來把這些POJO類生成出來。所以,我們要做的是一個生成代碼的代碼,用來生成POJO對象。
要做這件事情,可以用各種編程語言來實現。筆者個人偏好JavaScript,而且JavaScript里面的object model比較適合做這件事,因此這里筆者通過Node.js來實現。代碼如下,回頭會把代碼開源到GitHub.
用法為, 把POJO的定義寫到schema.js文件中,然后運行node createpojo.js

// createpojo.js
var fs = require('fs');
var schema = require("./schema")

var defaultindent = 2;

var getIndent = function(i) {
  return getIndentCore(i, 0);
};
var getIndentCore = function(len, i) {
  if (i >= len) {
    return "";
  }
  return getIndentCore(len, i+1) + " ";
};

var createField = function(field, indentsize) {
  var i = indentsize == undefined ? 2 : indentsize;
  return getIndent(i) + "private " + field.type + " " + field.name + ";";
};

var createFields = function(fields, indentsize) {
  var fieldsstring = fields.map(function(f) {
    return createField(f, indentsize);
  });
  return fieldsstring.join("\n");
};

var createEmptyConstructor = function(clz, indentsize) {
  return getIndent(indentsize) + "public " + clz + "() {\n\n" + getIndent(indentsize) + "}";
};
var createVariable = function(f) {
  return f.type + " " + f.name;
};
var createArglist = function(fields) {
  var args = fields.map(createVariable);
  return args.join(", ");
};
var createAssign = function(field, indentsize) {
  return getIndent(indentsize) + "this." + field.name + " = " + field.name + ";";
};
var createAssigns = function(fields, indentsize) {
  var assigns = fields.map(function(f) {
    return createAssign(f, indentsize);
  });
  return assigns.join("\n");
};
var createConstructor = function(clz, fields, indentsize) {
  return getIndent(indentsize) + "public " + clz + "(" + createArglist(fields) + ") {\n" + createAssigns(fields, indentsize + defaultindent) + "\n" + getIndent(indentsize) + "}";
};
var createConstructors = function(clz, fields, indentsize) {
  return createEmptyConstructor(clz, indentsize) + "\n\n" + createConstructor(clz, fields, indentsize);
};
var getFuncName = function(name) {
  return name.substring(0,1).toUpperCase() + name.substring(1);
};
var createSetter = function(field, indentsize) {
  var line1 = getIndent(indentsize) + "public void set" + getFuncName(field.name) + "(" + createVariable(field) + ") {";
  var line2 = createAssign(field, indentsize + defaultindent);
  var line3 = getIndent(indentsize) + "}";
  var lines = [line1, line2, line3];
  return lines.join("\n");
};
var createGetter = function(field, indentsize) {
  var line1 = getIndent(indentsize) + "public " + field.type + " get" + getFuncName(field.name) + "() {";
  var line2 = getIndent(indentsize + defaultindent) + "return this." + field.name + ";";
  var line3 = getIndent(indentsize) + "}";
  var lines = [line1, line2, line3];
  return lines.join("\n");
};
var createAccessor = function(field, indentsize) {
  var access = [createSetter(field, indentsize), createGetter(field, indentsize)];
  return access.join("\n");
};
var createAccessors = function(fields, indentsize) {
  var accesses = fields.map(function(f) {return createAccessor(f, indentsize);});
  return accesses.join("\n\n");
};
var createClass = function(pkg, clz, fields) {
  var line1 = "package " + pkg + ";";
  var line2 = "public class " + clz + " {";
  var line3 = createFields(fields, defaultindent);
  var line4 = createConstructors(clz, fields, defaultindent);
  var line5 = createAccessors(fields, defaultindent);
  var line6 = "}";
  var lines = [line1, line2, line3, line4, line5, line6];
  return lines.join("\n\n");
};

var classcontents = schema.map(function(s) {
  return createClass(s["package"], s["name"], s["fields"]);
});

 
for (var i = 0; i < schema.length; i++) {
  fs.writeFile(schema[i].name + ".java", classcontents[i], function(e){
    if (e) {
      console.log("error: " + e);
    }
  });
}


// schema.js
var schemas = [
  {
    "name": "TestClass",
    "package": "example.com",
    "fields": [
      {"name": "name", "type": "String"},
      {"name": "value", "type": "String"}
    ]
  }
]

module.exports = schemas;

代碼只是用來做工具用,所以沒有寫的很完善。如果讀者覺得代碼有改進之處,歡迎在代碼開源之后提交更新。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM