Guest User

Untitled

a guest
Dec 17th, 2017
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.53 KB | None | 0 0
  1. import org.apache.commons.lang.StringUtils;
  2. import play.db.jpa.Model;
  3.  
  4. import javax.persistence.Transient;
  5. import java.io.*;
  6. import java.lang.reflect.Field;
  7. import java.lang.reflect.Modifier;
  8. import java.math.BigDecimal;
  9. import java.sql.Timestamp;
  10. import java.text.SimpleDateFormat;
  11. import java.util.ArrayList;
  12. import java.util.Date;
  13. import java.util.LinkedList;
  14. import java.util.List;
  15.  
  16. /**
  17. * 代码生成器
  18. */
  19. public class CodeGenerator {
  20. private static final String PROJECT_PATH = System.getProperty("user.dir");//项目在硬盘上的基础路径
  21. private static final String MODEL_ILE_PATH = PROJECT_PATH + "/app/models/";//model路径
  22.  
  23. private static final String AUTHOR = "lyl";//@author
  24. private static final String DATE = new SimpleDateFormat("yyyy/MM/dd").format(new Date());//@date
  25.  
  26. /**
  27. * Gen code.
  28. *
  29. * @param classes the classes
  30. */
  31. public void genCode(Class... classes) {
  32. try {
  33. for (Class clazz : classes) {
  34. Field[] rawFields = getCurrentFields(clazz);
  35.  
  36. Object o = clazz.newInstance();
  37. String primaryKeyField;
  38. boolean isExtendModel = false;
  39. if (isExtendModel = (o instanceof Model)) {
  40. primaryKeyField = "id";
  41. } else {
  42. primaryKeyField = findPrimaryKeyField(rawFields, clazz).getName();
  43. }
  44. String importPackage = genImport();
  45. String annotation = genAnnotation(clazz);
  46. String staticField = genStaticField(clazz, rawFields, primaryKeyField, isExtendModel);
  47. String method = genMethod(clazz, rawFields, isExtendModel);
  48. insertFile(clazz, importPackage, annotation, staticField, method);
  49. }
  50. } catch (Exception e) {
  51. e.printStackTrace();
  52. }
  53. }
  54.  
  55. private String genImport() {
  56. return ("import org.slf4j.Logger;\n" +
  57. "import org.slf4j.LoggerFactory;\n" +
  58. "import play.db.jpa.GenericModel;\n" +
  59. "import transaction.DBDispatcher;\n" +
  60. "import transaction.JDBCBuilder;\n" +
  61. "\n" +
  62. "import javax.persistence.Entity;\n" +
  63. "import javax.persistence.Id;\n" +
  64. "import java.sql.ResultSet;\n" +
  65. "import java.sql.SQLException;\n" +
  66. "import java.util.ArrayList;\n" +
  67. "import java.util.List;\n");
  68. }
  69.  
  70. /**
  71. * 生成Annotation
  72. */
  73. private String genAnnotation(Class clazz) {
  74. String name = clazz.getSimpleName();
  75. return "@Entity(name = " + name + ".TABLE_NAME)\n";
  76. }
  77.  
  78. /**
  79. * 生成静态字段
  80. */
  81. private String genStaticField(Class clazz, Field[] fileds, String primaryKyField, boolean isExtendModel) {
  82. String className = clazz.getSimpleName();
  83. Field[] fields = clazz.getFields();
  84. StringBuilder builder = new StringBuilder();
  85. builder.append(" private static final Logger LOGGER = LoggerFactory.getLogger(")
  86. .append(className).append(".class);\n");
  87.  
  88. builder.append(" public static final String TAG = \"").append(className).append("\";\n");
  89. builder.append(" public static final String TABLE_NAME = \"")
  90. .append(splitClassName(className))
  91. .append("\";\n");
  92. builder.append(" private static final String ALL_PROPERTY = \"")
  93. .append(genFieldString(fileds, isExtendModel)).append("\";\n");
  94. builder.append(" private static final String QUERY_PREFIX = \"select \" + ALL_PROPERTY + \" from \" + TABLE_NAME + \" where \";\n");
  95. builder.append(" private static final String PARAM_HOLDERS = ALL_PROPERTY.replaceAll(\"\\\\w+\", \"?\");\n");
  96. builder.append(" private static final String UPDATE_PARAM_HOLDERS = ALL_PROPERTY.replaceFirst(\"")
  97. .append(primaryKyField)
  98. .append("\\\\s*,\", \"\").replaceAll(\",\", \" = ?,\") + \"= ? \";\n");
  99. builder.append(" public static final DBDispatcher DP = new DBDispatcher();\n");
  100. builder.append("\n");
  101. return builder.toString();
  102. }
  103.  
  104. private boolean isExistField(Class clazz, String fieldName) {
  105. Field[] fields = clazz.getFields();
  106. for (Field field : fields) {
  107. if (field.getName().equalsIgnoreCase(fieldName)) {
  108. return true;
  109. }
  110. }
  111. return false;
  112. }
  113.  
  114. private String genMethod(Class clazz, Field[] rawFields, boolean isExtendModel) {
  115. StringBuilder builder = new StringBuilder();
  116. String queryMethod = genQueryMethod(clazz, rawFields, isExtendModel);
  117. String jdbcMethod = genJDbcMethod(clazz, rawFields, isExtendModel);
  118. return builder.append("\n").append(queryMethod).append(jdbcMethod).toString();
  119. }
  120.  
  121. private String genQueryMethod(Class clazz, Field[] rawFields, boolean isExtendModel) {
  122. String className = clazz.getSimpleName();
  123. Field field = findPrimaryKeyField(rawFields, clazz);
  124. StringBuilder builder = new StringBuilder();
  125.  
  126. /*
  127. * 用主键获取单个entity
  128. * */
  129. builder.append(" public static ").append(className).append(" find").append(className).append("By");
  130. if (isExtendModel) {
  131. builder.append("Id(int id) {\n");
  132. } else {
  133. builder.append(changeFieldFirstCharToUpperCase(field.getName()))
  134. .append("(")
  135. .append(getFieldClassString(field.getType()))
  136. .append(" ")
  137. .append(field.getName())
  138. .append(") {\n");
  139. }
  140. builder.append(" String query = QUERY_PREFIX + \"").append(field.getName()).append("=?\";\n");
  141. builder.append(" return findOne(query, ").append(field.getName()).append(");\n");
  142. builder.append(" }\n");
  143. builder.append("\n");
  144.  
  145. /*
  146. * 自定义查询entity
  147. * */
  148. builder.append(" public static List<").append(className).append("> find").append(className).append("List(String query, Object... params) {\n");
  149. builder.append(" query = QUERY_PREFIX + query;\n");
  150. builder.append(" return findList(query, params);\n");
  151. builder.append(" }\n");
  152. builder.append("\n");
  153. return builder.toString();
  154.  
  155. }
  156.  
  157. private String genJDbcMethod(Class clazz, Field[] rawFields, boolean isExtendModel) {
  158. String className = clazz.getSimpleName();
  159. String varName = changeClassNameToVariable(className);
  160. String listName = changeClassNameToVariableList(className);
  161. Field field = findPrimaryKeyField(rawFields, clazz);
  162. StringBuilder builder = new StringBuilder();
  163.  
  164. /*
  165. * 插入
  166. * */
  167. builder.append(" public boolean rawInsert() {\n");
  168. builder.append(" String sql = \"insert into \" + TABLE_NAME + \"(\" + ALL_PROPERTY + \")\" +\n");
  169. builder.append(" \" values(\" + PARAM_HOLDERS + \")\";\n");
  170. builder.append(" long returnId = DP.insert(sql, ").append(genFieldString(rawFields, isExtendModel)).append(");\n");
  171. builder.append(" return returnId > 0L;\n");
  172. builder.append(" }\n");
  173. builder.append("\n");
  174.  
  175. /*
  176. * 更新
  177. * */
  178. builder.append(" public boolean update() {\n");
  179. builder.append(" String sql = \"update \" + TABLE_NAME + \" set \" + UPDATE_PARAM_HOLDERS + \" where ");
  180. if (isExtendModel) {
  181. builder.append("id");
  182. } else {
  183. builder.append(field.getName());
  184. }
  185. builder.append("=?\";\n");
  186. builder.append(" long returnId = DP.update(sql, ");
  187. String allField = genFieldString(rawFields, isExtendModel);
  188. if (isExtendModel) {
  189. allField = allField.replaceAll("null,", "");
  190. allField = allField + ",id";
  191. } else {
  192. allField = allField.replaceFirst("\\w*,", "");
  193. allField = allField + "," + field.getName();
  194. }
  195. builder.append(allField);
  196. builder.append(");\n");
  197. builder.append(" return returnId > 0L;\n");
  198. builder.append(" }\n");
  199. builder.append("\n");
  200.  
  201. /*
  202. * 查找单个entity jdbc实现
  203. * */
  204. builder.append(" private static ").append(className).append(" findOne").append("(String query, Object... param) {\n");
  205. builder.append(" return new JDBCBuilder.JDBCExecutor<").append(className).append(">(DP, query, param) {\n");
  206. builder.append(" @Override\n");
  207. builder.append(" public ").append(className).append(" doWithResultSet(ResultSet rs) throws SQLException {\n");
  208. builder.append(" while (rs.next()) {\n");
  209. builder.append(" ").append(className).append(" ").append(varName).append(" = parse").append(className).append("(rs);\n");
  210. builder.append(" if (").append(varName).append(" != null) {\n");
  211. builder.append(" return ").append(varName).append(";\n");
  212. builder.append(" }\n");
  213. builder.append(" }\n");
  214. builder.append(" return null;\n");
  215. builder.append(" }\n");
  216. builder.append(" }.call();\n");
  217. builder.append(" }\n");
  218. builder.append("\n");
  219.  
  220. /*
  221. * 查找entity列表 jdbc实现
  222. * */
  223. builder.append(" private static List<").append(className).append("> findList(String query, Object... params) {\n");
  224. builder.append(" return new JDBCBuilder.JDBCExecutor<List<").append(className).append(">>(DP, query, params) {\n");
  225. builder.append(" @Override\n");
  226. builder.append(" public List<").append(className).append("> doWithResultSet(ResultSet rs) throws SQLException {\n");
  227. builder.append(" List<").append(className).append("> ").append(listName).append(" = new ArrayList<").append(className).append(">();\n");
  228. builder.append(" while (rs.next()) {\n");
  229. builder.append(" ").append(className).append(" ").append(varName).append(" = parse").append(className).append("(rs);\n");
  230. builder.append(" if (").append(varName).append(" != null) {\n");
  231. builder.append(" ").append(listName).append(".add(").append(varName).append(");\n");
  232. builder.append(" }\n");
  233. builder.append(" }\n");
  234. builder.append(" return ").append(listName).append(";\n");
  235. builder.append(" }\n");
  236. builder.append(" }.call();\n");
  237. builder.append(" }\n");
  238. builder.append("\n");
  239.  
  240. /*
  241. * jdbc转entity
  242. * */
  243. builder.append(" private static ").append(className).append(" parse").append(className).append("(ResultSet rs) {\n");
  244. builder.append(" ").append(className).append(" ").append(varName).append(" = new ").append(className).append("();\n");
  245. builder.append(" try {\n");
  246. for (Field f : rawFields) {
  247. builder.append(" ")
  248. .append(varName).append(".")
  249. .append(f.getName())
  250. .append(" = rs.get")
  251. .append(getFieldClassStringInResultSet(f.getType()))
  252. .append("(\"").append(f.getName()).append("\");\n");
  253. }
  254. builder.append(" return ").append(varName).append(";\n");
  255. builder.append(" } catch (SQLException e) {\n");
  256. builder.append(" e.printStackTrace();\n");
  257. builder.append(" }\n");
  258. builder.append(" return null;\n");
  259. builder.append(" }\n");
  260. builder.append("\n");
  261. return builder.toString();
  262. }
  263.  
  264. /**
  265. * 区分是否为数据库需要的字段
  266. */
  267. private Field[] getCurrentFields(Class clazz) {
  268. Field[] fields = clazz.getFields();
  269. List<Field> fieldList = new LinkedList<Field>();
  270. for (Field field : fields) {
  271. if (field.isAnnotationPresent(Transient.class)) {
  272. continue;
  273. }
  274. if (Modifier.isTransient(field.getModifiers())) {
  275. continue;
  276. }
  277. if (Modifier.isStatic(field.getModifiers())) {
  278. continue;
  279. }
  280. fieldList.add(field);
  281. }
  282. return fieldList.toArray(new Field[0]);
  283. }
  284.  
  285. /**
  286. * 找到Id项
  287. */
  288. private Field findPrimaryKeyField(Field[] rawFields, Class clazz) {
  289. for (Field field : rawFields) {
  290. if (field.isAnnotationPresent(javax.persistence.Id.class)) {
  291. return field;
  292. }
  293. }
  294. throw new RuntimeException("未找到primary key,请继承Model或添加@id");
  295. }
  296.  
  297. /**
  298. * 将内容插入文件
  299. */
  300. private void insertFile(Class clazz, String importPackage, String annotation, String staticField, String method) throws UnsupportedEncodingException {
  301. File file = new File(MODEL_ILE_PATH, clazz.getSimpleName() + ".java");
  302. String content = getFileContent(file);
  303.  
  304. content = clearOld(content, clazz);
  305. content = insertImport(importPackage, content);
  306. content = insertAnnotation(annotation, content);
  307. content = insertStaticField(staticField, content);
  308. content = insertMethod(method, content);
  309.  
  310. try {
  311. BufferedWriter out = new BufferedWriter(new FileWriter(file));
  312. out.write(content);
  313. out.close();
  314. } catch (IOException e) {
  315. }
  316. }
  317.  
  318. private String clearOld(String content, Class clazz) {
  319. String[] strings = content.split("\n");
  320. if (strings.length == 1) {
  321. strings = content.split("\r\n");
  322. }
  323. List<String> lineList = new ArrayList<String>();
  324. Field key = findPrimaryKeyField(clazz.getFields(), clazz);
  325. String keyName;
  326. if (key == null) {
  327. keyName = "id";
  328. } else {
  329. keyName = key.getName();
  330. }
  331. int flag = 0;
  332. int leftParenthesis = 0;
  333. int rightParenthesis = 0;
  334. for (int i = 0; i < strings.length; i++) {
  335. String line = strings[i];
  336. if (flag == 1) {
  337. if (leftParenthesis == rightParenthesis) {
  338. flag = 0;
  339. leftParenthesis = 0;
  340. rightParenthesis = 0;
  341. continue;
  342. }
  343. line = line.trim().replaceAll("[\\n\\r]", "");
  344. int len = line.length();
  345. int leftIndex = line.lastIndexOf("{");
  346. int rightIndex = line.indexOf("}");
  347. if (leftIndex == -1 && rightIndex == -1) {
  348. continue;
  349. }
  350. if (leftIndex == len - 1) {
  351. leftParenthesis += 1;
  352. }
  353. if (rightIndex == 0) {
  354. rightParenthesis += 1;
  355. }
  356. continue;
  357. }
  358. if (needClearAnnotation(line)) {
  359. continue;
  360. } else if (needClearStaticField(line)) {
  361. continue;
  362. } else if (needClearMethod(line, clazz, keyName)) {
  363. flag = 1;
  364. leftParenthesis = 1;
  365. continue;
  366. }
  367. lineList.add(line);
  368. }
  369. String[] lines = lineList.toArray(new String[0]);
  370. return StringUtils.join(lines, "\n");
  371. }
  372.  
  373. private boolean needClearAnnotation(String line) {
  374. return line.contains("@Entity(name");
  375. }
  376.  
  377. private boolean needClearStaticField(String line) {
  378. return line.contains("LoggerFactory.getLogger")
  379. || line.contains("public static final String TAG")
  380. || line.contains("public static final String TABLE_NAME")
  381. || line.contains("private static final String ALL_PROPERTY")
  382. || line.contains("private static final String QUERY_PREFIX")
  383. || line.contains("private static final String PARAM_HOLDERS")
  384. || line.contains("private static final String UPDATE_PARAM_HOLDERS")
  385. || line.contains("public static final DBDispatcher DP");
  386. }
  387.  
  388. private boolean needClearMethod(String line, Class clazz, String keyName) {
  389. String className = clazz.getSimpleName();
  390.  
  391. return line.contains("public static " + className + " find" + className + "By" + changeFieldFirstCharToUpperCase(keyName))
  392. || line.contains("public static List<" + className + "> find" + className + "List")
  393. || line.contains("public boolean rawInsert()")
  394. || line.contains("public boolean update()")
  395. || line.contains("private static " + className + " findOne")
  396. || line.contains("private static List<" + className + "> findList")
  397. || line.contains("private static " + className + " parse" + className);
  398. }
  399.  
  400. /**
  401. * 插入import
  402. */
  403. private String insertImport(String importPackage, String content) {
  404. int importIndex = findImportInsertIndex(content);
  405. return content.substring(0, importIndex) + importPackage + content.substring(importIndex);
  406. }
  407.  
  408. /**
  409. * 插入Annotation
  410. */
  411. private String insertAnnotation(String annotation, String content) {
  412. int annotationIndex = findAnnotationInsertIndex(content);
  413. return content.substring(0, annotationIndex) + annotation + content.substring(annotationIndex);
  414. }
  415.  
  416. /**
  417. * 插入方法
  418. */
  419. private String insertMethod(String method, String content) {
  420. int methodIndex = findMethodInsertIndex(content);
  421. return content.substring(0, methodIndex) + method + content.substring(methodIndex);
  422. }
  423.  
  424. /**
  425. * 插入静态字段
  426. */
  427. private String insertStaticField(String staticField, String content) {
  428. int headIndex = findStaticFieldInsertIndex(content);
  429. return content.substring(0, headIndex + 3) + staticField + content.substring(headIndex + 3);
  430. }
  431.  
  432. /**
  433. * 寻找插入import的索引位置
  434. */
  435. private int findImportInsertIndex(String content) {
  436. return content.indexOf("import ");
  437. }
  438.  
  439. /**
  440. * 寻找插入annotation的索引位置
  441. */
  442. private int findAnnotationInsertIndex(String content) {
  443. return content.indexOf("public class");
  444. }
  445.  
  446. /**
  447. * 寻找插入静态字段的索引位置
  448. */
  449. private int findStaticFieldInsertIndex(String content) {
  450. int index = content.indexOf("{\r\n");
  451. if (index == -1) {
  452. index = content.indexOf("{\n");
  453. }
  454. return index;
  455. }
  456.  
  457. /**
  458. * 寻找插入方法的索引位置
  459. */
  460. private int findMethodInsertIndex(String content) {
  461. return content.lastIndexOf("}");
  462. }
  463.  
  464.  
  465. /**
  466. * 获取文件内容
  467. */
  468. private String getFileContent(File file) throws UnsupportedEncodingException {
  469. String encoding = "utf-8";
  470. Long filelength = file.length();
  471. byte[] filecontent = new byte[filelength.intValue()];
  472. try {
  473. FileInputStream in = new FileInputStream(file);
  474. in.read(filecontent);
  475. in.close();
  476. } catch (FileNotFoundException e) {
  477. e.printStackTrace();
  478. } catch (IOException e) {
  479. e.printStackTrace();
  480. }
  481. return new String(filecontent, encoding);
  482. }
  483.  
  484. /**
  485. * 生成字段string
  486. */
  487. private String genFieldString(Field[] fields, boolean isExtendModel) {
  488. int len = fields.length;
  489. String[] strings = new String[len];
  490. if (isExtendModel) {
  491. strings[0] = "null";
  492. for (int i = 0, fieldIndex = i; fieldIndex < len; fieldIndex++) {
  493. String name = fields[fieldIndex].getName();
  494. if (name.equals("id")) {
  495. continue;
  496. }
  497. strings[i + 1] = name;
  498. i++;
  499. }
  500. } else {
  501. for (int i = 0; i < len; i++) {
  502. strings[i] = fields[i].getName();
  503. }
  504. }
  505. return StringUtils.join(strings, ",");
  506. }
  507.  
  508. /**
  509. * 按大小写分隔类名
  510. *
  511. * @param className 类名
  512. * @return
  513. */
  514. private String splitClassName(String className) {
  515. int index = 0;
  516. ArrayList arrayList = new ArrayList<String>();
  517. for (int i = 1; i < className.length(); i++) {
  518. if (Character.isUpperCase(className.charAt(i))) {
  519. arrayList.add(className.substring(index, i).toLowerCase());
  520. index = i;
  521. }
  522. }
  523. arrayList.add(className.substring(index, className.length()).toLowerCase());
  524. String[] strings = (String[]) arrayList.toArray(new String[0]);
  525. return StringUtils.join(strings, "_");
  526. }
  527.  
  528. /**
  529. * 获取字段类型的string
  530. *
  531. * @param fieldClass the field class
  532. * @return the field class string
  533. */
  534. public static String getFieldClassString(Class<?> fieldClass) {
  535. String type = null;
  536.  
  537. if (fieldClass == Long.class || fieldClass == long.class) {
  538. type = "Long";
  539. } else if (fieldClass == Integer.class || fieldClass == int.class) {
  540. type = "Integer";
  541. } else if (fieldClass == Double.class || fieldClass == double.class) {
  542. type = "Double";
  543. } else if (fieldClass == String.class) {
  544. type = "String";
  545. } else if (fieldClass == Boolean.class || fieldClass == boolean.class) {
  546. type = "Boolean";
  547. } else if (fieldClass == BigDecimal.class) {
  548. type = "BigDecimal";
  549. } else if (fieldClass == Date.class) {
  550. type = "Date";
  551. }else if (fieldClass == Timestamp.class) {
  552. type = "Timestamp";
  553. }
  554. return type;
  555. }
  556.  
  557. public static String getFieldClassStringInResultSet(Class<?> fieldClass) {
  558. if (fieldClass == Integer.class || fieldClass == int.class) {
  559. return "Int";
  560. } else {
  561. return getFieldClassString(fieldClass);
  562. }
  563. }
  564.  
  565.  
  566. private String changeClassNameToVariable(String className) {
  567. String s = className.substring(0, 1).toLowerCase();
  568. return s + className.substring(1);
  569. }
  570.  
  571. private String changeClassNameToVariableList(String className) {
  572. return changeClassNameToVariable(className) + "List";
  573. }
  574.  
  575. private String changeFieldFirstCharToUpperCase(String name) {
  576. return name.substring(0, 1).toUpperCase() + name.substring(1);
  577. }
  578. }
Add Comment
Please, Sign In to add comment