├── .gitignore
├── LICENSE
├── README.md
├── TODO.txt
├── example
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── Main.java
│ └── resources
│ └── SimpleExample
│ ├── custom.conf
│ ├── pom.xml
│ └── src
│ └── main
│ ├── java
│ ├── ${package}
│ │ ├── controller
│ │ │ ├── ${bean.name}Controller.java
│ │ │ └── BaseController.java
│ │ ├── dao
│ │ │ ├── ${bean.name}Dao.java
│ │ │ └── BaseDao.java
│ │ ├── model
│ │ │ └── ${bean.name}.java
│ │ ├── service
│ │ │ ├── ${bean.name}Service.java
│ │ │ └── impl
│ │ │ │ └── ${bean.name}ServiceImpl.java
│ │ └── util
│ │ │ └── JsonUtil.java
│ └── net
│ │ └── sf
│ │ └── log4jdbc
│ │ └── DataSourceSpyInterceptor.java
│ ├── resources
│ ├── log4j.properties
│ ├── mappers
│ │ └── ${bean.name}Mapper.xml
│ ├── mybatis
│ │ └── mybatis.xml
│ └── spring
│ │ ├── application-context.xml
│ │ ├── application-datasource.xml
│ │ ├── application-mybatis.xml
│ │ └── application-servlet.xml
│ └── webapp
│ └── WEB-INF
│ ├── jetty-web.xml
│ └── web.xml
├── pom.xml
└── src
└── main
├── java
└── github
│ └── jadetang
│ └── maliang
│ ├── MEngine.java
│ ├── bean
│ ├── Column.java
│ ├── JavaClass.java
│ ├── JavaDataBaseRelation.java
│ ├── JavaField.java
│ ├── Relation.java
│ ├── Table.java
│ └── Tuple.java
│ ├── builder
│ ├── ContextBuilder.java
│ ├── JavaDataBaseRelationBuilder.java
│ └── SourceCodeGenerator.java
│ ├── conf
│ └── MConfig.java
│ ├── exception
│ └── MaliangException.java
│ ├── resource
│ ├── ClassLoaderWrapper.java
│ └── Resources.java
│ └── util
│ ├── ContextUtil.java
│ └── FileUtil.java
└── resources
├── log4j.properties
└── reference.conf
/.gitignore:
--------------------------------------------------------------------------------
1 | *.class
2 |
3 | # Mobile Tools for Java (J2ME)
4 | .mtj.tmp/
5 |
6 | # Package Files #
7 | *.jar
8 | *.war
9 | *.ear
10 |
11 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
12 | hs_err_pid*
13 |
14 |
15 |
16 | .idea
17 |
18 | /target
19 |
20 | *.iml
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Tang Sicheng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Maliang
2 |
3 | Maliang(马良), the name of this project comes from a character of folk tail in China who has a magical brush by which he can draw any thing and turn it to real thing.
4 |
5 | ## Motivation
6 | In most of J2EE projet, there are a lot of codes are about CRUD which refer to the basic functions of a database or persistence layer in a software system. By using Maliang, you can generate these template codes based on your DDL
7 | ```
8 | CREATE TABLE `user` (
9 | `id` int(11) NOT NULL AUTO_INCREMENT,
10 | `name` varchar(32) DEFAULT NULL,
11 | `age` int(11) DEFAULT NULL,
12 | `sex` varchar(2) DEFAULT NULL,
13 | PRIMARY KEY (`id`)
14 | )
15 | ```
16 |
17 | ## Under the hood
18 | Maliang use sql parser to parser DDL, then convert the result to a VelocityContext.
19 | The *SourceCodeGenerator.generate(VelocityContext context)* will generate the code with the template and output directory, so acctually you could generate code with your own context builder and your own tempalte.
20 |
21 | ## Some rules
22 | 1. **Directroy and File Name**
23 | The *SourceCodeGenerator* will replace automatically replace the directory path and the file name with the value in VelocityContext. Suppose you have a template file called ```/${basepackage}/${name}Dao.java```, and in the context the ```${basepackage}``` equals ```com.github.maliang``` and the ```${name}``` equals ```jadetang```, you will get a new file ```/com/github/maliang/jadetangDao.java```
24 |
25 | 2. **Database table naming convention**
26 | Usually we name the database objects in a different way comparing we name the java objects, with the custom config file, you can control how the database object name are converted to the java object name.Here is a config examle
27 | ```
28 | name {
29 | separator = "T_APP"
30 | table.prefix = "F"
31 | column.prefix = "_"
32 | }
33 | ```
34 |
--------------------------------------------------------------------------------
/TODO.txt:
--------------------------------------------------------------------------------
1 | 按照是否值得做从前到后排序
2 | 0. 更多的模板
3 |
4 | 1. 领域对象需要更加完善的信息以生成更加强大的模板。例如
5 | ~ 某个字段为空,则生成的java对象应该有@NotNull标注。
6 | ~ 如果表有一个自增长的id字段,则可以生成selectById,deleteById等方法
7 | ~ 如果某些字段是date类型,生成的spring controller方法实际上是需要对于date类型的http参数进行特殊。
8 | 现在用的是jsqlparser,这些信息都应该可以拿到,通过修改JavaDataBaseRelationBuilder方法,可以增强model包下的领域模型的信息,例如java type是否是日期类型,是否为空,是否是主键。
9 | 或者重新写一个真对create table的parser
10 |
11 | 2. 目前的路径只能是绝对路径,如果在windows下,配置成/data/dirX之类的路径是不行的,但是log4j等日志框架,可以支持。
12 |
13 | 3. 目前的ddl只能通过输入的方式,也可以通过直接连数据库的方式来获取,例如mybatis generator的做法。
14 |
15 | 4. 只支持单表生成sql,可以通过配置表和表之间关系的方式生成join sql和更加复杂的复合model,可以参考 spring roo的one to many的表关系配置。
--------------------------------------------------------------------------------
/example/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | maliang
7 | github.jadetang
8 | 1.0-SNAPSHOT
9 |
10 | 4.0.0
11 |
12 | github.jadetang
13 | maliang-example
14 |
15 |
16 |
--------------------------------------------------------------------------------
/example/src/main/java/Main.java:
--------------------------------------------------------------------------------
1 | import com.typesafe.config.ConfigFactory;
2 | import github.jadetang.maliang.MEngine;
3 | import github.jadetang.maliang.conf.MConfig;
4 | import github.jadetang.maliang.resource.Resources;
5 |
6 | import java.io.File;
7 | import java.io.IOException;
8 |
9 | /**
10 | * @Author Tang Sicheng
11 | */
12 | public class Main {
13 |
14 |
15 | private static MConfig mConfig = new MConfig(ConfigFactory.load());
16 |
17 | private static String sql = "CREATE TABLE user (\n" +
18 | " age INT,\n" +
19 | " NAME VARCHAR(32),\n" +
20 | " sex VARCHAR\n" +
21 | ");" +
22 | "create table salary(" +
23 | "name varchar(32)," +
24 | "pay int)";
25 |
26 | public static void main(String[] args) throws IOException {
27 |
28 | File customConfig = Resources.getResourceAsFile(Main.class.getClassLoader(),"SimpleExample/custom.conf");
29 | MEngine engine = new MEngine(customConfig);
30 | engine.generateCode(sql);
31 |
32 | /* Path simpleExample = Paths.get("example/src/main/resources/SimpleExample");
33 | Path outPut = Paths.get("example/target/output");
34 |
35 | JavaObjectBuilder javaObjectBuilder = new JavaObjectBuilder(mConfig);
36 | Tuple t = javaObjectBuilder.parser(sql);
37 | VelocityContext c = ContextBuilder.build(t._1(),t._2(),mConfig);
38 |
39 | // System.out.println(m.getBasePackage());
40 | SourceCodeGenerator generator = new SourceCodeGenerator(simpleExample.toAbsolutePath().toString(), outPut.toAbsolutePath().toString(), mConfig);
41 | generator.init();
42 | generator.generate(c);*/
43 | }
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/custom.conf:
--------------------------------------------------------------------------------
1 | maven {
2 | groupId = com.meizu.orion
3 | artifactId = quick-start
4 | version = 1.0.0-SNAPSHOT
5 | package = com.meizu.orion
6 | }
7 |
8 |
9 |
10 | dir{
11 | template = "E:\\code_base\\maliang\\example\\src\\main\\resources\\SimpleExample"
12 | output = "E:\\test"
13 | backup = "E:\\temp"
14 | }
15 |
16 |
17 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 |
6 | com.meizu.base
7 | parent.war
8 | 2.2.1
9 |
10 | ${groupId}
11 | ${artifactId}
12 | ${version}
13 | ${artifactId}
14 | war
15 | http://maven.apache.org
16 |
17 |
18 |
19 |
20 |
21 | com.meizu.framework
22 | framework-service
23 | 1.0.2
24 |
25 |
26 |
27 |
28 |
29 |
30 | org.springframework
31 | spring-beans
32 |
33 |
34 | org.springframework
35 | spring-core
36 |
37 |
38 | org.springframework
39 | spring-context
40 |
41 |
42 | org.springframework
43 | spring-webmvc
44 |
45 |
46 | javaee
47 | javaee
48 | provided
49 |
50 |
51 |
52 |
53 |
54 | org.mybatis
55 | mybatis
56 | 3.5.6
57 |
58 |
59 | org.mybatis
60 | mybatis-spring
61 | 1.2.0
62 |
63 |
64 | org.springframework
65 | spring-tx
66 |
67 |
68 |
69 |
70 | com.github.miemiedev
71 | mybatis-paginator
72 | 1.2.17
73 |
74 |
75 |
76 |
77 |
78 |
79 | org.apache.commons
80 | commons-lang3
81 | 3.3.2
82 |
83 |
84 |
85 |
86 |
87 | log4j
88 | log4j
89 |
90 |
91 | org.slf4j
92 | slf4j-log4j12
93 | 1.7.5
94 |
95 |
96 | com.googlecode.log4jdbc
97 | log4jdbc
98 | 1.2
99 |
100 |
101 |
102 |
103 |
104 |
105 | com.google.code.gson
106 | gson
107 | 2.2.4
108 |
109 |
110 |
111 |
112 |
113 |
114 | com.jolbox
115 | bonecp
116 | 0.8.0.RELEASE
117 |
118 |
119 | mysql-connector-java
120 | mysql-connector-java
121 | 5.1.22
122 |
123 |
124 |
125 |
126 |
127 |
128 | org.springframework
129 | spring-test
130 | test
131 |
132 |
133 | junit
134 | junit
135 | test
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | env.develop
146 |
147 | true
148 |
149 |
150 |
151 |
152 |
153 | org.apache.maven.plugins
154 | maven-war-ant-plugin
155 |
156 |
157 | combining js...
158 |
159 |
160 |
162 |
164 |
165 |
166 |
167 |
169 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 | env.production
181 |
182 |
183 |
184 | org.apache.maven.plugins
185 | maven-war-ant-plugin
186 |
187 |
188 | combining js...
189 |
190 |
191 |
193 |
195 |
196 |
197 |
198 |
200 |
202 |
203 |
206 |
208 |
209 |
210 |
211 |
212 |
215 |
217 |
218 |
219 |
220 |
221 |
222 |
225 |
226 |
227 |
228 |
229 |
230 | org.codehaus.mojo
231 | rpm-maven-plugin
232 |
233 |
234 | org.apache.maven.plugins
235 | maven-deploy-plugin
236 |
237 |
238 | org.codehaus.mojo
239 | build-helper-maven-plugin
240 |
241 |
242 |
243 |
244 |
245 |
246 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/controller/${bean.name}Controller.java:
--------------------------------------------------------------------------------
1 | #define( $service ) ${StringUtil.lowerFirstLetter(${bean.name})}Service#end
2 | #set( $beanRef = ${StringUtil.lowerFirstLetter(${bean.name})} )
3 |
4 | package ${package}.controller;
5 |
6 | import ${package}.service.${bean.name}Service;
7 | import ${package}.model.${bean.name};
8 |
9 | import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
10 | import com.github.miemiedev.mybatis.paginator.domain.PageList;
11 | import org.springframework.beans.factory.annotation.Autowired;
12 | import org.springframework.stereotype.Controller;
13 | import org.springframework.web.bind.annotation.RequestMapping;
14 | import org.springframework.web.bind.annotation.RequestMethod;
15 | import org.springframework.web.bind.annotation.RequestParam;
16 |
17 | import javax.servlet.http.HttpServletResponse;
18 | import java.io.IOException;
19 | import java.util.List;
20 |
21 | @Controller
22 | @RequestMapping(value = "/v1/${beanRef}s")
23 | public class ${bean.name}Controller extends BaseController{
24 |
25 |
26 | @Autowired
27 | private ${bean.name}Service ${service};
28 |
29 | @RequestMapping(value="",method=RequestMethod.POST)
30 | public void insert${bean.name}(${bean.name} $beanRef,HttpServletResponse response) throws IOException {
31 | Integer affectRecord = ${service}.insert($beanRef);
32 | responseAsJson(response,affectRecord);
33 | }
34 |
35 | @RequestMapping(value="",method=RequestMethod.GET)
36 | public void selectAll${bean.name}(HttpServletResponse response) throws IOException {
37 | List<${bean.name}> all${bean.name} = ${service}.selectAll();
38 | responseAsJson(response,all${bean.name});
39 | }
40 |
41 | @RequestMapping(value="/$beanRef",method=RequestMethod.GET)
42 | public void select${bean.name}(${bean.name} $beanRef,@RequestParam(required = false, defaultValue = "1") int page,
43 | @RequestParam(required = false, defaultValue = "10") int limit,HttpServletResponse response)
44 | throws IOException {
45 | List ${bean.name}s = ${service}.select($beanRef, new PageBounds(page, limit));
46 | responseAsJson(response,(PageList)${bean.name}s);
47 | }
48 |
49 | @RequestMapping(value="/$beanRef",method=RequestMethod.DELETE)
50 | public void delele${bean.name}(${bean.name} $beanRef,HttpServletResponse response )throws IOException {
51 | Integer affectRecord = ${service}.delete($beanRef);
52 | responseAsJson(response,affectRecord);
53 | }
54 |
55 | @RequestMapping(value="/$beanRef",method=RequestMethod.PUT)
56 | public void update${bean.name}(${bean.name} $beanRef,HttpServletResponse response )throws IOException {
57 | Integer affectRecord = ${service}.update($beanRef);
58 | responseAsJson(response,affectRecord);
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/controller/BaseController.java:
--------------------------------------------------------------------------------
1 | package ${package}.controller;
2 |
3 |
4 | import ${package}.util.JsonUtil;
5 |
6 | import javax.servlet.http.HttpServletResponse;
7 | import java.io.IOException;
8 | import java.io.PrintWriter;
9 |
10 | public class BaseController{
11 |
12 | protected void responseAsJson(HttpServletResponse response,Object object) throws IOException {
13 | response.setContentType("application/json; charset=utf-8");
14 | PrintWriter out = response.getWriter();
15 | out.write(JsonUtil.toJson(object));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/dao/${bean.name}Dao.java:
--------------------------------------------------------------------------------
1 | package ${config.basePackage}.dao;
2 |
3 | import java.util.List;
4 | import ${config.basePackage}.model.${bean.name};
5 |
6 | import org.springframework.stereotype.Repository;
7 | import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
8 |
9 | @Repository("${StringUtil.lowerFirstLetter(${bean.name})}Dao")
10 | public class ${bean.name}Dao extends BaseDao{
11 |
12 | public List select(${bean.name} entity,PageBounds pageBounds) {
13 | return this.getSqlMap().selectList(this.getClass().getName()+".select", entity, pageBounds);
14 | }
15 |
16 | public List<${bean.name}> selectAll(){
17 | return this.getSqlMap().selectList(this.getClass().getName()+".selectAll");
18 | }
19 |
20 | public Integer delete(${bean.name} entity){
21 | return this.getSqlMap().delete(this.getClass().getName()+".delete",entity);
22 | }
23 |
24 | public Integer update(${bean.name} entity){
25 | return this.getSqlMap().update(this.getClass().getName()+".update",entity);
26 | }
27 |
28 | public Integer insert(${bean.name} entity){
29 | return this.getSqlMap().insert(this.getClass().getName()+".insert",entity);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/dao/BaseDao.java:
--------------------------------------------------------------------------------
1 | package ${package}.dao;
2 |
3 | import org.mybatis.spring.SqlSessionTemplate;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.beans.factory.annotation.Qualifier;
6 |
7 | public abstract class BaseDao{
8 | protected SqlSessionTemplate getSqlMap(){
9 | return sqlSessionTemplate;
10 | }
11 |
12 | public SqlSessionTemplate getSqlSessionTemplate() {
13 | return sqlSessionTemplate;
14 | }
15 |
16 | public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
17 | this.sqlSessionTemplate = sqlSessionTemplate;
18 | }
19 |
20 | @Autowired
21 | @Qualifier("sqlSessionTemplate")
22 | private SqlSessionTemplate sqlSessionTemplate;
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/model/${bean.name}.java:
--------------------------------------------------------------------------------
1 | #set( $symbol_pound = '#' )
2 | #set( $symbol_dollar = '$' )
3 | #set( $symbol_escape = '\' )
4 | package ${package}.model;
5 |
6 | import org.apache.commons.lang3.builder.ToStringBuilder;
7 | import org.apache.commons.lang3.builder.ToStringStyle;
8 |
9 | public class ${bean.name}{
10 |
11 | public ${bean.name}(){}
12 |
13 | #foreach ( $field in $bean.getFields() )
14 | private $field.type ${StringUtil.lowerFirstLetter(${field.name})};
15 |
16 | #end
17 | #foreach ( $field in $bean.getFields() )
18 | public void set${field.name}($field.type ${StringUtil.lowerFirstLetter(${field.name})}){
19 | this.${StringUtil.lowerFirstLetter(${field.name})} = ${StringUtil.lowerFirstLetter(${field.name})};
20 | }
21 |
22 | public $field.type get${field.name}(){
23 | return ${StringUtil.lowerFirstLetter(${field.name})};
24 | }
25 | #end
26 |
27 | @Override
28 | public String toString() {
29 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/service/${bean.name}Service.java:
--------------------------------------------------------------------------------
1 | package ${package}.service;
2 |
3 | import ${package}.dao.${bean.name}Dao;
4 | import ${package}.model.${bean.name};
5 | import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
6 | import java.util.List;
7 |
8 | public interface ${bean.name}Service{
9 |
10 | Integer insert(${bean.name} entity);
11 |
12 | Integer update(${bean.name} entity);
13 |
14 | List select(${bean.name} entity,PageBounds pageBounds);
15 |
16 | List<${bean.name}> selectAll();
17 |
18 | Integer delete(${bean.name} entity);
19 | }
20 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/service/impl/${bean.name}ServiceImpl.java:
--------------------------------------------------------------------------------
1 | #define( $dao ) ${StringUtil.lowerFirstLetter(${bean.name})}Dao#end
2 | package ${package}.service.impl;
3 |
4 | import ${package}.dao.${bean.name}Dao;
5 | import ${package}.model.${bean.name};
6 | import ${package}.service.${bean.name}Service;
7 | import com.github.miemiedev.mybatis.paginator.domain.PageBounds;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.stereotype.Service;
10 | import java.util.List;
11 |
12 | @Service("${beanRef}ServiceImpl")
13 | public class ${bean.name}ServiceImpl implements ${bean.name}Service{
14 |
15 | @Autowired
16 | private ${bean.name}Dao ${dao};
17 |
18 | public Integer insert(${bean.name} entity){
19 | return ${dao}.insert(entity);
20 | }
21 |
22 | public Integer update(${bean.name} entity){
23 | return ${dao}.update(entity);
24 | }
25 |
26 | public List select(${bean.name} entity,PageBounds pageBounds){
27 | return ${dao}.select(entity,pageBounds);
28 | }
29 |
30 | public List<${bean.name}> selectAll(){
31 | return ${dao}.selectAll();
32 | }
33 |
34 | public Integer delete(${bean.name} entity){
35 | return ${dao}.delete(entity);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/${package}/util/JsonUtil.java:
--------------------------------------------------------------------------------
1 | package ${package}.util;
2 |
3 | import com.github.miemiedev.mybatis.paginator.domain.PageList;
4 | import com.github.miemiedev.mybatis.paginator.domain.Paginator;
5 | import com.google.gson.*;
6 |
7 | import java.lang.reflect.Type;
8 | import java.util.ArrayList;
9 |
10 | /**
11 | * @author TANG SICHENG
12 | */
13 | public class JsonUtil {
14 |
15 |
16 |
17 | private final static Gson gson;
18 | static {
19 | GsonBuilder gsonBuilder = new GsonBuilder();
20 | gsonBuilder.registerTypeAdapter(PageList.class, new PageListSerialiser());
21 | gson = gsonBuilder.create();
22 | }
23 |
24 |
25 | public static String toJson(Object o){
26 | return gson.toJson(o);
27 | }
28 |
29 | private static class PageListSerialiser implements JsonSerializer {
30 |
31 |
32 | @Override
33 | public JsonElement serialize(PageList pageList, Type type, JsonSerializationContext context) {
34 | final JsonObject jsonObject = new JsonObject();
35 | Paginator paginator = pageList.getPaginator();
36 | jsonObject.addProperty("totalCount", paginator.getTotalCount());
37 | jsonObject.addProperty("totalPages", paginator.getTotalPages());
38 | jsonObject.addProperty("page", paginator.getPage());
39 |
40 | final JsonElement items = context.serialize(new ArrayList(pageList));
41 | jsonObject.add("items", items);
42 |
43 | jsonObject.addProperty("startRow", paginator.getStartRow());
44 | jsonObject.addProperty("endRow", paginator.getEndRow());
45 |
46 | jsonObject.addProperty("offset", paginator.getOffset());
47 |
48 | final JsonArray jsonSlides = new JsonArray();
49 | for (final Integer slide : paginator.getSlider()) {
50 | final JsonPrimitive jsonSlide = new JsonPrimitive(slide);
51 | jsonSlides.add(jsonSlide);
52 | }
53 | jsonObject.add("slider", jsonSlides);
54 |
55 | jsonObject.addProperty("prePage", paginator.getPrePage());
56 | jsonObject.addProperty("nextPage", paginator.getNextPage());
57 |
58 | jsonObject.addProperty("firstPage", paginator.isFirstPage());
59 | jsonObject.addProperty("hasNextPage", paginator.isHasNextPage());
60 | jsonObject.addProperty("hasPrePage", paginator.isHasPrePage());
61 | jsonObject.addProperty("lastPage", paginator.isLastPage());
62 |
63 | return jsonObject;
64 | }
65 | }
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/java/net/sf/log4jdbc/DataSourceSpyInterceptor.java:
--------------------------------------------------------------------------------
1 | package net.sf.log4jdbc;
2 |
3 | import org.aopalliance.intercept.MethodInterceptor;
4 | import org.aopalliance.intercept.MethodInvocation;
5 |
6 | import java.sql.Connection;
7 |
8 | /**
9 | * @author badqiu
10 | */
11 | public class DataSourceSpyInterceptor implements MethodInterceptor {
12 |
13 | private RdbmsSpecifics rdbmsSpecifics = null;
14 |
15 | private RdbmsSpecifics getRdbmsSpecifics(Connection conn) {
16 | if(rdbmsSpecifics == null) {
17 | rdbmsSpecifics = DriverSpy.getRdbmsSpecifics(conn);
18 | }
19 | return rdbmsSpecifics;
20 | }
21 |
22 | public Object invoke(MethodInvocation invocation) throws Throwable {
23 | Object result = invocation.proceed();
24 | if(SpyLogFactory.getSpyLogDelegator().isJdbcLoggingEnabled()) {
25 | if(result instanceof Connection) {
26 | Connection conn = (Connection)result;
27 | return new ConnectionSpy(conn,DriverSpy.getRdbmsSpecifics(conn));
28 | }
29 | }
30 | return result;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,stdout,FILE
2 |
3 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
4 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
5 | log4j.appender.stdout.layout.conversionPattern= %d [%t] %-p %x %m%n
6 |
7 |
8 | log4j.appender.FILE = org.apache.log4j.DailyRollingFileAppender
9 | log4j.appender.FILE.File = /data/logs/${artifactId}.log
10 | log4j.appender.FILE.Append = true
11 | log4j.appender.FILE.encoding = UTF-8
12 | log4j.appender.FILE.layout = org.apache.log4j.PatternLayout
13 | log4j.appender.FILE.MaxBackupIndex = 3
14 | log4j.appender.FILE.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
15 |
16 | log4j.logger.org.springframework=INFO
17 |
18 | log4j.logger.jdbc.sqlonly = INFO
19 | log4j.logger.jdbc.sqltiming = OFF
20 | log4j.logger.jdbc.audit = OFF
21 | log4j.logger.jdbc.resultset = OFF
22 | log4j.logger.jdbc.connection = ERROR
23 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/mappers/${bean.name}Mapper.xml:
--------------------------------------------------------------------------------
1 | #set( $empty = '' )
2 | #define( $beanClass )${package}.model.${bean.name}#end
3 | #define( $daoClass )${config.basePackage}.dao.${bean.name}Dao#end
4 |
5 |
6 |
7 |
8 |
9 |
10 | #foreach ( $relation in ${relations.getRelations()} )
11 | ${relation.column.name} as ${StringUtil.lowerFirstLetter(${relation.field.name})}#if($foreach.hasNext),#end$empty
12 | #end
13 |
14 |
15 |
16 |
17 | #foreach ( $relation in ${relations.getRelations()} )
18 |
19 | and ${relation.column.name} = #{${StringUtil.lowerFirstLetter(${relation.field.name})}}
20 |
21 | #end$empty
22 |
23 |
24 |
25 |
28 |
29 |
30 |
34 |
35 |
36 | delete from ${table.name}
37 |
38 |
39 |
40 |
41 | UPDATE ${table.name} SET
42 | #foreach ( $relation in ${relations.getRelations()} )
43 |
44 | ${relation.column.name}=#{${StringUtil.lowerFirstLetter(${relation.field.name})},jdbyType=${relation.column.type}},
45 |
46 | #end
47 |
48 |
49 |
50 |
51 |
52 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/mybatis/mybatis.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
17 |
18 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/spring/application-context.xml:
--------------------------------------------------------------------------------
1 | #set( $symbol_pound = '#' )
2 | #set( $symbol_dollar = '$' )
3 | #set( $symbol_escape = '\' )
4 |
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/spring/application-datasource.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
35 |
36 |
38 |
39 |
40 | log4jdbcInterceptor
41 |
42 |
43 |
44 |
45 | dataSource
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/spring/application-mybatis.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 | classpath:mappers/*Mapper.xml
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/resources/spring/application-servlet.xml:
--------------------------------------------------------------------------------
1 | #set( $symbol_pound = '#' )
2 | #set( $symbol_dollar = '$' )
3 | #set( $symbol_escape = '\' )
4 |
5 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/webapp/WEB-INF/jetty-web.xml:
--------------------------------------------------------------------------------
1 | #set( $symbol_pound = '#' )
2 | #set( $symbol_dollar = '$' )
3 | #set( $symbol_escape = '\' )
4 |
5 |
6 |
7 |
16 |
17 |
18 |
19 | /
20 | 200000
21 | true
22 | false
23 |
24 |
25 | - 127.0.0.1
26 | - localhost
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/example/src/main/resources/SimpleExample/src/main/webapp/WEB-INF/web.xml:
--------------------------------------------------------------------------------
1 | #set( $symbol_pound = '#' )
2 | #set( $symbol_dollar = '$' )
3 | #set( $symbol_escape = '\' )
4 |
5 |
9 | ${artifactId}
10 |
11 | SessionFilter
12 | com.meizu.framework.impl.servlet.SessionFilter
13 |
14 | IgnoreContent
15 | js,css,jpg,png,gif,swf,bmp,ico
16 |
17 |
18 |
19 | SessionFilter
20 | /*
21 |
22 |
23 | EncodingFilter
24 | org.springframework.web.filter.CharacterEncodingFilter
25 |
26 | encoding
27 | UTF-8
28 |
29 |
30 | forceEncoding
31 | true
32 |
33 |
34 |
35 | EncodingFilter
36 | /*
37 |
38 |
39 | log4jConfigLocation
40 | classpath:log4j.properties
41 |
42 |
43 | contextConfigLocation
44 | classpath:spring/application-context.xml
45 |
46 |
47 | org.springframework.web.util.Log4jConfigListener
48 |
49 |
50 | org.springframework.web.context.request.RequestContextListener
51 |
52 |
53 | com.meizu.framework.impl.container.WebContextLoaderListener
54 |
55 |
56 | dispatcher
57 | org.springframework.web.servlet.DispatcherServlet
58 |
59 | contextConfigLocation
60 | classpath:spring/application-context.xml
61 |
62 | 1
63 |
64 |
65 | dispatcher
66 | /
67 |
68 |
69 | index.html
70 |
71 |
72 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.github.jadetang
8 | maliang
9 | jar
10 | 1.0-SNAPSHOT
11 |
12 |
13 |
14 | org.apache.velocity
15 | velocity
16 | 1.7
17 |
18 |
19 | com.github.jsqlparser
20 | jsqlparser
21 | 0.9
22 |
23 |
24 | com.google.guava
25 | guava
26 | 29.0-jre
27 |
28 |
29 | com.typesafe
30 | config
31 | 1.2.1
32 |
33 |
34 |
35 |
36 | org.slf4j
37 | slf4j-api
38 | 1.6.1
39 |
40 |
41 | org.slf4j
42 | slf4j-log4j12
43 | 1.6.1
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | org.apache.maven.plugins
52 | maven-compiler-plugin
53 | 2.3.2
54 |
55 | 1.7
56 | 1.7
57 | UTF-8
58 |
59 |
60 |
61 | maven-source-plugin
62 | 2.2.1
63 |
64 | true
65 |
66 |
67 |
68 | compile
69 |
70 | jar
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/MEngine.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang;
2 |
3 | import com.typesafe.config.Config;
4 | import com.typesafe.config.ConfigFactory;
5 | import github.jadetang.maliang.bean.JavaDataBaseRelation;
6 | import github.jadetang.maliang.builder.ContextBuilder;
7 | import github.jadetang.maliang.builder.JavaDataBaseRelationBuilder;
8 | import github.jadetang.maliang.builder.SourceCodeGenerator;
9 | import github.jadetang.maliang.conf.MConfig;
10 | import org.apache.velocity.VelocityContext;
11 |
12 | import java.io.File;
13 | import java.io.IOException;
14 | import java.util.List;
15 | import java.util.Properties;
16 |
17 | /**
18 | * @Author Tang Sicheng
19 | */
20 | public class MEngine {
21 |
22 | private MConfig mConfig;
23 | private JavaDataBaseRelationBuilder javaObjectBuilder;
24 | private SourceCodeGenerator generator;
25 |
26 | /**
27 | * Construct an instance with default configuration
28 | */
29 | public MEngine() {
30 | this(ConfigFactory.empty());
31 | }
32 |
33 | /**
34 | * Construct an instance with custom properties
35 | * @param properties custom properties
36 | */
37 | public MEngine(Properties properties) {
38 | this(ConfigFactory.parseProperties(properties));
39 | }
40 |
41 | /**
42 | * Construct an instance with custom properties written in file
43 | * @param file
44 | */
45 | public MEngine(File file){
46 | this(ConfigFactory.parseFile(file));
47 | }
48 |
49 |
50 | public MEngine(Config config) {
51 | Config defaultConfig = ConfigFactory.load();
52 | mConfig = new MConfig(config.withFallback(defaultConfig));
53 | javaObjectBuilder = new JavaDataBaseRelationBuilder(mConfig);
54 | generator = new SourceCodeGenerator(mConfig);
55 | }
56 |
57 |
58 | public void generateCode(String createStatement) throws IOException {
59 | List relations = javaObjectBuilder.parserMulit(createStatement);
60 | generator.init();
61 | for (JavaDataBaseRelation relation : relations) {
62 | VelocityContext context = ContextBuilder.build(relation, mConfig);
63 | generator.generate(context);
64 | }
65 | }
66 |
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/Column.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | import org.apache.commons.lang.builder.ToStringBuilder;
4 | import org.apache.commons.lang.builder.ToStringStyle;
5 |
6 | /**
7 | * @Author Tang Sicheng
8 | */
9 | public class Column {
10 |
11 | private String name;
12 |
13 | private String type;
14 |
15 | public String getName() {
16 | return name.toUpperCase();
17 | }
18 |
19 | public void setName(String name) {
20 | this.name = name;
21 | }
22 |
23 | public String getType() {
24 | return type;
25 | }
26 |
27 | public void setType(String type) {
28 | this.type = type;
29 | }
30 |
31 | private Column(){}
32 |
33 | private Column(ColumnBuilder builder){
34 | this.name = builder.name;
35 | this.type = builder.type;
36 | }
37 |
38 | public static class ColumnBuilder{
39 | private String name;
40 | private String type;
41 | public ColumnBuilder(){}
42 |
43 | public ColumnBuilder withName(String name){
44 | this.name = name;
45 | return this;
46 | }
47 |
48 | public ColumnBuilder withType(String type){
49 | this.type = type;
50 | return this;
51 | }
52 |
53 | public Column build(){
54 | return new Column(this);
55 | }
56 | }
57 |
58 | @Override
59 | public String toString() {
60 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/JavaClass.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | import org.apache.commons.lang.builder.ToStringBuilder;
4 | import org.apache.commons.lang.builder.ToStringStyle;
5 |
6 | import java.util.LinkedList;
7 |
8 | /**
9 | * @author TANG SICHENG
10 | */
11 | public class JavaClass {
12 |
13 | private String name;
14 |
15 | private LinkedList fields;
16 |
17 | private JavaClass() {
18 | }
19 |
20 | private JavaClass(JavaClassBuilder builder) {
21 | this.name = builder.name;
22 | this.fields = builder.javaFields;
23 | }
24 |
25 | public String getName() {
26 | return name;
27 | }
28 |
29 | public LinkedList getFields() {
30 | return fields;
31 | }
32 |
33 | @Override
34 | public String toString() {
35 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
36 | }
37 |
38 | public static class JavaClassBuilder {
39 |
40 | private String name;
41 | private LinkedList javaFields;
42 |
43 | public JavaClassBuilder() {
44 | }
45 |
46 | public JavaClassBuilder withName(String name) {
47 | JavaClassBuilder.this.name = name;
48 | return this;
49 | }
50 |
51 | public JavaClassBuilder withFields(LinkedList fields) {
52 | JavaClassBuilder.this.javaFields = new LinkedList(fields);
53 | return this;
54 | }
55 |
56 | public JavaClass build() {
57 | return new JavaClass(this);
58 | }
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/JavaDataBaseRelation.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | import com.google.common.collect.Lists;
4 |
5 | import java.util.LinkedList;
6 |
7 | /**
8 | * @author TANG SICHENG
9 | */
10 | public class JavaDataBaseRelation {
11 |
12 | private JavaClass bean;
13 | private Table table;
14 | private LinkedList relations;
15 |
16 | public JavaDataBaseRelation(JavaClass bean,Table table){
17 | this.bean = bean;
18 | this.table = table;
19 | this.relations = getRelations(bean,table);
20 | }
21 |
22 | private LinkedList getRelations(JavaClass bean, Table table) {
23 | LinkedList relations = Lists.newLinkedList();
24 | assert bean.getFields().size() == table.getColumns().size();
25 | int length = bean.getFields().size();
26 | for (int i = 0; i < length; i++) {
27 | relations.add(new Relation(bean.getFields().get(i),table.getColumns().get(i)));
28 | }
29 | return relations;
30 | }
31 |
32 | public JavaClass getBean() {
33 | return bean;
34 | }
35 |
36 | public void setBean(JavaClass bean) {
37 | this.bean = bean;
38 | }
39 |
40 | public Table getTable() {
41 | return table;
42 | }
43 |
44 | public void setTable(Table table) {
45 | this.table = table;
46 | }
47 |
48 | public LinkedList getRelations() {
49 | return relations;
50 | }
51 |
52 | public void setRelations(LinkedList relations) {
53 | this.relations = relations;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/JavaField.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | import org.apache.commons.lang.builder.ToStringBuilder;
4 | import org.apache.commons.lang.builder.ToStringStyle;
5 |
6 |
7 | /**
8 | * @author TANG SICHENG
9 | */
10 | public class JavaField {
11 |
12 | private String name;
13 |
14 | /**
15 | * represent a field type like Integer,Double,etc
16 | */
17 | private String type;
18 |
19 | private JavaField(){}
20 |
21 | private JavaField(JavaFieldBuilder javaFieldBuilder){
22 | this.name = javaFieldBuilder.name;
23 | this.type = javaFieldBuilder.type;
24 | }
25 |
26 | public String getName() {
27 | return name;
28 | }
29 |
30 | public String getType() {
31 | return type;
32 | }
33 |
34 | @Override
35 | public String toString(){
36 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
37 | }
38 |
39 | public static class JavaFieldBuilder{
40 | private String name;
41 | private String type;
42 |
43 | public JavaFieldBuilder(){}
44 |
45 | public JavaFieldBuilder withName(String name){
46 | JavaFieldBuilder.this.name = name;
47 | return this;
48 | }
49 |
50 | public JavaFieldBuilder withType(String type){
51 | JavaFieldBuilder.this.type = type;
52 | return this;
53 | }
54 |
55 | public JavaField build(){
56 | return new JavaField(this);
57 | }
58 |
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/Relation.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | /**
4 | * @author TANG SICHENG
5 | */
6 | public class Relation extends Tuple {
7 |
8 | private JavaField field;
9 |
10 | private Column column;
11 |
12 | public Relation(JavaField first, Column second) {
13 | super(first, second);
14 | this.field = first;
15 | this.column = second;
16 | }
17 |
18 | public JavaField bean(){
19 | return super._1();
20 | }
21 |
22 | public Column table(){
23 | return super._2();
24 | }
25 |
26 | public JavaField getField() {
27 | return field;
28 | }
29 |
30 | public void setField(JavaField field) {
31 | this.field = field;
32 | }
33 |
34 | public Column getColumn() {
35 | return column;
36 | }
37 |
38 | public void setColumn(Column column) {
39 | this.column = column;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/Table.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | import com.google.common.collect.Lists;
4 | import org.apache.commons.lang.builder.ToStringBuilder;
5 | import org.apache.commons.lang.builder.ToStringStyle;
6 |
7 | import java.util.LinkedList;
8 |
9 | /**
10 | * A simple pojo representing a table in database
11 | * @Author Tang Sicheng
12 | */
13 | public class Table {
14 |
15 | private String name;
16 |
17 | private LinkedList columns;
18 |
19 | public String getName() {
20 | return name.toUpperCase();
21 | }
22 |
23 | public void setName(String name) {
24 | this.name = name;
25 | }
26 |
27 | public LinkedList getColumns() {
28 | return columns;
29 | }
30 |
31 | public void setColumns(LinkedList columns) {
32 | this.columns = columns;
33 | }
34 |
35 | private Table(){}
36 |
37 | private Table(TableBuilder builder){
38 | this.name = builder.name;
39 | this.columns = Lists.newLinkedList(builder.columns);
40 | }
41 |
42 | public static class TableBuilder{
43 | private String name;
44 |
45 | private LinkedList columns;
46 |
47 | public TableBuilder(){}
48 |
49 | public TableBuilder withName(String name){
50 | this.name = name;
51 | return this;
52 | }
53 |
54 | public TableBuilder withColumns(LinkedList columns){
55 | this.columns = Lists.newLinkedList(columns);
56 | return this;
57 | }
58 |
59 | public Table build(){
60 | return new Table(this);
61 | }
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/bean/Tuple.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.bean;
2 |
3 | /**
4 | * @Author Tang Sicheng
5 | */
6 | public class Tuple {
7 | private T first;
8 | private S second;
9 |
10 | public Tuple(T first, S second) {
11 | this.first = first;
12 | this.second = second;
13 | }
14 |
15 | public T _1() {
16 | return first;
17 | }
18 |
19 | public S _2() {
20 | return second;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/builder/ContextBuilder.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.builder;
2 |
3 | import github.jadetang.maliang.bean.JavaDataBaseRelation;
4 | import github.jadetang.maliang.conf.MConfig;
5 | import github.jadetang.maliang.util.ContextUtil;
6 | import org.apache.velocity.VelocityContext;
7 |
8 | /**
9 | * @Author Tang Sicheng
10 | */
11 | public class ContextBuilder {
12 |
13 | /**
14 | * populate a {@link org.apache.velocity.VelocityContext}
15 | * @param relation
16 | * @return
17 | */
18 | public static VelocityContext build(JavaDataBaseRelation relation,MConfig config){
19 | VelocityContext context = new VelocityContext();
20 | context.put("bean", relation.getBean());
21 | context.put("table",relation.getTable());
22 | context.put("relations",relation);
23 | context.put("config",config);
24 | context.put("groupId",config.getGroupId());
25 | context.put("artifactId",config.getArtifactId());
26 | context.put("version",config.getVersion());
27 | context.put("package",config.getBasePackage());
28 | context.put("StringUtil", ContextUtil.newWrapper());
29 | return context;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/builder/JavaDataBaseRelationBuilder.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.builder;
2 |
3 | import com.google.common.base.Function;
4 | import com.google.common.base.Joiner;
5 | import com.google.common.base.Splitter;
6 | import com.google.common.collect.Lists;
7 | import github.jadetang.maliang.bean.*;
8 | import github.jadetang.maliang.bean.JavaClass.JavaClassBuilder;
9 | import github.jadetang.maliang.bean.JavaField.JavaFieldBuilder;
10 | import github.jadetang.maliang.conf.MConfig;
11 | import github.jadetang.maliang.exception.MaliangException;
12 | import github.jadetang.maliang.util.ContextUtil;
13 | import net.sf.jsqlparser.JSQLParserException;
14 | import net.sf.jsqlparser.parser.CCJSqlParserUtil;
15 | import net.sf.jsqlparser.statement.Statement;
16 | import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
17 | import net.sf.jsqlparser.statement.create.table.CreateTable;
18 | import org.apache.commons.lang.StringUtils;
19 |
20 | import java.util.LinkedList;
21 | import java.util.List;
22 |
23 | /**
24 | * using jsqlparser to parser a create table
25 | * then convert the result to {@link github.jadetang.maliang.bean.JavaDataBaseRelation}
26 | * @author TANG SICHENG
27 | */
28 | public class JavaDataBaseRelationBuilder {
29 |
30 | private MConfig mConfig;
31 |
32 | public JavaDataBaseRelationBuilder(MConfig mConfig) {
33 | this.mConfig = mConfig;
34 | this.tablePrefix = mConfig.getTablePrefix();
35 | this.columnPrefix = mConfig.getColumnPrefix();
36 | this.separator = mConfig.getSeparator();
37 | }
38 |
39 | private String tablePrefix;
40 |
41 | private String separator;
42 |
43 | private String columnPrefix;
44 |
45 |
46 | private Tuple parseToTuple(String createSQL) {
47 | try {
48 | Statement statement = CCJSqlParserUtil.parse(createSQL);
49 | if (statement instanceof CreateTable) {
50 | JavaClass javaClass= buildJavaClass((CreateTable) statement);
51 | Table table = buildTable((CreateTable) statement);
52 | return new Tuple<>(javaClass,table);
53 | } else {
54 | throw new MaliangException("only accept create statement");
55 | }
56 | } catch (JSQLParserException e) {
57 | throw new MaliangException(e);
58 |
59 | }
60 | }
61 |
62 |
63 | public JavaDataBaseRelation parser(String createSQL){
64 | Tuple tuple = parseToTuple(createSQL);
65 | return new JavaDataBaseRelation(tuple._1(),tuple._2());
66 | }
67 |
68 |
69 |
70 |
71 | public List parserMulit(String createSQLs){
72 | List sqls = Lists.newLinkedList(Splitter.on(";").omitEmptyStrings().trimResults().split(createSQLs));
73 | return Lists.transform(sqls, new Function() {
74 | public JavaDataBaseRelation apply(String input) {
75 | return parser(input);
76 | }
77 | });
78 | }
79 |
80 |
81 |
82 | private Table buildTable(CreateTable createStatement) {
83 | Table.TableBuilder tableBuilder = new Table.TableBuilder();
84 | tableBuilder.withName(createStatement.getTable().getName().toUpperCase());
85 | tableBuilder.withColumns(extractColumns(createStatement));
86 | return tableBuilder.build();
87 | }
88 |
89 | private LinkedList extractColumns(CreateTable createStatement) {
90 | LinkedList columns = Lists.newLinkedList();
91 | List columnDefinitions = createStatement.getColumnDefinitions();
92 | for (ColumnDefinition c:columnDefinitions){
93 | Column.ColumnBuilder cBuilder = new Column.ColumnBuilder();
94 | cBuilder.withName(c.getColumnName().toUpperCase());
95 | cBuilder.withType(c.getColDataType().getDataType());
96 | columns.add(cBuilder.build());
97 | }
98 | return columns;
99 | }
100 |
101 | private JavaClass buildJavaClass(CreateTable createStatement) {
102 | JavaClassBuilder jBuilder = new JavaClassBuilder();
103 | String tableName = createStatement.getTable().getName();
104 | String javaClassName = transformName(tableName,tablePrefix,separator);
105 | jBuilder.withName(javaClassName);
106 | jBuilder.withFields(extractFields(createStatement));
107 | return jBuilder.build();
108 | }
109 |
110 | /**
111 | * transform a database name to a java name,for example, a table in database called
112 | * T_APP_USER,then with prefix T
113 | * @param originName database object name
114 | * @param prefix database object name prefix
115 | * @param separator database object separator
116 | * @return
117 | */
118 | private String transformName(String originName,String prefix,String separator){
119 | if(StringUtils.isNotBlank(originName)){
120 | originName = StringUtils.removeStart(originName,prefix);
121 | }
122 | if(StringUtils.isNotBlank(separator)){
123 | List names = Splitter.on(separator).omitEmptyStrings().trimResults().splitToList(originName);
124 | List javaStyleNames = Lists.transform(names, new Function() {
125 | public String apply(String input) {
126 | return ContextUtil.onlyFirstLetterIsUp(input);
127 | }
128 | });
129 | originName = Joiner.on("").join(javaStyleNames);
130 | }else {
131 | originName = ContextUtil.onlyFirstLetterIsUp(originName);
132 | }
133 | return ContextUtil.upperFirstLetter(originName);
134 | }
135 |
136 | private LinkedList extractFields(CreateTable createStatement) {
137 | LinkedList javaFields = Lists.newLinkedList();
138 | List columnDefinitions = createStatement.getColumnDefinitions();
139 | for (ColumnDefinition c:columnDefinitions){
140 | javaFields.add(convertColumnToField(c));
141 | }
142 | return javaFields;
143 | }
144 |
145 | private JavaField convertColumnToField(ColumnDefinition columnDefinition){
146 | JavaFieldBuilder jfBuilder = new JavaFieldBuilder();
147 | String columnName = columnDefinition.getColumnName();
148 | String javaFieldName = transformName(columnName,columnPrefix,separator);
149 | jfBuilder.withName(javaFieldName);
150 | String javaType = mConfig.getJavaType(columnDefinition.getColDataType().getDataType());
151 | jfBuilder.withType(javaType);
152 | return jfBuilder.build();
153 | }
154 |
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/builder/SourceCodeGenerator.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.builder;
2 |
3 | import github.jadetang.maliang.conf.MConfig;
4 | import github.jadetang.maliang.exception.MaliangException;
5 | import github.jadetang.maliang.util.FileUtil;
6 | import org.apache.velocity.Template;
7 | import org.apache.velocity.VelocityContext;
8 | import org.apache.velocity.app.VelocityEngine;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import java.io.*;
13 | import java.nio.file.DirectoryStream;
14 | import java.nio.file.Files;
15 | import java.nio.file.Path;
16 | import java.nio.file.Paths;
17 | import java.nio.file.attribute.FileAttribute;
18 | import java.util.regex.Matcher;
19 | import java.util.regex.Pattern;
20 |
21 | /**
22 | * @Author Tang Sicheng
23 | */
24 | public class SourceCodeGenerator {
25 |
26 |
27 | private static Logger log = LoggerFactory.getLogger(SourceCodeGenerator.class);
28 |
29 |
30 | private String templatePathStr;
31 | private String outPutPath;
32 | private MConfig config;
33 | private VelocityEngine ve;
34 | private Path templatePath;
35 | private boolean ready = false;
36 |
37 | public SourceCodeGenerator(MConfig mConfig) {
38 | this.config = mConfig;
39 | this.templatePathStr = config.getTemplateDir();
40 | this.templatePath = Paths.get(templatePathStr);
41 | this.outPutPath = config.getOutputDir();
42 | }
43 |
44 | public void init() throws IOException {
45 | initEngine();
46 | FileUtil.delDirectory(outPutPath);
47 | ready = true;
48 | }
49 |
50 |
51 | private void initEngine() {
52 | ve = new VelocityEngine();
53 | ve.setProperty(ve.FILE_RESOURCE_LOADER_PATH, templatePathStr);
54 | }
55 |
56 | public void generate(VelocityContext context) throws IOException {
57 | if (!ready) {
58 | throw new MaliangException("should call init before");
59 | }
60 | Path outputPath = Paths.get(outPutPath);
61 | driver(templatePath, outputPath, context);
62 | ve.setProperty(ve.FILE_RESOURCE_LOADER_PATH, templatePath);
63 | }
64 |
65 | private void driver(Path sourcePath, Path desPath, VelocityContext context) throws IOException {
66 | File sourceFile = sourcePath.toFile();
67 | if (!sourceFile.exists()) {
68 | return;
69 | } else if (sourceFile.isDirectory()) {
70 | desPath = newDirPath(desPath, context);
71 | Files.createDirectories( desPath, new FileAttribute[]{});
72 | try (DirectoryStream subPaths = Files.newDirectoryStream(sourcePath)) {
73 | for (Path subPath : subPaths) {
74 | driver(subPath, Paths.get(desPath.toAbsolutePath().toString() + File.separator + subPath.getFileName()), context);
75 | }
76 | }
77 | } else if (sourceFile.isFile()) {
78 | generateCode(sourcePath, desPath.getParent(), context);
79 | }
80 | }
81 |
82 | private void generateCode(Path oriFileName, Path tmpDir, VelocityContext context) throws IOException {
83 | String newFileName = newPathName(oriFileName.getFileName().toString(), context);
84 | String absoluteFileName = tmpDir.toAbsolutePath().toString() + File.separator + newFileName;
85 | if (Paths.get(absoluteFileName).toFile().exists()) {
86 | //the file already exist
87 | return;
88 | } else {
89 | log.debug("FILE_RESOURCE_LOADER_PATH:" + oriFileName.getParent().toAbsolutePath().toString());
90 | log.debug("try find resource:" + templatePath.relativize(oriFileName).toString());
91 | Template template = ve.getTemplate(templatePath.relativize(oriFileName).toString(), "UTF-8");
92 | assert template != null;
93 | Writer writer = null;
94 | try {
95 | writer = new FileWriter(new File(absoluteFileName), false);
96 | template.merge(context, writer);
97 | } finally {
98 | if (writer != null) {
99 | writer.close();
100 | }
101 | }
102 | }
103 | }
104 |
105 | /**
106 | * if the path string has velocity reference like ${bean.name},then replace it with
107 | * the content in the Velocity Context, and replace "." with File.pathSeparator
108 | * @param
109 | * @return
110 | */
111 | private Path newDirPath(Path originPath, VelocityContext context) {
112 | String newPathNameString = newPathName(originPath.toAbsolutePath().toString(), context).replace(".", File.separator);
113 | log.debug("new Path :"+newPathNameString);
114 | return Paths.get(newPathNameString);
115 | }
116 |
117 | /**
118 | * if the pathName has velocity reference like ${bean.name},then replace it with
119 | * the content in the Velocity Context
120 | * @param fileName
121 | * @return
122 | */
123 | private String newPathName(String fileName, VelocityContext context) {
124 | //match ${xxxx}
125 | String patternString = "\\$\\{(.|\\w)+\\}";
126 | Pattern pattern = Pattern.compile(patternString);
127 | Matcher matcher = pattern.matcher(fileName);
128 | while (matcher.find()){
129 | String contextValue = evaluateVTL(matcher.group(), context);
130 | fileName = fileName.replaceFirst(patternString, contextValue);
131 | }
132 | return fileName;
133 | }
134 |
135 | private String evaluateVTL(String contextKey, VelocityContext context) {
136 | try (StringWriter writer = new StringWriter()) {
137 | ve.evaluate(context, writer, "Maliang", contextKey);
138 | return writer.toString();
139 | } catch (IOException e) {
140 | e.printStackTrace();
141 | }
142 | return null;
143 | }
144 |
145 | }
146 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/conf/MConfig.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.conf;
2 |
3 | import com.google.common.collect.Maps;
4 | import com.typesafe.config.Config;
5 | import com.typesafe.config.ConfigFactory;
6 | import com.typesafe.config.ConfigValue;
7 |
8 | import java.util.Map;
9 | import java.util.Set;
10 |
11 | /**
12 | * @author TANG SICHENG
13 | */
14 | public class MConfig {
15 |
16 | private String groupId;
17 |
18 | private String artifactId;
19 |
20 | private String version;
21 |
22 | private String basePackage;
23 |
24 | private Config config;
25 |
26 | private Map typeMap;
27 |
28 |
29 | public String getJavaType(String sqlType) {
30 | return typeMap.get(sqlType.toUpperCase());
31 | }
32 |
33 | public MConfig(Config config) {
34 | config.checkValid(ConfigFactory.defaultReference(), "maven");
35 | this.groupId = config.getString("maven.groupId");
36 | this.artifactId = config.getString("maven.artifactId");
37 | this.version = config.getString("maven.version");
38 | this.basePackage = config.getString("maven.package");
39 | this.typeMap = buildMap(config.getConfig("database.type"));
40 | this.config = config;
41 | }
42 |
43 | private Map buildMap(Config config) {
44 | Set> entrySet = config.entrySet();
45 | Map m = Maps.newHashMap();
46 | for (Map.Entry e : entrySet) {
47 | m.put(e.getKey(), String.valueOf(e.getValue().unwrapped()));
48 | }
49 | return m;
50 | }
51 |
52 | public String getVersion() {
53 | return version;
54 | }
55 |
56 | public String getArtifactId() {
57 | return artifactId;
58 | }
59 |
60 | public String getGroupId() {
61 | return groupId;
62 | }
63 |
64 | public String getBasePackage() {
65 | return basePackage;
66 | }
67 |
68 | public void setBasePackage(String basePackage) {
69 | this.basePackage = basePackage;
70 | }
71 |
72 | public String getOutputDir() {
73 | return this.config.getString("dir.output");
74 | }
75 |
76 | public String getTemplateDir() {
77 | return this.config.getString("dir.template");
78 | }
79 |
80 | public String getTablePrefix() {
81 | return this.config.getString("name.table.prefix");
82 | }
83 |
84 | public String getSeparator() {
85 | return this.config.getString("name.separator");
86 | }
87 |
88 | public String getColumnPrefix() {
89 | return this.config.getString("name.column.prefix");
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/exception/MaliangException.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.exception;/**
2 | * Created by tangsicheng on 2015/9/18.
3 | */
4 |
5 | /**
6 | * @author TANG SICHENG
7 | */
8 | public class MaliangException extends RuntimeException {
9 |
10 | static final long serialVersionUID = -7034897190745766938L;
11 |
12 | public MaliangException() {
13 | super();
14 | }
15 |
16 | public MaliangException(String message) {
17 | super(message);
18 | }
19 |
20 |
21 | public MaliangException(String message, Throwable cause) {
22 | super(message, cause);
23 | }
24 |
25 | public MaliangException(Throwable cause) {
26 | super(cause);
27 | }
28 |
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/resource/ClassLoaderWrapper.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2009-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package github.jadetang.maliang.resource;
17 |
18 | import java.io.InputStream;
19 | import java.net.URL;
20 |
21 | /**
22 | * A class to wrap access to multiple class loaders making them work as one
23 | * @author Clinton Begin
24 | * copy from https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/io/ClassLoaderWrapper.java
25 | */
26 | public class ClassLoaderWrapper {
27 |
28 | ClassLoader defaultClassLoader;
29 | ClassLoader systemClassLoader;
30 |
31 | ClassLoaderWrapper() {
32 | try {
33 | systemClassLoader = ClassLoader.getSystemClassLoader();
34 | } catch (SecurityException ignored) {
35 | // AccessControlException on Google App Engine
36 | }
37 | }
38 |
39 | /*
40 | * Get a resource as a URL using the current class path
41 | *
42 | * @param resource - the resource to locate
43 | * @return the resource or null
44 | */
45 | public URL getResourceAsURL(String resource) {
46 | return getResourceAsURL(resource, getClassLoaders(null));
47 | }
48 |
49 | /*
50 | * Get a resource from the classpath, starting with a specific class loader
51 | *
52 | * @param resource - the resource to find
53 | * @param classLoader - the first classloader to try
54 | * @return the stream or null
55 | */
56 | public URL getResourceAsURL(String resource, ClassLoader classLoader) {
57 | return getResourceAsURL(resource, getClassLoaders(classLoader));
58 | }
59 |
60 | /*
61 | * Get a resource from the classpath
62 | *
63 | * @param resource - the resource to find
64 | * @return the stream or null
65 | */
66 | public InputStream getResourceAsStream(String resource) {
67 | return getResourceAsStream(resource, getClassLoaders(null));
68 | }
69 |
70 | /*
71 | * Get a resource from the classpath, starting with a specific class loader
72 | *
73 | * @param resource - the resource to find
74 | * @param classLoader - the first class loader to try
75 | * @return the stream or null
76 | */
77 | public InputStream getResourceAsStream(String resource, ClassLoader classLoader) {
78 | return getResourceAsStream(resource, getClassLoaders(classLoader));
79 | }
80 |
81 | /*
82 | * Find a class on the classpath (or die trying)
83 | *
84 | * @param name - the class to look for
85 | * @return - the class
86 | * @throws ClassNotFoundException Duh.
87 | */
88 | public Class> classForName(String name) throws ClassNotFoundException {
89 | return classForName(name, getClassLoaders(null));
90 | }
91 |
92 | /*
93 | * Find a class on the classpath, starting with a specific classloader (or die trying)
94 | *
95 | * @param name - the class to look for
96 | * @param classLoader - the first classloader to try
97 | * @return - the class
98 | * @throws ClassNotFoundException Duh.
99 | */
100 | public Class> classForName(String name, ClassLoader classLoader) throws ClassNotFoundException {
101 | return classForName(name, getClassLoaders(classLoader));
102 | }
103 |
104 | /*
105 | * Try to get a resource from a group of classloaders
106 | *
107 | * @param resource - the resource to get
108 | * @param classLoader - the classloaders to examine
109 | * @return the resource or null
110 | */
111 | InputStream getResourceAsStream(String resource, ClassLoader[] classLoader) {
112 | for (ClassLoader cl : classLoader) {
113 | if (null != cl) {
114 |
115 | // try to find the resource as passed
116 | InputStream returnValue = cl.getResourceAsStream(resource);
117 |
118 | // now, some class loaders want this leading "/", so we'll add it and try again if we didn't find the resource
119 | if (null == returnValue) {
120 | returnValue = cl.getResourceAsStream("/" + resource);
121 | }
122 |
123 | if (null != returnValue) {
124 | return returnValue;
125 | }
126 | }
127 | }
128 | return null;
129 | }
130 |
131 | /*
132 | * Get a resource as a URL using the current class path
133 | *
134 | * @param resource - the resource to locate
135 | * @param classLoader - the class loaders to examine
136 | * @return the resource or null
137 | */
138 | URL getResourceAsURL(String resource, ClassLoader[] classLoader) {
139 |
140 | URL url;
141 |
142 | for (ClassLoader cl : classLoader) {
143 |
144 | if (null != cl) {
145 |
146 | // look for the resource as passed in...
147 | url = cl.getResource(resource);
148 |
149 | // ...but some class loaders want this leading "/", so we'll add it
150 | // and try again if we didn't find the resource
151 | if (null == url) {
152 | url = cl.getResource("/" + resource);
153 | }
154 |
155 | // "It's always in the last place I look for it!"
156 | // ... because only an idiot would keep looking for it after finding it, so stop looking already.
157 | if (null != url) {
158 | return url;
159 | }
160 |
161 | }
162 |
163 | }
164 |
165 | // didn't find it anywhere.
166 | return null;
167 |
168 | }
169 |
170 | /*
171 | * Attempt to load a class from a group of classloaders
172 | *
173 | * @param name - the class to load
174 | * @param classLoader - the group of classloaders to examine
175 | * @return the class
176 | * @throws ClassNotFoundException - Remember the wisdom of Judge Smails: Well, the world needs ditch diggers, too.
177 | */
178 | Class> classForName(String name, ClassLoader[] classLoader) throws ClassNotFoundException {
179 |
180 | for (ClassLoader cl : classLoader) {
181 |
182 | if (null != cl) {
183 |
184 | try {
185 |
186 | Class> c = Class.forName(name, true, cl);
187 |
188 | if (null != c) {
189 | return c;
190 | }
191 |
192 | } catch (ClassNotFoundException e) {
193 | // we'll ignore this until all classloaders fail to locate the class
194 | }
195 |
196 | }
197 |
198 | }
199 |
200 | throw new ClassNotFoundException("Cannot find class: " + name);
201 |
202 | }
203 |
204 | ClassLoader[] getClassLoaders(ClassLoader classLoader) {
205 | return new ClassLoader[]{
206 | classLoader,
207 | defaultClassLoader,
208 | Thread.currentThread().getContextClassLoader(),
209 | getClass().getClassLoader(),
210 | systemClassLoader};
211 | }
212 |
213 | }
214 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/resource/Resources.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2009-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package github.jadetang.maliang.resource;
17 |
18 | import java.io.File;
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.io.InputStreamReader;
22 | import java.io.Reader;
23 | import java.net.URL;
24 | import java.net.URLConnection;
25 | import java.nio.charset.Charset;
26 | import java.util.Properties;
27 |
28 | /**
29 | * A class to simplify access to resources through the classloader.
30 | * @author Clinton Begin
31 | * copy from https://github.com/mybatis/mybatis-3/blob/master/src/main/java/org/apache/ibatis/io/Resources.java
32 | *
33 | */
34 | public class Resources {
35 |
36 | private static ClassLoaderWrapper classLoaderWrapper = new ClassLoaderWrapper();
37 |
38 | /*
39 | * Charset to use when calling getResourceAsReader.
40 | * null means use the system default.
41 | */
42 | private static Charset charset;
43 |
44 | Resources() {
45 | }
46 |
47 | /*
48 | * Returns the default classloader (may be null).
49 | *
50 | * @return The default classloader
51 | */
52 | public static ClassLoader getDefaultClassLoader() {
53 | return classLoaderWrapper.defaultClassLoader;
54 | }
55 |
56 | /*
57 | * Sets the default classloader
58 | *
59 | * @param defaultClassLoader - the new default ClassLoader
60 | */
61 | public static void setDefaultClassLoader(ClassLoader defaultClassLoader) {
62 | classLoaderWrapper.defaultClassLoader = defaultClassLoader;
63 | }
64 |
65 | /*
66 | * Returns the URL of the resource on the classpath
67 | *
68 | * @param resource The resource to find
69 | * @return The resource
70 | * @throws java.io.IOException If the resource cannot be found or read
71 | */
72 | public static URL getResourceURL(String resource) throws IOException {
73 | // issue #625
74 | return getResourceURL(null, resource);
75 | }
76 |
77 | /*
78 | * Returns the URL of the resource on the classpath
79 | *
80 | * @param loader The classloader used to fetch the resource
81 | * @param resource The resource to find
82 | * @return The resource
83 | * @throws java.io.IOException If the resource cannot be found or read
84 | */
85 | public static URL getResourceURL(ClassLoader loader, String resource) throws IOException {
86 | URL url = classLoaderWrapper.getResourceAsURL(resource, loader);
87 | if (url == null) {
88 | throw new IOException("Could not find resource " + resource);
89 | }
90 | return url;
91 | }
92 |
93 | /*
94 | * Returns a resource on the classpath as a Stream object
95 | *
96 | * @param resource The resource to find
97 | * @return The resource
98 | * @throws java.io.IOException If the resource cannot be found or read
99 | */
100 | public static InputStream getResourceAsStream(String resource) throws IOException {
101 | return getResourceAsStream(null, resource);
102 | }
103 |
104 | /*
105 | * Returns a resource on the classpath as a Stream object
106 | *
107 | * @param loader The classloader used to fetch the resource
108 | * @param resource The resource to find
109 | * @return The resource
110 | * @throws java.io.IOException If the resource cannot be found or read
111 | */
112 | public static InputStream getResourceAsStream(ClassLoader loader, String resource) throws IOException {
113 | InputStream in = classLoaderWrapper.getResourceAsStream(resource, loader);
114 | if (in == null) {
115 | throw new IOException("Could not find resource " + resource);
116 | }
117 | return in;
118 | }
119 |
120 | /*
121 | * Returns a resource on the classpath as a Properties object
122 | *
123 | * @param resource The resource to find
124 | * @return The resource
125 | * @throws java.io.IOException If the resource cannot be found or read
126 | */
127 | public static Properties getResourceAsProperties(String resource) throws IOException {
128 | Properties props = new Properties();
129 | InputStream in = getResourceAsStream(resource);
130 | props.load(in);
131 | in.close();
132 | return props;
133 | }
134 |
135 | /*
136 | * Returns a resource on the classpath as a Properties object
137 | *
138 | * @param loader The classloader used to fetch the resource
139 | * @param resource The resource to find
140 | * @return The resource
141 | * @throws java.io.IOException If the resource cannot be found or read
142 | */
143 | public static Properties getResourceAsProperties(ClassLoader loader, String resource) throws IOException {
144 | Properties props = new Properties();
145 | InputStream in = getResourceAsStream(loader, resource);
146 | props.load(in);
147 | in.close();
148 | return props;
149 | }
150 |
151 | /*
152 | * Returns a resource on the classpath as a Reader object
153 | *
154 | * @param resource The resource to find
155 | * @return The resource
156 | * @throws java.io.IOException If the resource cannot be found or read
157 | */
158 | public static Reader getResourceAsReader(String resource) throws IOException {
159 | Reader reader;
160 | if (charset == null) {
161 | reader = new InputStreamReader(getResourceAsStream(resource));
162 | } else {
163 | reader = new InputStreamReader(getResourceAsStream(resource), charset);
164 | }
165 | return reader;
166 | }
167 |
168 | /*
169 | * Returns a resource on the classpath as a Reader object
170 | *
171 | * @param loader The classloader used to fetch the resource
172 | * @param resource The resource to find
173 | * @return The resource
174 | * @throws java.io.IOException If the resource cannot be found or read
175 | */
176 | public static Reader getResourceAsReader(ClassLoader loader, String resource) throws IOException {
177 | Reader reader;
178 | if (charset == null) {
179 | reader = new InputStreamReader(getResourceAsStream(loader, resource));
180 | } else {
181 | reader = new InputStreamReader(getResourceAsStream(loader, resource), charset);
182 | }
183 | return reader;
184 | }
185 |
186 | /*
187 | * Returns a resource on the classpath as a File object
188 | *
189 | * @param resource The resource to find
190 | * @return The resource
191 | * @throws java.io.IOException If the resource cannot be found or read
192 | */
193 | public static File getResourceAsFile(String resource) throws IOException {
194 | return new File(getResourceURL(resource).getFile());
195 | }
196 |
197 | /*
198 | * Returns a resource on the classpath as a File object
199 | *
200 | * @param loader - the classloader used to fetch the resource
201 | * @param resource - the resource to find
202 | * @return The resource
203 | * @throws java.io.IOException If the resource cannot be found or read
204 | */
205 | public static File getResourceAsFile(ClassLoader loader, String resource) throws IOException {
206 | return new File(getResourceURL(loader, resource).getFile());
207 | }
208 |
209 | /*
210 | * Gets a URL as an input stream
211 | *
212 | * @param urlString - the URL to get
213 | * @return An input stream with the data from the URL
214 | * @throws java.io.IOException If the resource cannot be found or read
215 | */
216 | public static InputStream getUrlAsStream(String urlString) throws IOException {
217 | URL url = new URL(urlString);
218 | URLConnection conn = url.openConnection();
219 | return conn.getInputStream();
220 | }
221 |
222 | /*
223 | * Gets a URL as a Reader
224 | *
225 | * @param urlString - the URL to get
226 | * @return A Reader with the data from the URL
227 | * @throws java.io.IOException If the resource cannot be found or read
228 | */
229 | public static Reader getUrlAsReader(String urlString) throws IOException {
230 | Reader reader;
231 | if (charset == null) {
232 | reader = new InputStreamReader(getUrlAsStream(urlString));
233 | } else {
234 | reader = new InputStreamReader(getUrlAsStream(urlString), charset);
235 | }
236 | return reader;
237 | }
238 |
239 | /*
240 | * Gets a URL as a Properties object
241 | *
242 | * @param urlString - the URL to get
243 | * @return A Properties object with the data from the URL
244 | * @throws java.io.IOException If the resource cannot be found or read
245 | */
246 | public static Properties getUrlAsProperties(String urlString) throws IOException {
247 | Properties props = new Properties();
248 | InputStream in = getUrlAsStream(urlString);
249 | props.load(in);
250 | in.close();
251 | return props;
252 | }
253 |
254 | /*
255 | * Loads a class
256 | *
257 | * @param className - the class to fetch
258 | * @return The loaded class
259 | * @throws ClassNotFoundException If the class cannot be found (duh!)
260 | */
261 | public static Class> classForName(String className) throws ClassNotFoundException {
262 | return classLoaderWrapper.classForName(className);
263 | }
264 |
265 | public static Charset getCharset() {
266 | return charset;
267 | }
268 |
269 | public static void setCharset(Charset charset) {
270 | Resources.charset = charset;
271 | }
272 |
273 | }
274 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/util/ContextUtil.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.util;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | /**
7 | * @Author Tang Sicheng
8 | */
9 | public class ContextUtil {
10 |
11 | public static final Logger log = LoggerFactory.getLogger(ContextUtil.class);
12 |
13 |
14 | private ContextUtil(){}
15 |
16 | public static String upperFirstLetter(String str) {
17 | return str.substring(0, 1).toUpperCase() + str.substring(1);
18 | }
19 |
20 | public static String lowerFirstLetter(String str) {
21 | return str.substring(0, 1).toLowerCase() + str.substring(1);
22 | }
23 |
24 | public static String onlyFirstLetterIsUp(String str) {
25 | return upperFirstLetter(str.toLowerCase());
26 | }
27 |
28 | /**
29 | * Velocity context seems do not support static method
30 | * @return
31 | */
32 | public static ContextUtilWrapper newWrapper(){
33 | return new ContextUtilWrapper();
34 | }
35 |
36 | public static class ContextUtilWrapper {
37 | public ContextUtilWrapper() {
38 | }
39 |
40 | public String upperFirstLetter(String str) {
41 | return ContextUtil.upperFirstLetter(str);
42 | }
43 |
44 | public static String lowerFirstLetter(String str) {
45 | return ContextUtil.lowerFirstLetter(str);
46 | }
47 |
48 | public static String onlyFirstLetterIsUp(String str) {
49 | return ContextUtil.onlyFirstLetterIsUp(str);
50 | }
51 |
52 | }
53 | }
54 |
55 |
56 |
--------------------------------------------------------------------------------
/src/main/java/github/jadetang/maliang/util/FileUtil.java:
--------------------------------------------------------------------------------
1 | package github.jadetang.maliang.util;
2 |
3 | import com.google.common.base.Joiner;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.nio.file.DirectoryStream;
10 | import java.nio.file.Files;
11 | import java.nio.file.Path;
12 | import java.nio.file.Paths;
13 | import java.util.Arrays;
14 | import java.util.List;
15 |
16 | /**
17 | * @Author Tang Sicheng
18 | */
19 | public class FileUtil {
20 |
21 |
22 | private static Logger log = LoggerFactory.getLogger(FileUtil.class);
23 |
24 | public static void delDirectory(String path) throws IOException {
25 | Path p = Paths.get(path);
26 | delHelp(p);
27 | }
28 |
29 | private static void delHelp(Path p) throws IOException {
30 | if (!p.toFile().exists()) {
31 | return;
32 | } else if (p.toFile().isFile()) {
33 | log.debug("delete file:" + p.toAbsolutePath().toString());
34 | Files.delete(p);
35 | } else if (p.toFile().isDirectory()) {
36 | try (DirectoryStream ds = Files.newDirectoryStream(p)) {
37 | for (Path subPath : ds) {
38 | delHelp(subPath);
39 | }
40 | }
41 | log.debug("delete directory:" + p.toAbsolutePath().toString());
42 | Files.delete(p);
43 | }
44 | }
45 |
46 | public static String concatPath(String... paths) {
47 | List pathList = Arrays.asList(paths);
48 | return Joiner.on(File.separator).join(pathList).toString();
49 | }
50 |
51 | public static void main(String[] args) throws IOException {
52 | FileUtil.delDirectory("E:\\test");
53 |
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | logRoot=/data2/log/distinctservice/
2 |
3 | # This is the configuring for logging displayed in the Application Server
4 | log4j.rootLogger=DEBUG,stdout
5 |
6 |
7 | ################################
8 | #stdout configure
9 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender
10 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
11 | log4j.appender.stdout.layout.conversionPattern=[%C{1}:%L] [%d{yyyy-MM-dd HH:mm:ss}] [%-5p] - %m%n
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/main/resources/reference.conf:
--------------------------------------------------------------------------------
1 | maven {
2 | groupId = github.jadetang
3 | artifactId = maliang
4 | version = 1.0.0-SNAPSHOT
5 | package = github.jadetang.maliang
6 | }
7 |
8 | database {
9 | type {
10 | VARCHAR = java.lang.String
11 | CHAR = java.lang.String
12 | BLOB = "java.lang.byte[]"
13 | VARCHAR = java.lang.String
14 | INTEGER = java.lang.Long
15 | TINYINT = java.lang.Integer
16 | SMALLINT = java.lang.Integer
17 | MEDIUMINT = java.lang.Integer
18 | BIT = java.lang.Boolean
19 | BIGINT = java.math.BigInteger
20 | FLOAT = java.lang.Float
21 | DOUBLE = java.lang.Double
22 | DECIMAL = java.math.BigDecimal
23 | DATE = java.sql.Date
24 | TIME = java.sql.Time
25 | DATETIME = java.sql.Timestamp
26 | TIMESTAMP = java.sql.Timestamp
27 | YEAR = java.sql.Date
28 | }
29 | }
30 |
31 | dir {
32 | template = tempalate
33 | output = maliang
34 | }
35 |
36 | name {
37 | separator = ""
38 | table.prefix = ""
39 | column.prefix = ""
40 | }
41 |
--------------------------------------------------------------------------------