CodeGenerator.java 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. package com.yonyou.occ.codegenerator;
  2. import freemarker.template.Configuration;
  3. import freemarker.template.Template;
  4. import freemarker.template.TemplateException;
  5. import freemarker.template.TemplateExceptionHandler;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.apache.commons.lang3.time.DateFormatUtils;
  8. import org.jdom2.Document;
  9. import org.jdom2.Element;
  10. import org.jdom2.JDOMException;
  11. import org.jdom2.Namespace;
  12. import org.jdom2.filter.Filters;
  13. import org.jdom2.input.SAXBuilder;
  14. import org.jdom2.xpath.XPathExpression;
  15. import org.jdom2.xpath.XPathFactory;
  16. import org.slf4j.Logger;
  17. import org.slf4j.LoggerFactory;
  18. import java.io.File;
  19. import java.io.FileWriter;
  20. import java.io.IOException;
  21. import java.io.Writer;
  22. import java.util.*;
  23. /**
  24. * 代码生成器
  25. *
  26. * @author wangruiv
  27. * @date 2017-06-18 11:21:31
  28. */
  29. public class CodeGenerator {
  30. private static List<String> EXCLUDE_COLUMNS = null;
  31. private final Logger log = LoggerFactory.getLogger(CodeGenerator.class);
  32. private final String oldBasePackage;
  33. private final String newBasePackage;
  34. private final String pdmFile;
  35. private final String tableCode;
  36. private final String author;
  37. private final String referenceType;
  38. private final boolean ifUseCustDocDefRef;
  39. private final String targetProjectRootPath;
  40. private final String moduleName;
  41. private final String templateDir = getClass().getResource("/").getPath() + "generator/";
  42. public CodeGenerator(String oldBasePackage, String newBasePackage, String pdmFile, String tableCode,
  43. String referenceType, boolean ifUseCustDocDefRef, String author, String targetProjectRootPath) {
  44. this.oldBasePackage = oldBasePackage;
  45. this.newBasePackage = newBasePackage;
  46. this.pdmFile = pdmFile;
  47. this.tableCode = tableCode;
  48. this.referenceType = referenceType;
  49. this.ifUseCustDocDefRef = ifUseCustDocDefRef;
  50. this.author = author;
  51. this.targetProjectRootPath = targetProjectRootPath;
  52. moduleName = getModuleNameByTable(tableCode);
  53. final String[] array = {"ID", "DR", "TS", "CREATOR", "CREATION_TIME", "MODIFIER", "MODIFIED_TIME"};
  54. EXCLUDE_COLUMNS = Arrays.asList(array);
  55. }
  56. public void run() {
  57. try {
  58. Table table = getTableFromPdmXml(pdmFile, tableCode, referenceType);
  59. generateEntity(table);
  60. generateRepository(table);
  61. generateDto(table);
  62. generateMapper(table);
  63. generateService(table);
  64. generateController(table);
  65. if (StringUtils.isNotEmpty(referenceType)) {
  66. generateRefController(table);
  67. }
  68. if (ifUseCustDocDefRef) {
  69. generateMapperDecorator(table);
  70. }
  71. generateMetaDataSql(table);
  72. } catch (JDOMException e) {
  73. log.error("解析XML文件时发生错误", e);
  74. } catch (IOException e) {
  75. log.error("读取XML文件时发生错误", e);
  76. } catch (TemplateException e) {
  77. log.error("解析模板文件时发生错误", e);
  78. }
  79. }
  80. private String getModuleNameByTable(String tableCode) {
  81. return tableCode.split("_")[0].toLowerCase();
  82. }
  83. private Table getTableFromPdmXml(String pdmFile, String tableCode, String referenceType)
  84. throws JDOMException, IOException {
  85. // read the XML into a JDOM2 document.
  86. SAXBuilder jdomBuilder = new SAXBuilder();
  87. Document jdomDocument = jdomBuilder.build(pdmFile);
  88. // use the default implementation
  89. XPathFactory xFactory = XPathFactory.instance();
  90. // namespaces
  91. Namespace nsAttribute = jdomDocument.getRootElement().getNamespace("a");
  92. Namespace nsCollection = jdomDocument.getRootElement().getNamespace("c");
  93. //Namespace nsObject = jdomDocument.getRootElement().getNamespace("o");
  94. XPathExpression<Element> expr = xFactory.compile("//a:Code[text()='" + tableCode + "']", Filters.element(),
  95. null, nsAttribute);
  96. Element tableElement = expr.evaluateFirst(jdomDocument).getParentElement();
  97. String tableName = tableElement.getChild("Name", nsAttribute).getText();
  98. String tableComment;
  99. Element tableCommentElement = tableElement.getChild("Comment", nsAttribute);
  100. if (tableCommentElement == null || StringUtils.isBlank(tableComment = tableCommentElement.getText())) {
  101. tableComment = tableName;
  102. }
  103. Table table = new Table(tableName, tableCode, tableComment, referenceType);
  104. List<Element> columnElements = tableElement.getChild("Columns", nsCollection).getChildren();
  105. for (Element columnElement : columnElements) {
  106. String code = columnElement.getChild("Code", nsAttribute).getText();
  107. if (EXCLUDE_COLUMNS.contains(code.toUpperCase())) {
  108. continue;
  109. }
  110. String name = columnElement.getChild("Name", nsAttribute).getText();
  111. String comment;
  112. Element commentElement = columnElement.getChild("Comment", nsAttribute);
  113. if (commentElement == null || StringUtils.isBlank(comment = commentElement.getText())) {
  114. comment = name;
  115. }
  116. String dataType = columnElement.getChild("DataType", nsAttribute).getText();
  117. Integer length = null;
  118. Element lengthElement = columnElement.getChild("Length", nsAttribute);
  119. if (lengthElement != null) {
  120. length = Integer.parseInt(lengthElement.getText());
  121. }
  122. Integer precision = null;
  123. Element precisionElement = columnElement.getChild("Precision", nsAttribute);
  124. if (precisionElement != null) {
  125. precision = Integer.parseInt(precisionElement.getText());
  126. }
  127. Table.Column column = table.new Column(name, code, comment, dataType, length, precision);
  128. table.getColumns().add(column);
  129. }
  130. return table;
  131. }
  132. private void generate(Table table, String templateName, String targetSubPath)
  133. throws IOException, TemplateException {
  134. Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
  135. cfg.setDirectoryForTemplateLoading(new File(templateDir));
  136. cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
  137. Template template = cfg.getTemplate(templateName + ".ftl", "UTF-8");
  138. // 定义模板数据
  139. Map<String, Object> data = new HashMap<String, Object>();
  140. data.put("oldBasePackage", oldBasePackage);
  141. data.put("newBasePackage", newBasePackage);
  142. data.put("moduleName", moduleName);
  143. data.put("date", DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss"));
  144. data.put("ifUseCustDocDefRef", ifUseCustDocDefRef);
  145. data.put("author", author);
  146. data.put("table", table);
  147. // 输出文件
  148. String fileName = table.getClassName();
  149. // 文件后缀名
  150. String suffix = ".java";
  151. // 文件保存目录
  152. final String outFolderPath;
  153. if (templateName.equalsIgnoreCase("metaData")) {
  154. fileName = table.getName().toLowerCase() + "_元数据";
  155. suffix = ".sql";
  156. outFolderPath = targetProjectRootPath + targetSubPath;
  157. } else {
  158. if (!templateName.equalsIgnoreCase("entity")) {
  159. fileName += templateName.substring(0, 1).toUpperCase() + templateName.substring(1);
  160. }
  161. outFolderPath = targetProjectRootPath + "src/main/java/" + newBasePackage.replace(".", "/") + "/" +
  162. moduleName + targetSubPath;
  163. }
  164. File outFolder = new File(outFolderPath);
  165. if (!outFolder.exists() && !outFolder.mkdirs()) {
  166. System.err.println("文件目录创建失败!");
  167. return;
  168. }
  169. final String outFilePath = outFolderPath + fileName + suffix;
  170. Writer outFile = new FileWriter(outFilePath);
  171. template.process(data, outFile);
  172. System.out.println(templateName + "文件生成成功:" + outFilePath);
  173. }
  174. private void generateEntity(Table table) throws IOException, TemplateException {
  175. generate(table, "entity", "/entity/");
  176. }
  177. private void generateRepository(Table table) throws IOException, TemplateException {
  178. generate(table, "repository", "/repository/");
  179. }
  180. private void generateDto(Table table) throws IOException, TemplateException {
  181. generate(table, "dto", "/service/dto/");
  182. }
  183. private void generateMapper(Table table) throws IOException, TemplateException {
  184. generate(table, "mapper", "/service/mapper/");
  185. }
  186. private void generateService(Table table) throws IOException, TemplateException {
  187. generate(table, "service", "/service/");
  188. }
  189. private void generateController(Table table) throws IOException, TemplateException {
  190. generate(table, "controller", "/web/");
  191. }
  192. private void generateRefController(Table table) throws IOException, TemplateException {
  193. generate(table, "refController", "/web/");
  194. }
  195. private void generateMapperDecorator(Table table) throws IOException, TemplateException {
  196. generate(table, "mapperDecorator", "/service/mapper/");
  197. }
  198. private void generateMetaDataSql(Table table) throws IOException, TemplateException {
  199. generate(table, "metaData", "/sql/");
  200. }
  201. }