├── .gitignore
├── JavaWebCodeGenerator
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── com
│ │ │ └── zju
│ │ │ ├── CodeGenerator.java
│ │ │ ├── FileGenerator.java
│ │ │ ├── ShellRunner.java
│ │ │ ├── meta
│ │ │ ├── Configuration.java
│ │ │ ├── FullyQualifiedJavaType.java
│ │ │ ├── PrimitiveTypeWrapper.java
│ │ │ └── TableColumn.java
│ │ │ └── util
│ │ │ ├── ConfigurationParser.java
│ │ │ ├── JavaTypeResolver.java
│ │ │ └── StringUtils.java
│ ├── resources
│ │ └── ftl
│ │ │ ├── Dao.ftl
│ │ │ ├── DaoImpl.ftl
│ │ │ └── Meta.ftl
│ └── webapp
│ │ ├── WEB-INF
│ │ └── web.xml
│ │ └── index.jsp
│ └── test
│ ├── com
│ └── zju
│ │ ├── CodeGeneratorTest.java
│ │ └── ConfigurationParserTest.java
│ └── resources
│ └── ftl
│ ├── Dao.ftl
│ ├── DaoImpl.ftl
│ └── Meta.ftl
├── README.md
└── TheGameOfLife
├── .gitignore
├── pom.xml
└── src
└── main
├── java
└── com
│ └── zju
│ ├── Main.java
│ ├── controller
│ └── TheGameOfLifeController.java
│ ├── meta
│ ├── CellState.java
│ └── CellularArray.java
│ └── service
│ └── TheGameOfLifeService.java
├── resources
└── Spring
│ └── spring-config.xml
└── webapp
├── WEB-INF
└── web.xml
├── index.css
├── index.html
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | */.classpath
3 | */.project
4 | */.idea/
5 | */*.iml
6 | */target/
7 | */classes/
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .idea/
4 | *.iml
5 | target/
6 | classes/
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.zju
5 | JavaWebCodeGenerator
6 | war
7 | 1.0-SNAPSHOT
8 | JavaWebCodeGenerator Maven Webapp
9 | http://maven.apache.org
10 |
11 |
12 |
13 | org.springframework
14 | spring-framework-bom
15 | 4.3.2.RELEASE
16 | pom
17 | import
18 |
19 |
20 |
21 |
22 |
23 | org.springframework
24 | spring-core
25 |
26 |
27 | org.springframework
28 | spring-beans
29 |
30 |
31 | org.springframework
32 | spring-context
33 |
34 |
35 | mysql
36 | mysql-connector-java
37 | 5.1.38
38 |
39 |
40 | com.google.guava
41 | guava
42 | 18.0
43 |
44 |
45 | org.freemarker
46 | freemarker
47 | 2.3.23
48 |
49 |
50 | org.hsqldb
51 | hsqldb
52 | 2.3.4
53 |
54 |
55 | com.alibaba
56 | fastjson
57 | 1.2.7
58 |
59 |
60 | junit
61 | junit
62 | 4.12
63 | test
64 |
65 |
66 |
67 | JavaWebCodeGenerator
68 |
69 |
70 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/CodeGenerator.java:
--------------------------------------------------------------------------------
1 | package com.zju;
2 |
3 | import com.google.common.collect.Lists;
4 | import com.zju.meta.Configuration;
5 | import com.zju.meta.TableColumn;
6 | import com.zju.util.JavaTypeResolver;
7 | import com.zju.util.StringUtils;
8 | import freemarker.template.TemplateException;
9 |
10 | import java.io.IOException;
11 | import java.sql.*;
12 | import java.util.List;
13 |
14 | /**
15 | * 代码生成器
16 | */
17 | public class CodeGenerator {
18 | public static void generate(Configuration configuration) {
19 | System.out.println("开始连接数据库!");
20 | // File file = new File(configuration.getClassPathEntry());
21 | // if (!file.exists()) {
22 | // throw new RuntimeException("Class not found:"+file.getPath());
23 | // }
24 | // URL url;
25 | // try {
26 | // url = file.toURI().toURL();
27 | // } catch (MalformedURLException e) {
28 | // throw new RuntimeException("uri error");
29 | // }
30 | // ClassLoader parent = Thread.currentThread().getContextClassLoader();
31 | // URLClassLoader ucl = new URLClassLoader(new URL[]{url}, parent);
32 | Connection connection=null;
33 | ResultSet rs=null;
34 | DatabaseMetaData databaseMetaData=null;
35 | List columns= Lists.newArrayList();
36 | TableColumn column;
37 | JavaTypeResolver javaTypeResolver=new JavaTypeResolver();
38 | try {
39 | Class.forName(configuration.getDriverClass());
40 | //获取数据库连接
41 | connection = DriverManager.getConnection(configuration.getConnectionURL(), configuration.getUserId(), configuration.getPassword());
42 | databaseMetaData = connection.getMetaData();
43 | //获取表结构信息
44 | rs = databaseMetaData.getColumns("", "", configuration.getTableName(), "%");
45 | boolean supportsIsAutoIncrement = false;
46 | boolean supportsIsGeneratedColumn = false;
47 | ResultSetMetaData rsmd = rs.getMetaData();
48 | int colCount = rsmd.getColumnCount();
49 | for (int i = 1; i <= colCount; i++) {
50 | if ("IS_AUTOINCREMENT".equals(rsmd.getColumnName(i))) {
51 | supportsIsAutoIncrement = true;
52 | }
53 | if ("IS_GENERATEDCOLUMN".equals(rsmd.getColumnName(i))) {
54 | supportsIsGeneratedColumn = true;
55 | }
56 | }
57 | while (rs.next()) {
58 | column = new TableColumn();
59 | column.setJdbcType(rs.getInt("DATA_TYPE"));
60 | column.setLength(rs.getInt("COLUMN_SIZE"));
61 | column.setActualColumnName(rs.getString("COLUMN_NAME"));
62 | column.setNullable(rs.getInt("NULLABLE") == DatabaseMetaData.columnNullable);
63 | column.setScale(rs.getInt("DECIMAL_DIGITS"));
64 | column.setRemarks(rs.getString("REMARKS"));
65 | column.setDefaultValue(rs.getString("COLUMN_DEF"));
66 |
67 | if (supportsIsAutoIncrement) {
68 | column.setIsAutoIncrement("YES".equals(rs.getString("IS_AUTOINCREMENT")));
69 | }
70 | if (supportsIsGeneratedColumn) {
71 | column.setIsGeneratedColumn("YES".equals(rs.getString("IS_GENERATEDCOLUMN")));
72 | }
73 | column.setJavaType(javaTypeResolver.get(column));
74 | column.setJdbcTypeName(javaTypeResolver.calculateJdbcTypeName(column));
75 | column.setJavaProperty(StringUtils.getCamelCaseString(column.getActualColumnName(), false));
76 | columns.add(column);
77 | }
78 | } catch (ClassNotFoundException e) {
79 | e.printStackTrace();
80 | } catch (SQLException e) {
81 | e.printStackTrace();
82 | }finally {
83 | if(rs!=null){
84 | try {
85 | rs.close();
86 | } catch (SQLException e) {
87 | System.out.println("ResultSet 关闭失败");
88 | }
89 | }
90 | if(connection!=null){
91 | try {
92 | connection.close();
93 | } catch (SQLException e) {
94 | System.out.println("Connection 关闭失败");
95 | }
96 | }
97 | }
98 | System.out.println("数据表信息解析成功!");
99 | try {
100 | FileGenerator.writeFile(configuration,columns);//写文件
101 | } catch (IOException e) {
102 | e.printStackTrace();
103 | } catch (TemplateException e) {
104 | e.printStackTrace();
105 | }
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/FileGenerator.java:
--------------------------------------------------------------------------------
1 | package com.zju;
2 |
3 | import com.alibaba.fastjson.JSON;
4 | import com.zju.meta.TableColumn;
5 | import freemarker.template.Configuration;
6 | import freemarker.template.Template;
7 | import freemarker.template.TemplateException;
8 | import freemarker.template.TemplateExceptionHandler;
9 |
10 | import java.io.File;
11 | import java.io.FileWriter;
12 | import java.io.IOException;
13 | import java.io.Writer;
14 | import java.util.HashMap;
15 | import java.util.List;
16 | import java.util.Map;
17 |
18 | /**
19 | * 文件生成器
20 | */
21 | public class FileGenerator {
22 |
23 | private static String sf = "%s/%s/%s%s";
24 |
25 | public static void writeFile(com.zju.meta.Configuration configuration, List columns) throws IOException, TemplateException {
26 | System.out.println("开始生成文件!");
27 | File r=new File("");
28 | //测试环境获取项目根目录路径
29 | //String path=Class.class.getClass().getResource("/").getPath();
30 | //Jar包获取根目录路径
31 | String path=r.getAbsolutePath();
32 | //System.out.println("path:"+path);
33 | Configuration cfg = new Configuration();
34 | cfg.setDirectoryForTemplateLoading(new File(path + "/ftl")); //需要文件夹绝对路径
35 | cfg.setDefaultEncoding("UTF-8");
36 | cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
37 | Map root = new HashMap();
38 | root.put("configuration", configuration);
39 | root.put("columnList", columns);
40 | writeSingleFile(cfg, root, "DaoImpl.ftl", configuration.getProjectPath(), configuration.getSqlMappingPackage().replace(".", "/"), configuration.getDomainObjectName(), "DaoImpl.java",configuration.getOverwrite());
41 | writeSingleFile(cfg, root, "Dao.ftl", configuration.getProjectPath(), configuration.getSqlMappingPackage().replace(".", "/"), configuration.getDomainObjectName(), "Dao.java",configuration.getOverwrite());
42 | writeSingleFile(cfg, root, "Meta.ftl", configuration.getProjectPath(), configuration.getJavaModelPackage().replace(".", "/"), configuration.getDomainObjectName(), ".java",configuration.getOverwrite());
43 | }
44 |
45 | public static boolean writeSingleFile(Configuration cfg, Map root, String template, String projectPath, String packagePath, String fileName, String suffix,Boolean overwrite) throws IOException, TemplateException {
46 | Template temp = cfg.getTemplate(template);
47 | File file = new File(String.format(sf, projectPath, packagePath, fileName, suffix));
48 | if (!file.getParentFile().exists()) {
49 | if (!file.getParentFile().mkdirs()) {
50 | System.out.println("创建目标文件所在目录失败!");
51 | return false;
52 | }
53 | }
54 | if(file.exists()){
55 | if(!overwrite) {
56 | System.out.println(String.format("创建单个文件%s失败! 文件已存在", file.getPath()));
57 | return false;
58 | }
59 | }else {
60 | if (file.createNewFile()) {
61 | System.out.println(String.format("创建单个文件%s成功!", file.getPath()));
62 | } else {
63 | System.out.println(String.format("创建单个文件%s失败!", file.getPath()));
64 | return false;
65 | }
66 | }
67 | Writer out = null;
68 | try {
69 | out = new FileWriter(file);
70 | temp.process(root, out);
71 | out.flush();
72 | System.out.println(String.format(sf+"完成.", projectPath, packagePath, fileName, suffix));
73 | } catch (Exception e) {
74 | System.out.println(String.format("写入%s失败!", file.getPath()));
75 | } finally {
76 | if (out != null) {
77 | out.close();
78 | }
79 | }
80 | return true;
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/ShellRunner.java:
--------------------------------------------------------------------------------
1 | package com.zju;
2 |
3 | import com.google.common.collect.Maps;
4 | import com.zju.meta.Configuration;
5 | import com.zju.util.ConfigurationParser;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.util.Map;
10 |
11 | /**
12 | * 支持命令行运行项目
13 | */
14 | public class ShellRunner {
15 |
16 | private static final String CONFIG_FILE = "-configfile"; //配置文件
17 | private static final String OVERWRITE="-overwrite"; //是否重写文件
18 |
19 | public static void main(String[] args) throws IOException {
20 | System.out.println("开始执行命令!");
21 | boolean overwrite=false;
22 | if (args.length == 0) {
23 | System.out.println("args is empty");
24 | System.exit(0);
25 | return;
26 | }
27 | //命令参数
28 | Map arguments = parseCommandLine(args);
29 | if (!arguments.containsKey(CONFIG_FILE)) {
30 | System.out.println("args do not contain configfile");
31 | return;
32 | }
33 | if(arguments.containsKey(OVERWRITE)){
34 | overwrite=true;
35 | }
36 | String configfile = arguments.get(CONFIG_FILE);
37 | File configurationFile = new File(configfile);
38 | if (!configurationFile.exists()) {
39 | System.out.println("configfile is not exist");
40 | return;
41 | }
42 | Configuration configuration= ConfigurationParser.parseConfiguration(configurationFile,overwrite);
43 | System.out.println("配置文件解析成功!");
44 | CodeGenerator.generate(configuration);//生成代码
45 | }
46 |
47 | private static Map parseCommandLine(String[] args) {
48 | Map arguments = Maps.newHashMap();
49 | for (int i = 0; i < args.length; ++i) {
50 | if (CONFIG_FILE.equalsIgnoreCase(args[i])) {
51 | if ((i + 1) < args.length) {
52 | arguments.put(CONFIG_FILE, args[i + 1]);
53 | ++i;
54 | } else {
55 | System.out.println("args error");
56 | System.exit(-1);
57 | }
58 | }else if(OVERWRITE.equalsIgnoreCase(args[i])){
59 | arguments.put(OVERWRITE,"");
60 | }
61 | }
62 | return arguments;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/meta/Configuration.java:
--------------------------------------------------------------------------------
1 | package com.zju.meta;
2 |
3 | /**
4 | * 配置类
5 | */
6 | public class Configuration {
7 | private String classPathEntry;
8 | private String driverClass;
9 | private String connectionURL;
10 | private String userId;
11 | private String password;
12 | private String javaModelPackage;
13 | private String sqlMappingPackage;
14 | private String projectPath;
15 | private String tableName;
16 | private String domainObjectName;
17 | private Boolean overwrite;
18 |
19 | public Configuration() {
20 | }
21 |
22 | public String getClassPathEntry() {
23 | return classPathEntry;
24 | }
25 |
26 | public void setClassPathEntry(String classPathEntry) {
27 | this.classPathEntry = classPathEntry;
28 | }
29 |
30 | public String getDriverClass() {
31 | return driverClass;
32 | }
33 |
34 | public void setDriverClass(String driverClass) {
35 | this.driverClass = driverClass;
36 | }
37 |
38 | public String getConnectionURL() {
39 | return connectionURL;
40 | }
41 |
42 | public void setConnectionURL(String connectionURL) {
43 | this.connectionURL = connectionURL;
44 | }
45 |
46 | public String getUserId() {
47 | return userId;
48 | }
49 |
50 | public void setUserId(String userId) {
51 | this.userId = userId;
52 | }
53 |
54 | public String getPassword() {
55 | return password;
56 | }
57 |
58 | public void setPassword(String password) {
59 | this.password = password;
60 | }
61 |
62 | public String getJavaModelPackage() {
63 | return javaModelPackage;
64 | }
65 |
66 | public void setJavaModelPackage(String javaModelPackage) {
67 | this.javaModelPackage = javaModelPackage;
68 | }
69 |
70 | public String getSqlMappingPackage() {
71 | return sqlMappingPackage;
72 | }
73 |
74 | public void setSqlMappingPackage(String sqlMappingPackage) {
75 | this.sqlMappingPackage = sqlMappingPackage;
76 | }
77 |
78 | public String getProjectPath() {
79 | return projectPath;
80 | }
81 |
82 | public void setProjectPath(String projectPath) {
83 | this.projectPath = projectPath;
84 | }
85 |
86 | public String getTableName() {
87 | return tableName;
88 | }
89 |
90 | public void setTableName(String tableName) {
91 | this.tableName = tableName;
92 | }
93 |
94 | public String getDomainObjectName() {
95 | return domainObjectName;
96 | }
97 |
98 | public void setDomainObjectName(String domainObjectName) {
99 | this.domainObjectName = domainObjectName;
100 | }
101 |
102 | public Boolean getOverwrite() {
103 | return overwrite;
104 | }
105 |
106 | public void setOverwrite(Boolean overwrite) {
107 | this.overwrite = overwrite;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/meta/FullyQualifiedJavaType.java:
--------------------------------------------------------------------------------
1 | package com.zju.meta;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.StringTokenizer;
6 |
7 | public class FullyQualifiedJavaType implements
8 | Comparable {
9 |
10 | private static final String JAVA_LANG = "java.lang"; //$NON-NLS-1$
11 |
12 | private String baseShortName;
13 |
14 | private String baseQualifiedName;
15 |
16 | private boolean explicitlyImported;
17 |
18 | private String packageName;
19 |
20 | private boolean primitive;
21 |
22 | private boolean isArray;
23 |
24 | private PrimitiveTypeWrapper primitiveTypeWrapper;
25 |
26 | private List typeArguments;
27 |
28 | private boolean wildcardType;
29 |
30 | private boolean boundedWildcard;
31 |
32 | private boolean extendsBoundedWildcard;
33 |
34 | public FullyQualifiedJavaType(String fullTypeSpecification) {
35 | super();
36 | typeArguments = new ArrayList();
37 | parse(fullTypeSpecification);
38 | }
39 |
40 | public boolean isExplicitlyImported() {
41 | return explicitlyImported;
42 | }
43 |
44 | public String getFullyQualifiedName() {
45 | StringBuilder sb = new StringBuilder();
46 | if (wildcardType) {
47 | sb.append('?');
48 | if (boundedWildcard) {
49 | if (extendsBoundedWildcard) {
50 | sb.append(" extends "); //$NON-NLS-1$
51 | } else {
52 | sb.append(" super "); //$NON-NLS-1$
53 | }
54 |
55 | sb.append(baseQualifiedName);
56 | }
57 | } else {
58 | sb.append(baseQualifiedName);
59 | }
60 |
61 | if (typeArguments.size() > 0) {
62 | boolean first = true;
63 | sb.append('<');
64 | for (FullyQualifiedJavaType fqjt : typeArguments) {
65 | if (first) {
66 | first = false;
67 | } else {
68 | sb.append(", "); //$NON-NLS-1$
69 | }
70 | sb.append(fqjt.getFullyQualifiedName());
71 |
72 | }
73 | sb.append('>');
74 | }
75 |
76 | return sb.toString();
77 | }
78 |
79 | @Override
80 | public boolean equals(Object obj) {
81 | if (this == obj) {
82 | return true;
83 | }
84 |
85 | if (!(obj instanceof FullyQualifiedJavaType)) {
86 | return false;
87 | }
88 |
89 | FullyQualifiedJavaType other = (FullyQualifiedJavaType) obj;
90 |
91 | return getFullyQualifiedName().equals(other.getFullyQualifiedName());
92 | }
93 |
94 | @Override
95 | public int hashCode() {
96 | return getFullyQualifiedName().hashCode();
97 | }
98 |
99 | @Override
100 | public String toString() {
101 | return getFullyQualifiedName();
102 | }
103 |
104 | public int compareTo(FullyQualifiedJavaType other) {
105 | return getFullyQualifiedName().compareTo(other.getFullyQualifiedName());
106 | }
107 |
108 |
109 | private void parse(String fullTypeSpecification) {
110 | String spec = fullTypeSpecification.trim();
111 |
112 | if (spec.startsWith("?")) { //$NON-NLS-1$
113 | wildcardType = true;
114 | spec = spec.substring(1).trim();
115 | if (spec.startsWith("extends ")) { //$NON-NLS-1$
116 | boundedWildcard = true;
117 | extendsBoundedWildcard = true;
118 | spec = spec.substring(8); // "extends ".length()
119 | } else if (spec.startsWith("super ")) { //$NON-NLS-1$
120 | boundedWildcard = true;
121 | extendsBoundedWildcard = false;
122 | spec = spec.substring(6); // "super ".length()
123 | } else {
124 | boundedWildcard = false;
125 | }
126 | parse(spec);
127 | } else {
128 | int index = fullTypeSpecification.indexOf('<');
129 | if (index == -1) {
130 | simpleParse(fullTypeSpecification);
131 | } else {
132 | simpleParse(fullTypeSpecification.substring(0, index));
133 | int endIndex = fullTypeSpecification.lastIndexOf('>');
134 | if (endIndex == -1) {
135 | throw new RuntimeException(fullTypeSpecification); //$NON-NLS-1$
136 | }
137 | genericParse(fullTypeSpecification.substring(index, endIndex + 1));
138 | }
139 |
140 | // this is far from a perfect test for detecting arrays, but is close
141 | // enough for most cases. It will not detect an improperly specified
142 | // array type like byte], but it will detect byte[] and byte[ ]
143 | // which are both valid
144 | isArray = fullTypeSpecification.endsWith("]"); //$NON-NLS-1$
145 | }
146 | }
147 |
148 | private void simpleParse(String typeSpecification) {
149 | baseQualifiedName = typeSpecification.trim();
150 | if (baseQualifiedName.contains(".")) { //$NON-NLS-1$
151 | packageName = getPackage(baseQualifiedName);
152 | baseShortName = baseQualifiedName
153 | .substring(packageName.length() + 1);
154 | int index = baseShortName.lastIndexOf('.');
155 | if (index != -1) {
156 | baseShortName = baseShortName.substring(index + 1);
157 | }
158 |
159 | if (JAVA_LANG.equals(packageName)) { //$NON-NLS-1$
160 | explicitlyImported = false;
161 | } else {
162 | explicitlyImported = true;
163 | }
164 | } else {
165 | baseShortName = baseQualifiedName;
166 | explicitlyImported = false;
167 | packageName = ""; //$NON-NLS-1$
168 |
169 | if ("byte".equals(baseQualifiedName)) { //$NON-NLS-1$
170 | primitive = true;
171 | primitiveTypeWrapper = PrimitiveTypeWrapper.getByteInstance();
172 | } else if ("short".equals(baseQualifiedName)) { //$NON-NLS-1$
173 | primitive = true;
174 | primitiveTypeWrapper = PrimitiveTypeWrapper.getShortInstance();
175 | } else if ("int".equals(baseQualifiedName)) { //$NON-NLS-1$
176 | primitive = true;
177 | primitiveTypeWrapper = PrimitiveTypeWrapper
178 | .getIntegerInstance();
179 | } else if ("long".equals(baseQualifiedName)) { //$NON-NLS-1$
180 | primitive = true;
181 | primitiveTypeWrapper = PrimitiveTypeWrapper.getLongInstance();
182 | } else if ("char".equals(baseQualifiedName)) { //$NON-NLS-1$
183 | primitive = true;
184 | primitiveTypeWrapper = PrimitiveTypeWrapper
185 | .getCharacterInstance();
186 | } else if ("float".equals(baseQualifiedName)) { //$NON-NLS-1$
187 | primitive = true;
188 | primitiveTypeWrapper = PrimitiveTypeWrapper.getFloatInstance();
189 | } else if ("double".equals(baseQualifiedName)) { //$NON-NLS-1$
190 | primitive = true;
191 | primitiveTypeWrapper = PrimitiveTypeWrapper.getDoubleInstance();
192 | } else if ("boolean".equals(baseQualifiedName)) { //$NON-NLS-1$
193 | primitive = true;
194 | primitiveTypeWrapper = PrimitiveTypeWrapper
195 | .getBooleanInstance();
196 | } else {
197 | primitive = false;
198 | primitiveTypeWrapper = null;
199 | }
200 | }
201 | }
202 |
203 | private void genericParse(String genericSpecification) {
204 | int lastIndex = genericSpecification.lastIndexOf('>');
205 | if (lastIndex == -1) {
206 | // shouldn't happen - should be caught already, but just in case...
207 | throw new RuntimeException(genericSpecification); //$NON-NLS-1$
208 | }
209 | String argumentString = genericSpecification.substring(1, lastIndex);
210 | // need to find "," outside of a <> bounds
211 | StringTokenizer st = new StringTokenizer(argumentString, ",<>", true); //$NON-NLS-1$
212 | int openCount = 0;
213 | StringBuilder sb = new StringBuilder();
214 | while (st.hasMoreTokens()) {
215 | String token = st.nextToken();
216 | if ("<".equals(token)) { //$NON-NLS-1$
217 | sb.append(token);
218 | openCount++;
219 | } else if (">".equals(token)) { //$NON-NLS-1$
220 | sb.append(token);
221 | openCount--;
222 | } else if (",".equals(token)) { //$NON-NLS-1$
223 | if (openCount == 0) {
224 | typeArguments
225 | .add(new FullyQualifiedJavaType(sb.toString()));
226 | sb.setLength(0);
227 | } else {
228 | sb.append(token);
229 | }
230 | } else {
231 | sb.append(token);
232 | }
233 | }
234 |
235 | if (openCount != 0) {
236 | throw new RuntimeException(genericSpecification); //$NON-NLS-1$
237 | }
238 |
239 | String finalType = sb.toString();
240 | if (!finalType.isEmpty()) {
241 | typeArguments.add(new FullyQualifiedJavaType(finalType));
242 | }
243 | }
244 |
245 | private static String getPackage(String baseQualifiedName) {
246 | int index = baseQualifiedName.lastIndexOf('.');
247 | return baseQualifiedName.substring(0, index);
248 | }
249 |
250 |
251 | public String getBaseShortName() {
252 | return baseShortName;
253 | }
254 |
255 | public void setBaseShortName(String baseShortName) {
256 | this.baseShortName = baseShortName;
257 | }
258 | }
259 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/meta/PrimitiveTypeWrapper.java:
--------------------------------------------------------------------------------
1 | package com.zju.meta;
2 |
3 | public class PrimitiveTypeWrapper extends FullyQualifiedJavaType {
4 | private static PrimitiveTypeWrapper booleanInstance;
5 | private static PrimitiveTypeWrapper byteInstance;
6 | private static PrimitiveTypeWrapper characterInstance;
7 | private static PrimitiveTypeWrapper doubleInstance;
8 | private static PrimitiveTypeWrapper floatInstance;
9 | private static PrimitiveTypeWrapper integerInstance;
10 | private static PrimitiveTypeWrapper longInstance;
11 | private static PrimitiveTypeWrapper shortInstance;
12 |
13 | private String toPrimitiveMethod;
14 |
15 | private PrimitiveTypeWrapper(String fullyQualifiedName,
16 | String toPrimitiveMethod) {
17 | super(fullyQualifiedName);
18 | this.toPrimitiveMethod = toPrimitiveMethod;
19 | }
20 |
21 | public static PrimitiveTypeWrapper getBooleanInstance() {
22 | if (booleanInstance == null) {
23 | booleanInstance = new PrimitiveTypeWrapper("java.lang.Boolean", //$NON-NLS-1$
24 | "booleanValue()"); //$NON-NLS-1$
25 | }
26 |
27 | return booleanInstance;
28 | }
29 |
30 | public static PrimitiveTypeWrapper getByteInstance() {
31 | if (byteInstance == null) {
32 | byteInstance = new PrimitiveTypeWrapper("java.lang.Byte", //$NON-NLS-1$
33 | "byteValue()"); //$NON-NLS-1$
34 | }
35 |
36 | return byteInstance;
37 | }
38 |
39 | public static PrimitiveTypeWrapper getCharacterInstance() {
40 | if (characterInstance == null) {
41 | characterInstance = new PrimitiveTypeWrapper("java.lang.Character", //$NON-NLS-1$
42 | "charValue()"); //$NON-NLS-1$
43 | }
44 |
45 | return characterInstance;
46 | }
47 |
48 | public static PrimitiveTypeWrapper getDoubleInstance() {
49 | if (doubleInstance == null) {
50 | doubleInstance = new PrimitiveTypeWrapper("java.lang.Double", //$NON-NLS-1$
51 | "doubleValue()"); //$NON-NLS-1$
52 | }
53 |
54 | return doubleInstance;
55 | }
56 |
57 | public static PrimitiveTypeWrapper getFloatInstance() {
58 | if (floatInstance == null) {
59 | floatInstance = new PrimitiveTypeWrapper("java.lang.Float", //$NON-NLS-1$
60 | "floatValue()"); //$NON-NLS-1$
61 | }
62 |
63 | return floatInstance;
64 | }
65 |
66 | public static PrimitiveTypeWrapper getIntegerInstance() {
67 | if (integerInstance == null) {
68 | integerInstance = new PrimitiveTypeWrapper("java.lang.Integer", //$NON-NLS-1$
69 | "intValue()"); //$NON-NLS-1$
70 | }
71 |
72 | return integerInstance;
73 | }
74 |
75 | public static PrimitiveTypeWrapper getLongInstance() {
76 | if (longInstance == null) {
77 | longInstance = new PrimitiveTypeWrapper("java.lang.Long", //$NON-NLS-1$
78 | "longValue()"); //$NON-NLS-1$
79 | }
80 |
81 | return longInstance;
82 | }
83 |
84 | public static PrimitiveTypeWrapper getShortInstance() {
85 | if (shortInstance == null) {
86 | shortInstance = new PrimitiveTypeWrapper("java.lang.Short", //$NON-NLS-1$
87 | "shortValue()"); //$NON-NLS-1$
88 | }
89 |
90 | return shortInstance;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/meta/TableColumn.java:
--------------------------------------------------------------------------------
1 | package com.zju.meta;
2 |
3 | import java.util.Properties;
4 |
5 | /**
6 | * 数据表列
7 | */
8 | public class TableColumn {
9 | protected String actualColumnName;
10 |
11 | protected int jdbcType;
12 |
13 | protected String jdbcTypeName;
14 |
15 | protected boolean nullable;
16 |
17 | protected int length;
18 |
19 | protected int scale;
20 |
21 | protected boolean identity;
22 |
23 | protected boolean isSequenceColumn;
24 |
25 | protected String javaProperty;
26 |
27 |
28 | protected String tableAlias;
29 |
30 | protected String typeHandler;
31 |
32 |
33 | protected boolean isColumnNameDelimited;
34 |
35 | protected Properties properties;
36 |
37 | protected FullyQualifiedJavaType javaType;
38 |
39 | // any database comment associated with this column. May be null
40 | protected String remarks;
41 |
42 | protected String defaultValue;
43 |
44 | /**
45 | * true if the JDBC driver reports that this column is auto-increment
46 | */
47 | protected boolean isAutoIncrement;
48 |
49 | /**
50 | * true if the JDBC driver reports that this column is generated
51 | */
52 | protected boolean isGeneratedColumn;
53 |
54 | /**
55 | * True if there is a column override that defines this column as GENERATED ALWAYS
56 | */
57 | protected boolean isGeneratedAlways;
58 |
59 | public String getActualColumnName() {
60 | return actualColumnName;
61 | }
62 |
63 | public void setActualColumnName(String actualColumnName) {
64 | this.actualColumnName = actualColumnName;
65 | }
66 |
67 | public int getJdbcType() {
68 | return jdbcType;
69 | }
70 |
71 | public void setJdbcType(int jdbcType) {
72 | this.jdbcType = jdbcType;
73 | }
74 |
75 | public String getJdbcTypeName() {
76 | return jdbcTypeName;
77 | }
78 |
79 | public void setJdbcTypeName(String jdbcTypeName) {
80 | this.jdbcTypeName = jdbcTypeName;
81 | }
82 |
83 | public boolean isNullable() {
84 | return nullable;
85 | }
86 |
87 | public void setNullable(boolean nullable) {
88 | this.nullable = nullable;
89 | }
90 |
91 | public int getLength() {
92 | return length;
93 | }
94 |
95 | public void setLength(int length) {
96 | this.length = length;
97 | }
98 |
99 | public int getScale() {
100 | return scale;
101 | }
102 |
103 | public void setScale(int scale) {
104 | this.scale = scale;
105 | }
106 |
107 |
108 |
109 | public String getTableAlias() {
110 | return tableAlias;
111 | }
112 |
113 | public void setTableAlias(String tableAlias) {
114 | this.tableAlias = tableAlias;
115 | }
116 |
117 | public String getRemarks() {
118 | return remarks;
119 | }
120 |
121 | public void setRemarks(String remarks) {
122 | this.remarks = remarks;
123 | }
124 |
125 | public String getDefaultValue() {
126 | return defaultValue;
127 | }
128 |
129 | public void setDefaultValue(String defaultValue) {
130 | this.defaultValue = defaultValue;
131 | }
132 |
133 | public boolean isAutoIncrement() {
134 | return isAutoIncrement;
135 | }
136 |
137 | public void setIsAutoIncrement(boolean isAutoIncrement) {
138 | this.isAutoIncrement = isAutoIncrement;
139 | }
140 |
141 | public boolean isGeneratedColumn() {
142 | return isGeneratedColumn;
143 | }
144 |
145 | public void setIsGeneratedColumn(boolean isGeneratedColumn) {
146 | this.isGeneratedColumn = isGeneratedColumn;
147 | }
148 |
149 | public boolean isIdentity() {
150 | return identity;
151 | }
152 |
153 | public void setIdentity(boolean identity) {
154 | this.identity = identity;
155 | }
156 |
157 | public boolean isSequenceColumn() {
158 | return isSequenceColumn;
159 | }
160 |
161 | public void setIsSequenceColumn(boolean isSequenceColumn) {
162 | this.isSequenceColumn = isSequenceColumn;
163 | }
164 |
165 | public String getJavaProperty() {
166 | return javaProperty;
167 | }
168 |
169 | public void setJavaProperty(String javaProperty) {
170 | this.javaProperty = javaProperty;
171 | }
172 |
173 | public String getTypeHandler() {
174 | return typeHandler;
175 | }
176 |
177 | public void setTypeHandler(String typeHandler) {
178 | this.typeHandler = typeHandler;
179 | }
180 |
181 | public boolean isColumnNameDelimited() {
182 | return isColumnNameDelimited;
183 | }
184 |
185 | public void setIsColumnNameDelimited(boolean isColumnNameDelimited) {
186 | this.isColumnNameDelimited = isColumnNameDelimited;
187 | }
188 |
189 | public Properties getProperties() {
190 | return properties;
191 | }
192 |
193 | public void setProperties(Properties properties) {
194 | this.properties = properties;
195 | }
196 |
197 | public boolean isGeneratedAlways() {
198 | return isGeneratedAlways;
199 | }
200 |
201 | public void setIsGeneratedAlways(boolean isGeneratedAlways) {
202 | this.isGeneratedAlways = isGeneratedAlways;
203 | }
204 |
205 | public FullyQualifiedJavaType getJavaType() {
206 | return javaType;
207 | }
208 |
209 | public void setJavaType(FullyQualifiedJavaType javaType) {
210 | this.javaType = javaType;
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/util/ConfigurationParser.java:
--------------------------------------------------------------------------------
1 | package com.zju.util;
2 |
3 | import com.zju.meta.Configuration;
4 |
5 | import java.io.File;
6 | import java.io.FileReader;
7 | import java.io.IOException;
8 | import java.util.Properties;
9 |
10 | /**
11 | * 解析配置文件
12 | */
13 | public class ConfigurationParser {
14 |
15 | private static final String CLASS_PATH_ENTRY = "class.path.entry";
16 | private static final String DRIVER_CLASS = "driver.class";
17 | private static final String CONNECTION_URL = "connection.url";
18 | private static final String USER_ID = "user.id";
19 | private static final String USER_PASSWORD = "user.password";
20 | private static final String JAVA_MODEL_PACKAGE = "java.model.package";
21 | private static final String SQL_MAPPING_PACKAGE = "sql.mapping.package";
22 | private static final String PROJECT = "project";
23 | private static final String TABLE_NAME = "table.name";
24 | private static final String DOMAIN_OBJECT_NAME = "domain.object.name";
25 |
26 | /**
27 | * 配置文件解析
28 | * @param inputFile 配置文件
29 | * @param overwrite 是否重写参数
30 | * @return
31 | * @throws IOException
32 | */
33 | public static Configuration parseConfiguration(File inputFile,Boolean overwrite) throws IOException {
34 | FileReader fr = new FileReader(inputFile);
35 | Properties prop = new Properties();
36 | prop.load(fr);
37 | Configuration config = new Configuration();
38 | for (Object key : prop.keySet()) {
39 | if (CLASS_PATH_ENTRY.equalsIgnoreCase(key.toString())) {
40 | config.setClassPathEntry(prop.get(key).toString());
41 | } else if (DRIVER_CLASS.equalsIgnoreCase(key.toString())) {
42 | config.setDriverClass(prop.get(key).toString());
43 | } else if (CONNECTION_URL.equalsIgnoreCase(key.toString())) {
44 | config.setConnectionURL(prop.get(key).toString());
45 | } else if (USER_ID.equalsIgnoreCase(key.toString())) {
46 | config.setUserId(prop.get(key).toString());
47 | } else if (USER_PASSWORD.equalsIgnoreCase(key.toString())) {
48 | config.setPassword(prop.get(key).toString());
49 | } else if (JAVA_MODEL_PACKAGE.equalsIgnoreCase(key.toString())) {
50 | config.setJavaModelPackage(prop.get(key).toString());
51 | } else if (SQL_MAPPING_PACKAGE.equalsIgnoreCase(key.toString())) {
52 | config.setSqlMappingPackage(prop.get(key).toString());
53 | } else if (PROJECT.equalsIgnoreCase(key.toString())) {
54 | config.setProjectPath(prop.get(key).toString());
55 | } else if (TABLE_NAME.equalsIgnoreCase(key.toString())) {
56 | config.setTableName(prop.get(key).toString());
57 | } else if (DOMAIN_OBJECT_NAME.equalsIgnoreCase(key.toString())) {
58 | config.setDomainObjectName(prop.get(key).toString());
59 | }
60 | }
61 | config.setOverwrite(overwrite);
62 | return config;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/util/JavaTypeResolver.java:
--------------------------------------------------------------------------------
1 | package com.zju.util;
2 |
3 | import com.zju.meta.TableColumn;
4 | import com.zju.meta.FullyQualifiedJavaType;
5 |
6 | import java.math.BigDecimal;
7 | import java.sql.Types;
8 | import java.util.Date;
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | /**
13 | * 计算Java类型
14 | */
15 | public class JavaTypeResolver {
16 | protected Map typeMap;
17 |
18 | public JavaTypeResolver() {
19 | typeMap = new HashMap();
20 |
21 | typeMap.put(Types.ARRAY, new JdbcTypeInformation("ARRAY",
22 | new FullyQualifiedJavaType(Object.class.getName())));
23 | typeMap.put(Types.BIGINT, new JdbcTypeInformation("BIGINT",
24 | new FullyQualifiedJavaType(Long.class.getName())));
25 | typeMap.put(Types.BINARY, new JdbcTypeInformation("BINARY",
26 | new FullyQualifiedJavaType("byte[]")));
27 | typeMap.put(Types.BIT, new JdbcTypeInformation("BIT",
28 | new FullyQualifiedJavaType(Boolean.class.getName())));
29 | typeMap.put(Types.BLOB, new JdbcTypeInformation("BLOB",
30 | new FullyQualifiedJavaType("byte[]")));
31 | typeMap.put(Types.BOOLEAN, new JdbcTypeInformation("BOOLEAN",
32 | new FullyQualifiedJavaType(Boolean.class.getName())));
33 | typeMap.put(Types.CHAR, new JdbcTypeInformation("CHAR",
34 | new FullyQualifiedJavaType(String.class.getName())));
35 | typeMap.put(Types.CLOB, new JdbcTypeInformation("CLOB",
36 | new FullyQualifiedJavaType(String.class.getName())));
37 | typeMap.put(Types.DATALINK, new JdbcTypeInformation("DATALINK",
38 | new FullyQualifiedJavaType(Object.class.getName())));
39 | typeMap.put(Types.DATE, new JdbcTypeInformation("DATE",
40 | new FullyQualifiedJavaType(Date.class.getName())));
41 | typeMap.put(Types.DECIMAL, new JdbcTypeInformation("DECIMAL",
42 | new FullyQualifiedJavaType(BigDecimal.class.getName())));
43 | typeMap.put(Types.DISTINCT, new JdbcTypeInformation("DISTINCT",
44 | new FullyQualifiedJavaType(Object.class.getName())));
45 | typeMap.put(Types.DOUBLE, new JdbcTypeInformation("DOUBLE",
46 | new FullyQualifiedJavaType(Double.class.getName())));
47 | typeMap.put(Types.FLOAT, new JdbcTypeInformation("FLOAT",
48 | new FullyQualifiedJavaType(Double.class.getName())));
49 | typeMap.put(Types.INTEGER, new JdbcTypeInformation("INTEGER",
50 | new FullyQualifiedJavaType(Integer.class.getName())));
51 | typeMap.put(Types.JAVA_OBJECT, new JdbcTypeInformation("JAVA_OBJECT",
52 | new FullyQualifiedJavaType(Object.class.getName())));
53 | typeMap.put(Types.LONGNVARCHAR, new JdbcTypeInformation("LONGNVARCHAR",
54 | new FullyQualifiedJavaType(String.class.getName())));
55 | typeMap.put(Types.LONGVARBINARY, new JdbcTypeInformation(
56 | "LONGVARBINARY",
57 | new FullyQualifiedJavaType("byte[]")));
58 | typeMap.put(Types.LONGVARCHAR, new JdbcTypeInformation("LONGVARCHAR",
59 | new FullyQualifiedJavaType(String.class.getName())));
60 | typeMap.put(Types.NCHAR, new JdbcTypeInformation("NCHAR",
61 | new FullyQualifiedJavaType(String.class.getName())));
62 | typeMap.put(Types.NCLOB, new JdbcTypeInformation("NCLOB",
63 | new FullyQualifiedJavaType(String.class.getName())));
64 | typeMap.put(Types.NVARCHAR, new JdbcTypeInformation("NVARCHAR",
65 | new FullyQualifiedJavaType(String.class.getName())));
66 | typeMap.put(Types.NULL, new JdbcTypeInformation("NULL",
67 | new FullyQualifiedJavaType(Object.class.getName())));
68 | typeMap.put(Types.NUMERIC, new JdbcTypeInformation("NUMERIC",
69 | new FullyQualifiedJavaType(BigDecimal.class.getName())));
70 | typeMap.put(Types.OTHER, new JdbcTypeInformation("OTHER",
71 | new FullyQualifiedJavaType(Object.class.getName())));
72 | typeMap.put(Types.REAL, new JdbcTypeInformation("REAL",
73 | new FullyQualifiedJavaType(Float.class.getName())));
74 | typeMap.put(Types.REF, new JdbcTypeInformation("REF",
75 | new FullyQualifiedJavaType(Object.class.getName())));
76 | typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT",
77 | new FullyQualifiedJavaType(Short.class.getName())));
78 | typeMap.put(Types.STRUCT, new JdbcTypeInformation("STRUCT",
79 | new FullyQualifiedJavaType(Object.class.getName())));
80 | typeMap.put(Types.TIME, new JdbcTypeInformation("TIME",
81 | new FullyQualifiedJavaType(Date.class.getName())));
82 | typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP",
83 | new FullyQualifiedJavaType(Date.class.getName())));
84 | typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT",
85 | new FullyQualifiedJavaType(Byte.class.getName())));
86 | typeMap.put(Types.VARBINARY, new JdbcTypeInformation("VARBINARY",
87 | new FullyQualifiedJavaType("byte[]")));
88 | typeMap.put(Types.VARCHAR, new JdbcTypeInformation("VARCHAR",
89 | new FullyQualifiedJavaType(String.class.getName())));
90 | }
91 |
92 | public static class JdbcTypeInformation {
93 | private String jdbcTypeName;
94 |
95 | private FullyQualifiedJavaType fullyQualifiedJavaType;
96 |
97 | public JdbcTypeInformation(String jdbcTypeName,
98 | FullyQualifiedJavaType fullyQualifiedJavaType) {
99 | this.jdbcTypeName = jdbcTypeName;
100 | this.fullyQualifiedJavaType = fullyQualifiedJavaType;
101 | }
102 |
103 | public String getJdbcTypeName() {
104 | return jdbcTypeName;
105 | }
106 |
107 | public FullyQualifiedJavaType getFullyQualifiedJavaType() {
108 | return fullyQualifiedJavaType;
109 | }
110 | }
111 |
112 | protected FullyQualifiedJavaType overrideDefaultType(TableColumn column, FullyQualifiedJavaType defaultType) {
113 | FullyQualifiedJavaType answer = defaultType;
114 |
115 | switch (column.getJdbcType()) {
116 | case Types.BIT:
117 | answer = calculateBitReplacement(column, defaultType);
118 | break;
119 | case Types.DECIMAL:
120 | case Types.NUMERIC:
121 | answer = calculateBigDecimalReplacement(column, defaultType);
122 | break;
123 | }
124 |
125 | return answer;
126 | }
127 |
128 | protected FullyQualifiedJavaType calculateBitReplacement(TableColumn column, FullyQualifiedJavaType defaultType) {
129 | FullyQualifiedJavaType answer;
130 |
131 | if (column.getLength() > 1) {
132 | answer = new FullyQualifiedJavaType("byte[]"); //$NON-NLS-1$
133 | } else {
134 | answer = defaultType;
135 | }
136 |
137 | return answer;
138 | }
139 |
140 | protected FullyQualifiedJavaType calculateBigDecimalReplacement(TableColumn column, FullyQualifiedJavaType defaultType) {
141 | FullyQualifiedJavaType answer;
142 |
143 | if (column.getScale() > 0 || column.getLength() > 18) {
144 | answer = defaultType;
145 | } else if (column.getLength() > 9) {
146 | answer = new FullyQualifiedJavaType(Long.class.getName());
147 | } else if (column.getLength() > 4) {
148 | answer = new FullyQualifiedJavaType(Integer.class.getName());
149 | } else {
150 | answer = new FullyQualifiedJavaType(Short.class.getName());
151 | }
152 |
153 | return answer;
154 | }
155 |
156 | public FullyQualifiedJavaType get(TableColumn column) {
157 | FullyQualifiedJavaType answer = null;
158 | JdbcTypeInformation jdbcTypeInformation = typeMap
159 | .get(column.getJdbcType());
160 |
161 | if (jdbcTypeInformation != null) {
162 | answer = jdbcTypeInformation.getFullyQualifiedJavaType();
163 | answer = overrideDefaultType(column, answer);
164 | }
165 | return answer;
166 | }
167 |
168 | public String calculateJdbcTypeName(TableColumn introspectedColumn) {
169 | String answer = null;
170 | JdbcTypeInformation jdbcTypeInformation = typeMap
171 | .get(introspectedColumn.getJdbcType());
172 |
173 | if (jdbcTypeInformation != null) {
174 | answer = jdbcTypeInformation.getJdbcTypeName();
175 | }
176 |
177 | return answer;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/java/com/zju/util/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.zju.util;
2 |
3 | /**
4 | * 字符串处理
5 | */
6 | public class StringUtils {
7 | public static String getCamelCaseString(String inputString,
8 | boolean firstCharacterUppercase) {
9 | StringBuilder sb = new StringBuilder();
10 |
11 | boolean nextUpperCase = false;
12 | for (int i = 0; i < inputString.length(); i++) {
13 | char c = inputString.charAt(i);
14 |
15 | switch (c) {
16 | case '_':
17 | case '-':
18 | case '@':
19 | case '$':
20 | case '#':
21 | case ' ':
22 | case '/':
23 | case '&':
24 | if (sb.length() > 0) {
25 | nextUpperCase = true;
26 | }
27 | break;
28 |
29 | default:
30 | if (nextUpperCase) {
31 | sb.append(Character.toUpperCase(c));
32 | nextUpperCase = false;
33 | } else {
34 | sb.append(Character.toLowerCase(c));
35 | }
36 | break;
37 | }
38 | }
39 |
40 | if (firstCharacterUppercase) {
41 | sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
42 | }
43 |
44 | return sb.toString();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/resources/ftl/Dao.ftl:
--------------------------------------------------------------------------------
1 | public interface ${configuration.domainObjectName}Dao {
2 |
3 | boolean add(${configuration.domainObjectName} obj);
4 |
5 | ${configuration.domainObjectName} getById(long id);
6 |
7 | }
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/resources/ftl/DaoImpl.ftl:
--------------------------------------------------------------------------------
1 | public class ${configuration.domainObjectName}DaoImpl implements ${configuration.domainObjectName}Dao{
2 |
3 | @Override
4 | public boolean add(${configuration.domainObjectName} obj) {
5 | long id = this.allocateRecordId();
6 | if (id < 1) {
7 | return false;
8 | }
9 | String sql = "insert into ${configuration.tableName}("+
10 | "<#list columnList as column><#if 0,#if>${column.actualColumnName}#list>"+
11 | ") values ( <#list columnList as column><#if 0,#if>?#list> ) ";
12 | List params = new ArrayList();
13 | <#list columnList as column>
14 | params.add(obj.get${column.javaProperty?cap_first}());
15 | #list>
16 | return getSqlSupport().addRecord(sql, params);
17 | }
18 |
19 | @Override
20 | public ${configuration.domainObjectName} getById(long id) {
21 | String sql = "select * from ${configuration.tableName} where id = ?";
22 | return queryObject(sql, id);
23 | }
24 |
25 | @Override
26 | public ${configuration.domainObjectName} getObjectFromRs(ResultSet rs) throws SQLException {
27 | ${configuration.domainObjectName} obj=new ${configuration.domainObjectName}();
28 | <#list columnList as column>
29 | obj.set${column.javaProperty?cap_first}(rs.get${column.javaType.baseShortName?cap_first}("${column.actualColumnName}"));
30 | #list>
31 | return obj;
32 | }
33 | }
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/resources/ftl/Meta.ftl:
--------------------------------------------------------------------------------
1 | public class ${configuration.domainObjectName}{
2 |
3 | <#list columnList as column>
4 | //${column.remarks}
5 | private ${column.javaType.baseShortName?cap_first} ${column.javaProperty};
6 |
7 | #list>
8 | <#list columnList as column>
9 | public ${column.javaType.baseShortName?cap_first} get${column.javaProperty?cap_first}() {
10 | return this.${column.javaProperty};
11 | }
12 | public void set${column.javaProperty?cap_first}(${column.javaType.baseShortName?cap_first} ${column.javaProperty}) {
13 | this.${column.javaProperty} = ${column.javaProperty};
14 | }
15 |
16 | #list>
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | Archetype Created Web Application
7 |
8 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/main/webapp/index.jsp:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World!
4 |
5 |
6 |
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/test/com/zju/CodeGeneratorTest.java:
--------------------------------------------------------------------------------
1 | package com.zju;
2 |
3 | import com.zju.meta.Configuration;
4 | import com.zju.util.ConfigurationParser;
5 | import org.junit.Test;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * 代码生成 测试类
11 | */
12 | public class CodeGeneratorTest {
13 |
14 | @Test
15 | public void testGenerate() throws Exception {
16 | File file=new File("src/test/resources/generatorConfig.properties");
17 | Configuration configuration= ConfigurationParser.parseConfiguration(file,true);
18 | System.out.println(configuration);
19 | CodeGenerator.generate(configuration);
20 | }
21 | }
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/test/com/zju/ConfigurationParserTest.java:
--------------------------------------------------------------------------------
1 | package com.zju;
2 |
3 | import com.zju.meta.Configuration;
4 | import com.zju.util.ConfigurationParser;
5 | import org.junit.Test;
6 |
7 | import java.io.File;
8 |
9 | /**
10 | * 配置解析 测试类
11 | */
12 | public class ConfigurationParserTest {
13 |
14 | @Test
15 | public void testParseConfiguration() throws Exception {
16 | File file=new File("src/test/resources/generatorConfig.properties");
17 | Configuration configuration= ConfigurationParser.parseConfiguration(file,true);
18 | System.out.println(configuration);
19 | }
20 | }
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/test/resources/ftl/Dao.ftl:
--------------------------------------------------------------------------------
1 | public interface ${configuration.domainObjectName}Dao {
2 |
3 | boolean add(${configuration.domainObjectName} obj);
4 |
5 | ${configuration.domainObjectName} getById(long id);
6 |
7 | }
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/test/resources/ftl/DaoImpl.ftl:
--------------------------------------------------------------------------------
1 | public class ${configuration.domainObjectName}DaoImpl implements ${configuration.domainObjectName}Dao{
2 |
3 | @Override
4 | public boolean add(${configuration.domainObjectName} obj) {
5 | long id = this.allocateRecordId();
6 | if (id < 1) {
7 | return false;
8 | }
9 | String sql = "insert into ${configuration.tableName}("+
10 | "<#list columnList as column><#if 0,#if>${column.actualColumnName}#list>"+
11 | ") values ( <#list columnList as column><#if 0,#if>?#list> ) ";
12 | List params = new ArrayList();
13 | <#list columnList as column>
14 | params.add(obj.get${column.javaProperty?cap_first}());
15 | #list>
16 | return getSqlSupport().addRecord(sql, params);
17 | }
18 |
19 | @Override
20 | public ${configuration.domainObjectName} getById(long id) {
21 | String sql = "select * from ${configuration.tableName} where id = ?";
22 | return queryObject(sql, id);
23 | }
24 |
25 | @Override
26 | public ${configuration.domainObjectName} getObjectFromRs(ResultSet rs) throws SQLException {
27 | ${configuration.domainObjectName} obj=new ${configuration.domainObjectName}();
28 | <#list columnList as column>
29 | obj.set${column.javaProperty?cap_first}(rs.get${column.javaType.baseShortName?cap_first}("${column.actualColumnName}"));
30 | #list>
31 | return obj;
32 | }
33 | }
--------------------------------------------------------------------------------
/JavaWebCodeGenerator/src/test/resources/ftl/Meta.ftl:
--------------------------------------------------------------------------------
1 | public class ${configuration.domainObjectName}{
2 |
3 | <#list columnList as column>
4 | //${column.remarks}
5 | private ${column.javaType.baseShortName?cap_first} ${column.javaProperty};
6 |
7 | #list>
8 | <#list columnList as column>
9 | public ${column.javaType.baseShortName?cap_first} get${column.javaProperty?cap_first}() {
10 | return this.${column.javaProperty};
11 | }
12 | public void set${column.javaProperty?cap_first}(${column.javaType.baseShortName?cap_first} ${column.javaProperty}) {
13 | this.${column.javaProperty} = ${column.javaProperty};
14 | }
15 |
16 | #list>
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 练习场
2 | 想做的,有趣的,好玩的
3 |
4 | 1. TheGameOfLife 可视化生命游戏
5 | 2. JavaWebCodeGenerator 简单的MySQL代码生成器
--------------------------------------------------------------------------------
/TheGameOfLife/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .project
3 | .idea/
4 | *.iml
5 | target/
--------------------------------------------------------------------------------
/TheGameOfLife/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | com.zju
5 | TheGameOfLife
6 | war
7 | 1.0-SNAPSHOT
8 | TheGameOfLife Maven Webapp
9 | http://maven.apache.org
10 |
11 | 4.3.2.RELEASE
12 |
13 |
14 |
15 | junit
16 | junit
17 | 3.8.1
18 | test
19 |
20 |
21 | org.springframework
22 | spring-context
23 | ${spring.version}
24 |
25 |
26 | org.springframework
27 | spring-core
28 | ${spring.version}
29 |
30 |
31 | org.springframework
32 | spring-beans
33 | ${spring.version}
34 |
35 |
36 | javax.servlet
37 | javax.servlet-api
38 | 3.1.0
39 |
40 |
41 | org.springframework
42 | spring-web
43 | ${spring.version}
44 |
45 |
46 | org.springframework
47 | spring-webmvc
48 | ${spring.version}
49 |
50 |
51 | org.springframework
52 | spring-aop
53 | ${spring.version}
54 |
55 |
56 | log4j
57 | log4j
58 | 1.2.17
59 |
60 |
61 | com.alibaba
62 | fastjson
63 | 1.2.17
64 |
65 |
66 |
67 | TheGameOfLife
68 |
69 |
70 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/java/com/zju/Main.java:
--------------------------------------------------------------------------------
1 | package com.zju;
2 |
3 | import com.zju.meta.CellularArray;
4 | import com.zju.service.TheGameOfLifeService;
5 |
6 | public class Main {
7 |
8 | public static void print(CellularArray cellularArray) {
9 | if (null == cellularArray) {
10 | System.out.println("null");
11 | return;
12 | }
13 | for (int i = 0; i < cellularArray.getRow(); ++i) {
14 | for (int j = 0; j < cellularArray.getCol(); ++j) {
15 | System.out.print(cellularArray.getCell(i, j) + " ");
16 | }
17 | System.out.println();
18 | }
19 | System.out.println("print end");
20 | }
21 |
22 | public static void main(String[] args) {
23 | TheGameOfLifeService service = new TheGameOfLifeService();
24 | CellularArray cellularArray = new CellularArray(15, 20);
25 | cellularArray = service.randInit(cellularArray);
26 | print(cellularArray);
27 | System.out.println("------");
28 | cellularArray = service.generate(cellularArray);
29 | print(cellularArray);
30 | }
31 | }
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/java/com/zju/controller/TheGameOfLifeController.java:
--------------------------------------------------------------------------------
1 | package com.zju.controller;
2 |
3 | import com.zju.meta.CellularArray;
4 | import com.zju.service.TheGameOfLifeService;
5 | import org.springframework.stereotype.Controller;
6 | import org.springframework.web.bind.annotation.RequestBody;
7 | import org.springframework.web.bind.annotation.RequestMapping;
8 | import org.springframework.web.bind.annotation.RequestParam;
9 | import org.springframework.web.bind.annotation.ResponseBody;
10 |
11 | import javax.annotation.Resource;
12 |
13 | @Controller
14 | @RequestMapping("/")
15 | public class TheGameOfLifeController {
16 |
17 | private static final int defaultRow = 15;
18 | private static final int defaultCol = 15;
19 |
20 | @Resource
21 | private TheGameOfLifeService service;
22 |
23 | @ResponseBody
24 | @RequestMapping("/randInit")
25 | public Object getRandInit(@RequestParam(required = false) Integer row, @RequestParam(required = false) Integer col) {
26 | if (null == row) row = defaultRow;
27 | if (null == col) col = defaultCol;
28 | CellularArray cellularArray = service.randInit(new CellularArray(row, col));
29 | return cellularArray;
30 | }
31 |
32 | @ResponseBody
33 | @RequestMapping("/generate")
34 | public Object generate(@RequestBody CellularArray now) {
35 | CellularArray next = service.generate(now);
36 | return next;
37 | }
38 |
39 | @ResponseBody
40 | @RequestMapping("/empty")
41 | public Object empty(@RequestParam(required = false) Integer row, @RequestParam(required = false) Integer col) {
42 | if (null == row) row = defaultRow;
43 | if (null == col) col = defaultCol;
44 | CellularArray next = service.emptyInit(new CellularArray(row,col));
45 | return next;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/java/com/zju/meta/CellState.java:
--------------------------------------------------------------------------------
1 | package com.zju.meta;
2 |
3 | /**
4 | * 细胞状态
5 | */
6 | public enum CellState {
7 | DEAD(0),
8 | LIVE(1);
9 | private int value;
10 |
11 | CellState(int value) {
12 | this.value = value;
13 | }
14 |
15 | public int getValue() {
16 | return value;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/java/com/zju/meta/CellularArray.java:
--------------------------------------------------------------------------------
1 | package com.zju.meta;
2 |
3 | /**
4 | * 细胞阵列
5 | */
6 | public class CellularArray {
7 | private int[][] cells;
8 | private int row;
9 | private int col;
10 |
11 | public CellularArray() {
12 | }
13 |
14 | public CellularArray(int row, int col) {
15 | this.row = row;
16 | this.col = col;
17 | this.cells = new int[row][col];
18 | }
19 |
20 | public int getRow() {
21 | return row;
22 | }
23 |
24 | public void setRow(int row) {
25 | this.row = row;
26 | }
27 |
28 | public int getCol() {
29 | return col;
30 | }
31 |
32 | public void setCol(int col) {
33 | this.col = col;
34 | }
35 |
36 | public int[][] getCells() {
37 | return cells;
38 | }
39 |
40 | public void setCells(int[][] cells) {
41 | this.cells = cells;
42 | }
43 |
44 | public int getCell(int x, int y) {
45 | if (x < 0 || this.row <= x || y < 0 || this.col <= y) {
46 | return -1;
47 | }
48 | return this.cells[x][y];
49 | }
50 |
51 | public boolean setCell(int x, int y, int cell) {
52 | if (x < 0 || this.row <= x || y < 0 || this.col <= y) {
53 | return false;
54 | }
55 | this.cells[x][y] = cell;
56 | return true;
57 | }
58 |
59 | @Override
60 | public boolean equals(Object obj) {
61 | if (this == obj) return true;
62 | if (obj == null) return false;
63 | if (this.getClass() != obj.getClass()) return false;
64 | CellularArray other = (CellularArray) obj;
65 | if (this.row != other.getRow() || this.col != other.getCol()) return false;
66 | for (int i = 0; i < this.row; ++i) {
67 | for (int j = 0; j < this.col; ++j) {
68 | if (this.cells[i][j] != other.getCell(i, j)) {
69 | return false;
70 | }
71 | }
72 | }
73 | return true;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/java/com/zju/service/TheGameOfLifeService.java:
--------------------------------------------------------------------------------
1 | package com.zju.service;
2 |
3 | import com.zju.meta.CellState;
4 | import com.zju.meta.CellularArray;
5 | import org.springframework.stereotype.Service;
6 |
7 | import java.util.Random;
8 |
9 | @Service
10 | public class TheGameOfLifeService {
11 | //方向数组
12 | private int[] direct = {-1, 0, 1};
13 |
14 | /**
15 | * 给定阵列和坐标,计算坐标点的邻居存活数量
16 | * @param now 细胞阵列
17 | * @param x 横坐标
18 | * @param y 纵坐标
19 | * @return
20 | */
21 | private int countLiveNeighbor(CellularArray now, int x, int y) {
22 | int count = 0;
23 | for (int i = 0; i < 3; ++i) {
24 | for (int j = 0; j < 3; ++j) {
25 | if (CellState.LIVE.getValue() == now.getCell(x + this.direct[i], y + this.direct[j])) {
26 | ++count;
27 | }
28 | }
29 | }
30 | if (CellState.LIVE.getValue() == now.getCell(x, y)) {
31 | --count;
32 | }
33 | return count;
34 | }
35 |
36 | /**
37 | * 给定细胞阵列,生成下一代的细胞阵列
38 | * @param now 细胞阵列
39 | * @return
40 | */
41 | public CellularArray generate(CellularArray now) {
42 | if (null == now) {
43 | return null;
44 | }
45 | int liveCount;
46 | CellularArray next = new CellularArray(now.getRow(), now.getCol());
47 | for (int i = 0; i < next.getRow(); ++i) {
48 | for (int j = 0; j < next.getCol(); ++j) {
49 | liveCount = this.countLiveNeighbor(now, i, j);
50 | if (CellState.LIVE.getValue() == now.getCell(i, j) && (liveCount < 2 || liveCount > 3)) { //人口过少,人口过多
51 | next.setCell(i, j, CellState.DEAD.getValue());
52 | } else if (CellState.LIVE.getValue() == now.getCell(i, j) && (2 <= liveCount && liveCount <= 3)) { //正常
53 | next.setCell(i, j, CellState.LIVE.getValue());
54 | } else if (CellState.DEAD.getValue() == now.getCell(i, j) && (3 == liveCount)) { //繁殖
55 | next.setCell(i, j, CellState.LIVE.getValue());
56 | }
57 | }
58 | }
59 | return next;
60 | }
61 |
62 | /**
63 | * 给定细胞阵列,产生随机结果
64 | * @param cellularArray 细胞阵列
65 | * @return
66 | */
67 | public CellularArray randInit(CellularArray cellularArray) {
68 | if (null == cellularArray) return null;
69 | Random r = new Random();
70 | int value;
71 | for (int i = 0; i < cellularArray.getRow(); ++i) {
72 | for (int j = 0; j < cellularArray.getCol(); ++j) {
73 | value = r.nextInt(2);
74 | cellularArray.setCell(i, j, value);
75 | }
76 | }
77 | return cellularArray;
78 | }
79 |
80 | /**
81 | * 给定细胞阵列,产生初始化结果
82 | * @param cellularArray
83 | * @return
84 | */
85 | public CellularArray emptyInit(CellularArray cellularArray) {
86 | if (null == cellularArray) return null;
87 | for (int i = 0; i < cellularArray.getRow(); ++i) {
88 | for (int j = 0; j < cellularArray.getCol(); ++j) {
89 | cellularArray.setCell(i, j, CellState.DEAD.getValue());
90 | }
91 | }
92 | return cellularArray;
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/resources/Spring/spring-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | text/plain
20 | application/json
21 |
22 |
23 |
24 |
25 | WriteMapNullValue
26 | DisableCircularReferenceDetect
27 | WriteDateUseDateFormat
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 | The Game Of Life
7 |
8 | spring-mvc
9 | org.springframework.web.servlet.DispatcherServlet
10 |
11 | contextConfigLocation
12 | classpath:Spring/*.xml
13 |
14 | 1
15 |
16 |
17 | spring-mvc
18 |
19 | /backend/*
20 |
21 |
22 | /index.html
23 |
24 |
25 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/webapp/index.css:
--------------------------------------------------------------------------------
1 | .td-white {
2 | background-color: white;
3 | width: 20px;
4 | height: 20px;
5 | }
6 |
7 | .td-black {
8 | background-color: black;
9 | width: 20px;
10 | height: 20px;
11 | }
12 |
13 | body {
14 | margin: 10px;
15 | }
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/webapp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | The Game Of Life
7 |
8 |
9 |
10 |
11 |
12 |
13 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/TheGameOfLife/src/main/webapp/index.js:
--------------------------------------------------------------------------------
1 | var cellularArray;
2 | //根据参数控制页面显示的细胞阵列
3 | function createTable(cellularArray) {
4 | //清空控件内容
5 | $("#table").empty();
6 | var rowCount = cellularArray.row;
7 | var colCount = cellularArray.col;
8 | var table = $("");
9 | table.appendTo($("#table"));
10 | var cells = cellularArray.cells;
11 | for (var i = 0; i < rowCount; ++i) {
12 | var tr = $("
");
13 | tr.appendTo(table);
14 | for (var j = 0; j < colCount; ++j) {
15 | var td;
16 | if (cells[i][j] == 0) {
17 | td = $("" + " | ");
18 | } else {
19 | td = $("" + " | ");
20 | }
21 | td.appendTo(tr);
22 | }
23 | }
24 | $("#table").append("
");
25 | }
26 | //点击细胞后反转其生死
27 | function checkCell(cell) {
28 | var x = parseInt($(cell).attr("data-x"));
29 | var y = parseInt($(cell).attr("data-y"));
30 | var cells = cellularArray.cells;
31 | cells[x][y] = (cells[x][y] + 1) % 2;
32 | this.createTable(cellularArray);
33 | }
34 | $("#initButton").click(function () {
35 | var rowCount = $("#rowText").val();
36 | var colCount = $("#colText").val();
37 | $.ajax({
38 | url: "/backend/randInit",
39 | type: "GET",
40 | dataType: "JSON",
41 | contentType: "application/json",
42 | data: {
43 | row: rowCount,
44 | col: colCount
45 | },
46 | success: function (result) {
47 | cellularArray = result;
48 | createTable(cellularArray);
49 | }
50 | });
51 | $("#generateCount").val(0);
52 | });
53 | $("#generateButton").click(function () {
54 | var rowCount = $("#rowText").val();
55 | var colCount = $("#colText").val();
56 | var generateCount = $("#generateCount").val();
57 | $.ajax({
58 | type: "POST",
59 | url: "/backend/generate",
60 | dataType: "JSON",
61 | contentType: "application/json",
62 | data: JSON.stringify(cellularArray),
63 | success: function (result) {
64 | cellularArray = result;
65 | createTable(cellularArray);
66 | }
67 | });
68 | $("#generateCount").val(parseInt(generateCount) + 1);
69 | });
70 | $("#countCleanButton").click(function () {
71 | $("#generateCount").val(0);
72 | });
73 | $("#cellCleanButton").click(function () {
74 | var rowCount = $("#rowText").val();
75 | var colCount = $("#colText").val();
76 | $.ajax({
77 | url: "/backend/empty",
78 | type: "GET",
79 | dataType: "JSON",
80 | contentType: "application/json",
81 | data: {
82 | row: rowCount,
83 | col: colCount
84 | },
85 | success: function (result) {
86 | cellularArray = result;
87 | createTable(cellularArray);
88 | $("#generateCount").val(0);
89 | $("#rowText").val(cellularArray.row);
90 | $("#colText").val(cellularArray.col);
91 | }
92 | });
93 | });
--------------------------------------------------------------------------------