您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

Generator.java 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. package com.rthoni.intellij.codefromds.business;
  2. import com.intellij.database.psi.DbDataSource;
  3. import com.intellij.openapi.project.Project;
  4. import com.rthoni.intellij.codefromds.dbo.options.*;
  5. import com.rthoni.intellij.codefromds.dbo.template.*;
  6. import groovy.json.StringEscapeUtils;
  7. import org.json.JSONArray;
  8. import org.json.JSONObject;
  9. import org.jtwig.JtwigModel;
  10. import org.jtwig.JtwigTemplate;
  11. import org.jtwig.environment.EnvironmentConfiguration;
  12. import org.jtwig.environment.EnvironmentConfigurationBuilder;
  13. import org.jtwig.functions.FunctionRequest;
  14. import org.jtwig.functions.SimpleJtwigFunction;
  15. import java.io.File;
  16. import java.io.FileOutputStream;
  17. import java.io.IOException;
  18. import java.util.HashMap;
  19. import java.util.List;
  20. import java.util.Vector;
  21. import java.util.function.Consumer;
  22. /**
  23. * Created by robin on 11/15/16.
  24. */
  25. public abstract class Generator {
  26. public static void saveOptions(GenerateOptions options) throws Exception
  27. {
  28. HashMap<String, Object> map = options.toMap();
  29. JSONObject obj = new JSONObject(map);
  30. FileOutputStream file = new FileOutputStream(options.getConfigAbsolutePath());
  31. file.write(obj.toString(4).getBytes());
  32. file.close();
  33. }
  34. public static GenerateOptions loadOptions(String configPath) throws Exception
  35. {
  36. String data = Helper.readFile(configPath);
  37. JSONObject obj = new JSONObject(data);
  38. String src = obj.getJSONObject("selection").getString("source");
  39. DbDataSource dataSource = Helper.findDataSource(src);
  40. if (dataSource == null) {
  41. throw new Exception("Data source " + src + " not found");
  42. }
  43. GenerateOptions options = new GenerateOptions(dataSource);
  44. options.setConfigAbsolutePath(configPath);
  45. options.fromJson(obj);
  46. return options;
  47. }
  48. public static String escapeReservedWords(String id, TypesCastOptions options)
  49. {
  50. if (options.getReservedWords().contains(id)) {
  51. return "_" + id;
  52. }
  53. return id;
  54. }
  55. public static String escapeString(String str)
  56. {
  57. return StringEscapeUtils.escapeJava(str);
  58. }
  59. public static void convertSqlType(SqlTypeDbo type, TypesCastOptions options, DataSourceDbo dataSourceDbo)
  60. {
  61. if (type == null) {
  62. return;
  63. }
  64. boolean isArray = type.getType().endsWith("[]");
  65. boolean isSetOf = type.getType().startsWith("setof ");
  66. String sqlTypeName = isArray ? type.getType().substring(0, type.getType().length() - 2) : type.getType();
  67. if (isSetOf)
  68. {
  69. sqlTypeName = sqlTypeName.substring(6);
  70. }
  71. String typeName = null;
  72. HashMap<String, HashMap<String, String>> types = options.getTypes();
  73. if (types.containsKey(sqlTypeName)) {
  74. HashMap<String, String> subtype = types.get(sqlTypeName);
  75. if (subtype.containsKey(type.getVagueArg())) {
  76. typeName = subtype.get(type.getVagueArg());
  77. }
  78. else if (subtype.containsKey("*")) {
  79. typeName = subtype.get("*");
  80. }
  81. }
  82. if (typeName == null) {
  83. TableDataSourceDbo table = dataSourceDbo.findTable(sqlTypeName);
  84. if (table == null) {
  85. typeName = types.get("*").get("*");
  86. }
  87. else {
  88. typeName = table.getName();
  89. }
  90. }
  91. if (isArray) {
  92. typeName = options.getArrayTemplate().replace("%t", typeName);
  93. }
  94. if (isSetOf) {
  95. typeName = options.getSetOfTemplate().replace("%t", typeName);
  96. }
  97. type.setLanguageType(typeName);
  98. type.setLanguageTypeNotNull(options.getNonNullableTypes().contains(typeName));
  99. }
  100. // public static boolean isUnionSame(List<ColumnDataSourceDbo> part1, List<ColumnDataSourceDbo> part2, List<ColumnDataSourceDbo> list2)
  101. // {
  102. // List<ColumnDataSourceDbo> list1 = new Vector<>(part1);
  103. // for (ColumnDataSourceDbo col : part2) {
  104. // if (!list1.contains(col)) {
  105. // list1.add(col);
  106. // }
  107. // }
  108. // if (list1.size() != list2.size()) {
  109. // return false;
  110. // }
  111. // list1.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
  112. // list2.sort((o1, o2) -> o1.getName().compareTo(o2.getName()));
  113. // return list1.equals(list2);
  114. // }
  115. public static DataSourceDbo convertOptions(GenerateOptions options, TypesCastOptions types)
  116. {
  117. String dataSourceName = options.getSelection().getSource().getName();
  118. DataSourceDbo dataSourceDbo = DataSourcesBusiness.getDataSourceDbo(dataSourceName);
  119. for (TableDataSourceDbo table : dataSourceDbo.getTables())
  120. {
  121. TableSelection tableSelection = options.getSelection().getTables().stream()
  122. .filter(t -> t.getTable().getName().equals(table.getName()))
  123. .findFirst().orElse(null);
  124. for (ColumnDataSourceDbo column : table.getColumns())
  125. {
  126. ColumnSelection columnSelection = tableSelection.getColumns().stream()
  127. .filter(c -> c.getColumn().getName().equals(column.getName()))
  128. .findFirst().orElse(null);
  129. convertSqlType(column.getSqlType(), types, dataSourceDbo);
  130. column.setSelected(columnSelection.isSelected());
  131. }
  132. }
  133. for (StoredProcedureDbo spDbo : dataSourceDbo.getStoredProcedures())
  134. {
  135. StoredProcedureSelection sp = options.getSelection().getStoredProcedures().stream()
  136. .filter(s -> s.getStoredProcedure().getText().equals(spDbo.getFullName()))
  137. .findFirst().orElse(null);
  138. convertSqlType(spDbo.getSqlType(), types, dataSourceDbo);
  139. spDbo.setSelected(sp.isSelected());
  140. for (StoredProcedureArgDbo arg : spDbo.getArguments()) {
  141. convertSqlType(arg.getSqlType(), types, dataSourceDbo);
  142. }
  143. }
  144. return dataSourceDbo;
  145. }
  146. public static TypesCastOptions loadTypesCast(String file) throws IOException
  147. {
  148. TypesCastOptions dbo = new TypesCastOptions();
  149. String data = Helper.readFile(file);
  150. JSONObject obj = new JSONObject(data);
  151. JSONObject objTypes = obj.getJSONObject("types");
  152. HashMap<String, HashMap<String, String>> map = new HashMap<>();
  153. for (String key : objTypes.keySet()) {
  154. HashMap<String, String> typeMap = new HashMap<>();
  155. String type = objTypes.optString(key);
  156. JSONObject typeObject = objTypes.optJSONObject(key);
  157. if (typeObject != null) {
  158. for (String subtype : typeObject.keySet()) {
  159. typeMap.put(subtype, typeObject.getString(subtype));
  160. }
  161. }
  162. else if (type != null) {
  163. typeMap.put("*", type);
  164. }
  165. map.put(key, typeMap);
  166. }
  167. dbo.setTypes(map);
  168. List<String> nonNullableTypes = new Vector<>();
  169. JSONArray array = obj.getJSONArray("non-nullable-types");
  170. for (int i = 0; i < array.length(); ++i) {
  171. nonNullableTypes.add(array.getString(i));
  172. }
  173. dbo.setNonNullableTypes(nonNullableTypes);
  174. List<String> reservedWords = new Vector<>();
  175. array = obj.getJSONArray("reserved-words");
  176. for (int i = 0; i < array.length(); ++i) {
  177. reservedWords.add(array.getString(i));
  178. }
  179. dbo.setReservedWords(reservedWords);
  180. dbo.setArrayTemplate(obj.getString("arrayTemplate"));
  181. dbo.setSetOfTemplate(obj.getString("setOfTemplate"));
  182. return dbo;
  183. }
  184. public static void generateFile(String templatePath, String outputFile, DataSourceDbo dataSource,
  185. TableDataSourceDbo table, TypesCastOptions options) throws IOException
  186. {
  187. String data = Helper.readFile(templatePath);
  188. FileOutputStream file = new FileOutputStream(outputFile);
  189. final SimpleJtwigFunction escapeReservedWords = new SimpleJtwigFunction() {
  190. @Override
  191. public String name() {
  192. return "escapeReservedWords";
  193. }
  194. @Override
  195. public Object execute(FunctionRequest functionRequest) {
  196. Object obj = functionRequest.get(0);
  197. if (obj == null)
  198. {
  199. return null;
  200. }
  201. String arg = (String) obj;
  202. String v = escapeReservedWords(arg, options);
  203. return v;
  204. }
  205. };
  206. final SimpleJtwigFunction escapeString = new SimpleJtwigFunction() {
  207. @Override
  208. public String name() {
  209. return "escapeString";
  210. }
  211. @Override
  212. public Object execute(FunctionRequest functionRequest) {
  213. Object obj = functionRequest.get(0);
  214. if (obj == null)
  215. {
  216. return null;
  217. }
  218. String arg = (String) obj;
  219. String v = escapeString(arg);
  220. return v;
  221. }
  222. };
  223. final EnvironmentConfiguration configuration = EnvironmentConfigurationBuilder
  224. .configuration()
  225. .functions()
  226. .add(escapeReservedWords)
  227. .add(escapeString)
  228. .and()
  229. .build();
  230. JtwigTemplate template = JtwigTemplate.inlineTemplate(data, configuration);
  231. JtwigModel model = JtwigModel.newModel()
  232. .with("dataSource", dataSource)
  233. .with("table", table);
  234. template.render(model, file);
  235. file.close();
  236. }
  237. public static void generate(GenerateOptions options, Project project) throws IOException
  238. {
  239. DataSourcesBusiness.getDataSourcesDbo();
  240. String modelsAbsolutePath = Helper.getAbsolutePath(project, options.getModelsRelativePath());
  241. String dataSourceTemplateAbsolutePath = Helper.getAbsolutePath(project, options.getDataSourceTemplateRelativePath());
  242. String modelsTemplateAbsolutePath = Helper.getAbsolutePath(project, options.getModelsTemplateRelativePath());
  243. String typesCastAbsolutePath = Helper.getAbsolutePath(project, options.getCastFileRelativePath());
  244. String dataSourceAbsolutePath = Helper.getAbsolutePath(project, options.getDataSourceRelativePath());
  245. TypesCastOptions types = loadTypesCast(typesCastAbsolutePath);
  246. DataSourceDbo dbo = convertOptions(options, types);
  247. generateFile(dataSourceTemplateAbsolutePath, dataSourceAbsolutePath, dbo, null, types);
  248. for (TableDataSourceDbo table : dbo.getTables()) {
  249. if (table.hasAny()) {
  250. String filename = modelsAbsolutePath + File.separator + table.getName() + "." + options.getFilesExtension();
  251. generateFile(modelsTemplateAbsolutePath, filename, dbo, table, types);
  252. }
  253. }
  254. }
  255. }