first blood

This commit is contained in:
Shaun Chyxion 2017-04-17 23:44:46 +08:00
parent 5c29ed959f
commit 36ddf9e0a5
1780 changed files with 159516 additions and 1 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
.*
!.gitignore
!.gitkeep
*.iml
target/

13
ISSUE_TEMPLATE.zh-CN.md Normal file
View File

@ -0,0 +1,13 @@
## 该问题是怎么引起的?
## 重现步骤
## 报错信息

View File

@ -0,0 +1,15 @@
## 该Pull Request关联的Issue
## 修改描述
## 测试用例
## 修复效果的截屏

View File

@ -1 +1 @@
#tigon
# Tigon

3
deploy Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
mvn clean deploy -DskipTests -U -DaltDeploymentRepository=snapshot::default::http://101.231.57.218:8081/nexus/content/repositories/snapshots/

4
deploy_oss Executable file
View File

@ -0,0 +1,4 @@
#!/bin/bash
# mvn clean deploy -DskipTests -U -Prelease -DaltDeploymentRepository=oss::default::https://oss.sonatype.org/service/local/staging/deploy/maven2/
mvn clean deploy -DskipTests -Dmaven.javadoc.skip=true -U -Prelease -DaltDeploymentRepository=oss::default::https://oss.sonatype.org/content/repositories/snapshots

666
pom.xml Normal file
View File

@ -0,0 +1,666 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Tigon</name>
<description>Tigon</description>
<parent>
<groupId>me.chyxion</groupId>
<artifactId>maven-parent</artifactId>
<version>0.0.2-RELEASE</version>
</parent>
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
<spring.version>4.3.6.RELEASE</spring.version>
<spring-boot.version>1.5.2.RELEASE</spring-boot.version>
<slf4j.version>1.7.23</slf4j.version>
<log4j.version>2.7</log4j.version>
<shiro.version>1.3.2</shiro.version>
<aspectj.version>1.8.10</aspectj.version>
<main.class>Main</main.class>
</properties>
<scm>
<connection>scm:git:https://github.com/chyxion/tigon.git</connection>
<developerConnection>scm:git:git@github.com:chyxion/tigon.git</developerConnection>
<url>https://github.com/chyxion/tigon</url>
</scm>
<developers>
<developer>
<id>chyxion</id>
<name>Shaun Chyxion</name>
<email>chyxion@163.com</email>
<url>http://chyxion.github.io</url>
</developer>
</developers>
<modules>
<!--<module>tigon-lombok</module>-->
<module>tigon-model</module>
<module>tigon-mybatis</module>
<module>tigon-sequence</module>
<module>tigon-redis</module>
<module>tigon-mybatis-redis-cache</module>
<module>tigon-shiro-redis-cache</module>
<module>tigon-webmvc-core</module>
<module>tigon-webmvc-spring-boot</module>
<module>tigon-webmvc-war</module>
<module>tigon-shiro-core</module>
<module>tigon-shiro-spring-boot</module>
<module>tigon-shiro-war</module>
<module>tigon-service-api</module>
<module>tigon-service-support</module>
<module>tigon-props-config</module>
<module>tigon-extjs</module>
<module>tigon-freemarker-support</module>
<module>tigon-jsp-support</module>
<module>tigon-codegen</module>
</modules>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-lombok</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-model</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-mybatis</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-sequence</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-webmvc-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-webmvc-spring-boot</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-webmvc-war</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-redis</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-mybatis-redis-cache</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-shiro-redis-cache</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-shiro-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-shiro-spring-boot</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-shiro-war</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-service-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-service-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-extjs</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-freemarker-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-jsp-support</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-codegen</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-props-config</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.14</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.4.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!-- /mybatis -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.28</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.9.2.RELEASE</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.shiro/shiro-core -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-core</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-web</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<artifactId>commons-fileupload</artifactId>
<groupId>commons-fileupload</groupId>
<version>1.3.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>3.2.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-test</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-autoconfigure -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>${spring-boot.version}</version>
</dependency>
<!-- / Spring Boot -->
<dependency>
<artifactId>spring-core</artifactId>
<groupId>org.springframework</groupId>
<version>${spring.version}</version>
</dependency>
<dependency>
<artifactId>spring-beans</artifactId>
<groupId>org.springframework</groupId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<artifactId>spring-context</artifactId>
<groupId>org.springframework</groupId>
<version>${spring.version}</version>
</dependency>
<dependency>
<artifactId>spring-context-support</artifactId>
<groupId>org.springframework</groupId>
<version>${spring.version}</version>
</dependency>
<dependency>
<artifactId>spring-webmvc</artifactId>
<groupId>org.springframework</groupId>
<version>${spring.version}</version>
</dependency>
<dependency>
<artifactId>spring-web</artifactId>
<groupId>org.springframework</groupId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<artifactId>commons-codec</artifactId>
<groupId>commons-codec</groupId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- java web -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.7</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
target/lib
</outputDirectory>
<excludeScope>provided</excludeScope>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.6</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Built-By>Shaun Chyxion</Built-By>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<finalName>${project.artifactId}</finalName>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${main.class}</mainClass>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.tooling</resource>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<version>2.6.1</version>
<executions>
<execution>
<id>remove-config-file</id>
<goals><goal>clean</goal></goals>
<phase>compile</phase>
<configuration>
<excludeDefaultDirectories>true</excludeDefaultDirectories>
<filesets>
<fileset>
<directory>src/main/resources/spring</directory>
<includes>
<include>config.properties</include>
</includes>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.coderplus.maven.plugins</groupId>
<artifactId>copy-rename-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<id>copy-config-file</id>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<sourceFile>src/main/resources/config_${project.activeProfiles[0].id}.properties</sourceFile>
<destinationFile>src/main/resources/spring/config.properties</destinationFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.6</version>
<configuration>
<version>3.0</version>
<webResources>
<resource>
<directory>src/main/webapp</directory>
</resource>
</webResources>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8080</port>
<path>/</path>
<charset>utf-8</charset>
<uriEncoding>utf-8</uriEncoding>
<contextReloadable>false</contextReloadable>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-help-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-clean-plugin</artifactId>
<versionRange>
[2.6.1,)
</versionRange>
<goals>
<goal>clean</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>

1
tigon-codegen/README.md Normal file
View File

@ -0,0 +1 @@
# tigon-codegen

67
tigon-codegen/pom.xml Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>tigon-codegen</artifactId>
<packaging>jar</packaging>
<name>Tigon Code Gen</name>
<description>Tigon Code Gen</description>
<parent>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-freemarker-support</artifactId>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-extjs</artifactId>
</dependency>
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-webmvc-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon-mybatis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- /mybatis -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,20 @@
package me.chyxion.tigon.codegen;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
/**
* @version 0.0.1
* @since 0.0.4
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Feb 4, 2015 4:42:01 PM
*/
public interface CodeGenCustomizer {
/**
* customize your code gen result
* @param args
* @return
*/
void customize(CodeGenArgs args);
}

View File

@ -0,0 +1,235 @@
package me.chyxion.tigon.codegen.controller;
import java.util.List;
import java.util.Map;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import me.chyxion.tigon.codegen.service.CodeGenBaseTool;
import me.chyxion.tigon.codegen.service.CodeGenService;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.NotBlank;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;
import static org.springframework.web.bind.annotation.RequestMethod.DELETE;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 5, 2014 9:34:54 PM
*/
@Controller
@RequestMapping("/codegen")
public class CodeGenController {
@Autowired
private CodeGenService service;
@Autowired
private CodeGenBaseTool tool;
@RequestMapping(method = GET)
public ModelAndView index() {
return new ModelAndView("webapp/views/codegen")
.addObject("pkg", tool.getPkg());
}
@RequestMapping(value = "/tables")
public List<Map<String, Object>> tables() {
return service.tables();
}
@RequestMapping(method = POST)
public boolean gen(@Valid GenForm form) {
service.process(form.getModule(), form.getModel(),
form.getJaColumns(), form.getTable(), form);
return true;
}
@RequestMapping("/list")
public List<?> list() {
return service.list();
}
@RequestMapping(method = DELETE)
public boolean delete(
@RequestParam("items")
String items,
@RequestParam(value = "dropTable", defaultValue = "true")
boolean dropTable) {
service.delete(JSON.parseArray(items), dropTable);
return true;
}
public static class GenForm {
@NotNull
private String columns;
@NotBlank
private String model;
@NotBlank
private String table;
private String module;
private String pkg;
private boolean genController;
private boolean genService;
private boolean genMapper;
private boolean genModel;
private boolean genTable;
private boolean genView;
private boolean createTable;
/**
* @return the columns
*/
public JSONArray getJaColumns() {
return JSON.parseArray(columns);
}
public String getColumns() {
return columns;
}
/**
* @param columns the columns to set
*/
public void setColumns(String columns) {
this.columns = columns;
}
/**
* @return the model
*/
public String getModel() {
return model;
}
/**
* @param model the model to set
*/
public void setModel(String model) {
this.model = model;
}
/**
* @return the table
*/
public String getTable() {
return table;
}
/**
* @param table the table to set
*/
public void setTable(String table) {
this.table = table;
}
/**
* @return the module
*/
public String getModule() {
return StringUtils.isNotBlank(module) ? module : "";
}
/**
* @param module the module to set
*/
public void setModule(String module) {
this.module = module;
}
/**
* @return the createTable
*/
public boolean isCreateTable() {
return createTable;
}
/**
* @param createTable the createTable to set
*/
public void setCreateTable(boolean createTable) {
this.createTable = createTable;
}
/**
* @return the pkg
*/
public String getPkg() {
return pkg;
}
/**
* @param pkg the pkg to set
*/
public void setPkg(String pkg) {
this.pkg = pkg;
}
/**
* @return the genTable
*/
public boolean isGenTable() {
return genTable;
}
/**
* @param genTable the genTable to set
*/
public void setGenTable(boolean genTable) {
this.genTable = genTable;
}
/**
* @return the genController
*/
public boolean isGenController() {
return genController;
}
/**
* @param genController the genController to set
*/
public void setGenController(boolean genController) {
this.genController = genController;
}
/**
* @return the genService
*/
public boolean isGenService() {
return genService;
}
/**
* @param genService the genService to set
*/
public void setGenService(boolean genService) {
this.genService = genService;
}
/**
* @return the genMapper
*/
public boolean isGenMapper() {
return genMapper;
}
/**
* @param genMapper the genMapper to set
*/
public void setGenMapper(boolean genMapper) {
this.genMapper = genMapper;
}
/**
* @return the genView
*/
public boolean isGenView() {
return genView;
}
/**
* @param genView the genView to set
*/
public void setGenView(boolean genView) {
this.genView = genView;
}
/**
* @return the genModel
*/
public boolean isGenModel() {
return genModel;
}
/**
* @param genModel the genModel to set
*/
public void setGenModel(boolean genModel) {
this.genModel = genModel;
}
}
}

View File

@ -0,0 +1,58 @@
package me.chyxion.tigon.codegen.model;
import java.util.Map;
import lombok.Getter;
import lombok.Setter;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* May 11, 2016 7:31:30 PM
*/
@Getter
@Setter
public class CodeGenArgs {
public static final String TARGET_MODEL = "MODEL";
public static final String TARGET_MAPPER = "MAPPER";
public static final String TARGET_MAPPER_XML = "MAPPER_XML";
public static final String TARGET_MAPPER_TEST = "MAPPER_TEST";
public static final String TARGET_SERVICE = "SERVICE";
public static final String TARGET_SERVICE_SUPPORT = "SERVICE_SUPPORT";
public static final String TARGET_CONTROLLER = "CONTROLLER";
public static final String TARGET_CONTROLLER_TEST = "CONTROLLER_TEST";
public static final String TARGET_TABLE = "TABLE";
public static final String TARGET_VIEW = "VIEW";
/**
* gen target
*/
private String target;
/**
* result file
*/
private String file;
/**
* free marker template
*/
private String ftl;
/**
* free marker data model
*/
private Map<String, Object> model;
/**
* @param target
* @param ftl
* @param model
* @param file
*/
public CodeGenArgs(String target, String ftl, Map<String, Object> model, String file) {
this.target = target;
this.ftl = ftl;
this.model = model;
this.file = file;
}
}

View File

@ -0,0 +1,588 @@
package me.chyxion.tigon.codegen.service;
import java.io.File;
import java.util.Map;
import java.util.Set;
import java.util.Date;
import java.util.List;
import java.util.Arrays;
import org.slf4j.Logger;
import java.util.TreeSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.io.FileWriter;
import java.sql.ResultSet;
import org.w3c.dom.Element;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
import java.util.LinkedList;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.io.FileInputStream;
import org.slf4j.LoggerFactory;
import java.sql.DatabaseMetaData;
import com.alibaba.fastjson.JSON;
import java.io.InputStreamReader;
import me.chyxion.tigon.model.M1;
import freemarker.template.Template;
import org.apache.commons.io.IOUtils;
import javax.annotation.PostConstruct;
import org.apache.commons.io.FileUtils;
import me.chyxion.tigon.util.WordUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.CharEncoding;
import me.chyxion.tigon.codegen.utils.DbTool;
import org.springframework.stereotype.Service;
import javax.xml.parsers.DocumentBuilderFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.dao.DataAccessException;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.jdbc.core.ConnectionCallback;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import static org.springframework.context.ConfigurableApplicationContext.*;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
/**
* @version 0.0.1
* @since 0.0.1
* @author chyxion <br>
* chyxion@163.com <br>
* Dec 3, 2014 11:25:17 AM
*/
@Service
public class CodeGenBaseTool {
private static final Logger log =
LoggerFactory.getLogger(CodeGenBaseTool.class);
@Autowired
private FreeMarkerConfigurer fmCfg;
@Autowired(required = false)
private DataSource dataSource;
private JdbcTemplate jdbcTpl;
@Value("#{systemProperties['project.basedir']}")
private String projDir;
private String groupId;
private String pkg;
private Properties config = new Properties();
private Set<String> baseCols = new HashSet<String>();
/**
* @param col
* @return true if col is base col
*/
public boolean isBaseCol(String col) {
return baseCols.contains(col);
}
/**
* @param key
* @return
*/
public String getConfig(String key) {
return config.getProperty(key);
}
/**
* @param key
* @param defaultValue
* @return
*/
public String getConfig(String key, String defaultValue) {
return config.getProperty(key, defaultValue);
}
/**
* get config
* @param key
* @param defaultValue
* @return
*/
public boolean getConfig(String key, boolean defaultValue) {
return Boolean.valueOf(getConfig(key, String.valueOf(defaultValue)));
}
/**
* @param key
* @param defaultValue
* @return
*/
public int getConfig(String key, int defaultValue) {
return Integer.valueOf(getConfig(key, String.valueOf(defaultValue)));
}
/**
* @param key
* @param defaultValue
* @return
*/
public long getConfig(String key, long defaultValue) {
return Long.valueOf(getConfig(key, String.valueOf(defaultValue)));
}
/**
* @param key
* @param defaultValue
* @return
*/
public double getConfig(String key, double defaultValue) {
return Double.valueOf(getConfig(key, String.valueOf(defaultValue)));
}
/**
* @param key
* @param defaultValue
* @return
*/
public float getConfig(String key, float defaultValue) {
return Float.valueOf(getConfig(key, String.valueOf(defaultValue)));
}
/**
* @return the projDir
*/
public String getProjDir() {
return projDir;
}
/**
* @return the groupId
*/
public String getGroupId() {
return groupId;
}
/**
* @return the groupId
*/
public String getPkg() {
return pkg;
}
/**
* save record to file
* @param mapRec map record
*/
public void saveRecord(Map<String, Object> mapRec) {
mapRec.put(M1.DATE_CREATED, new Date());
writeStore(addRec(mapRec));
}
/**
* exec SQL file
* @param sqlFile
*/
public void execSQL(File sqlFile) {
if (jdbcTpl != null) {
DbTool.executeSqlScript(jdbcTpl, new FileSystemResource(sqlFile), false);
}
}
/**
* exec SQL string
* @param sql
*/
public void execSQL(String sql) {
if (jdbcTpl != null) {
jdbcTpl.execute(sql);
}
}
/**
* init config
*/
@PostConstruct
void init() {
// disable cache
log.info("Disable FreeMarker Cache In Dev Mode.");
fmCfg.getConfiguration().setTemplateUpdateDelayMilliseconds(0);
if (dataSource != null) {
jdbcTpl = new JdbcTemplate(dataSource, true);
}
try {
log.info("Parse Group ID From [{}/pom.xml].", projDir);
Element root = DocumentBuilderFactory.newInstance()
.newDocumentBuilder()
.parse(new File(projDir, "pom.xml"))
.getDocumentElement();
root.normalize();
groupId = root.getElementsByTagName("groupId").item(0).getTextContent().trim();
log.info("Group ID [{}] Found.", groupId);
}
catch (Exception e) {
throw new IllegalStateException(
"Parse [groupId] From Maven POM File [" + projDir + "/pom.xml] Error Caused", e);
}
InputStream cfgIns = CodeGenBaseTool.class
.getResourceAsStream("/codegen/config.properties");
if (cfgIns != null) {
try {
config.load(cfgIns);
log.info("Code Gen Config [{}] Found.", config);
}
catch (IOException e) {
throw new IllegalStateException(
"Load Code Gen Config Error Caused", e);
}
finally {
IOUtils.closeQuietly(cfgIns);
}
}
baseCols.add("id");
String baseColsProp = config.getProperty("base.cols");
if (StringUtils.isNotBlank(baseColsProp)) {
log.info("Code Gen Base Cols [{}] Found.", baseColsProp);
baseCols.addAll(Arrays.asList(
org.springframework.util.StringUtils
.tokenizeToStringArray(
baseColsProp, CONFIG_LOCATION_DELIMITERS, true, true)));
}
log.info("Code Gen Base Cols [{}] Result.", baseCols);
pkg = config.getProperty("base.package", groupId);
log.info("Code Gen Package [{}].", pkg);
}
/**
* list all model generated
* @return
*/
@SuppressWarnings("unchecked")
public List<Map<String, Object>> listAll() {
return (List<Map<String, Object>>) getStore().get("items");
}
/**
* get store data
* @return
*/
private Map<String, Object> getStore() {
File file = getStoreFile();
Map<String, Object> mapData = null;
if (file.exists()) {
FileInputStream fin = null;
try {
fin = new FileInputStream(file);
mapData = JSON.parseObject(IOUtils.toString(fin, CharEncoding.UTF_8));
}
catch (IOException e) {
log.info("Parse JSON File [{}] ERROR Caused.", file.getName());
try {
String backupFileName =
"codegen/data_broken_" +
DateFormatUtils.format(new Date(), "yyyy_MM_dd_HH_mm_ss") +
".json";
log.info("Backup Data File To [{}].", backupFileName);
if (fin != null) {
// backup data file
IOUtils.copy(fin,
new FileWriter(new File(projDir, backupFileName)),
CharEncoding.UTF_8);
}
}
catch (IOException e1) {
log.info("Backup JSON File [{}] ERROR Caused.", file.getName());
}
}
finally {
IOUtils.closeQuietly(fin);
}
}
if (mapData == null) {
mapData = new HashMap<String, Object>();
mapData.put("items", new LinkedList<Object>());
}
return mapData;
}
private void writeStore(Map<String, Object> storeData) {
File file = getStoreFile();
try {
storeData.put("date_updated", new Date());
FileUtils.write(file, JSON.toJSONStringWithDateFormat(storeData,
"yyyy-MM-dd HH:mm:ss",
SerializerFeature.PrettyFormat),
CharEncoding.UTF_8);
}
catch (IOException e) {
throw new RuntimeException("Write Data To File [" + file.getAbsolutePath() + "] ERROR Caused.", e);
}
}
private File getStoreFile() {
return new File(projDir, ".codegen/data.json");
}
@SuppressWarnings("unchecked")
private Map<String, Object> addRec(Map<String, Object> mapRec) {
Map<String, Object> mapData = getStore();
Map<String, Object> rec =
findRec(mapData, (String) mapRec.get("module"),
(String) mapRec.get("model"));
if (rec != null) {
rec.putAll(mapRec);
}
else {
((List<Map<String, Object>>) mapData.get("items")).add(mapRec);
}
return mapData;
}
@SuppressWarnings("unchecked")
private Map<String, Object> findRec(Map<String, Object> store, String module, String model) {
for (Map<String, Object> item : (List<Map<String, Object>>) store.get("items")) {
if (eqauls(item, module, model)) {
return item;
}
}
return null;
}
/**
* delete rec
* @param module
* @param model
*/
@SuppressWarnings("unchecked")
public void deleteRec(String module, String model, boolean dropTable) {
Map<String, Object> mapData = getStore();
Iterator<Map<String, Object>> it =
((List<Map<String, Object>>) mapData.get("items")).listIterator();
while (it.hasNext()) {
Map<String, Object> item = it.next();
if (eqauls(item, module, model)) {
List<String> files = (List<String>) item.get("files");
for (String filePath : files) {
File file = new File(projDir, filePath);
File fileParent = file.getParentFile();
FileUtils.deleteQuietly(file);
deleteEmptyDir(fileParent);
}
if (dropTable) {
// drop table
try {
execSQL("drop table " + item.get("table"));
}
catch (Exception e) {
log.info("Drop Table Error Caused.", e);
}
}
it.remove();
break;
}
}
writeStore(mapData);
}
/**
* render FreeMarker Template
* @param ftl
* @param model
* @return
*/
public String renderFtl(String ftl, Map<String, ?> model) {
try {
return FreeMarkerTemplateUtils.processTemplateIntoString(
new Template(ftl, new InputStreamReader(
CodeGenBaseTool.class.getResourceAsStream(ftl),
CharEncoding.UTF_8), fmCfg.getConfiguration()), model);
}
catch (Exception e) {
throw new RuntimeException("Code Generate Render ERROR, [" + e.getMessage() + "].", e);
}
}
public List<Map<String, Object>> tables() {
if (jdbcTpl != null) {
return jdbcTpl.execute(new ConnectionCallback<List<Map<String, Object>>>() {
@Override
public List<Map<String, Object>> doInConnection(Connection conn)
throws SQLException, DataAccessException {
List<Map<String, Object>> tables = new LinkedList<Map<String, Object>>();
ResultSet rs = null;
try {
DatabaseMetaData md = conn.getMetaData();
rs = md.getTables(null, null, "%", new String[] {"TABLE"});
String tablePrefix =
config.getProperty("table.prefix", "")
.toLowerCase();
while (rs.next()) {
Map<String, Object> mapTable = new HashMap<String, Object>();
String table = rs.getString(3).toLowerCase();
mapTable.put("id", table);
mapTable.put("text", table);
mapTable.put("table", table);
String[] tableNameParts = null;
if (StringUtils.isNotBlank(tablePrefix) &&
table.startsWith(tablePrefix + "_")) {
log.info("Table Prefix [{}] Found, Trim.", tablePrefix);
tableNameParts =
table.substring(tablePrefix.length() + 1)
.split("_");
}
else {
tableNameParts = table.split("_");
}
String model = "";
for (String tblNamePart : tableNameParts) {
model += StringUtils.capitalize(tblNamePart);
}
mapTable.put("model", model);
mapTable.put("leaf", true);
Set<String> keys = keys(md, table);
mapTable.put("keys", keys);
Set<String> indexes = indexes(md, table, false);
mapTable.put("indexes", indexes);
mapTable.put("cols", cols(md, table, keys, indexes));
tables.add(mapTable);
}
}
finally {
JdbcUtils.closeResultSet(rs);
}
return tables;
}
});
}
return new LinkedList<Map<String, Object>>();
}
// --
// private methods
private List<Map<String, Object>> cols(DatabaseMetaData md,
final String table, Set<String> keys, Set<String> indexes) {
List<Map<String, Object>> cols = new LinkedList<Map<String, Object>>();
ResultSet rs = null;
try {
rs = md.getColumns(null, "%", table, "%");
while (rs.next()) {
Map<String, Object> col = new HashMap<String, Object>();
String colName = rs.getString("COLUMN_NAME");
col.put("isKey", keys.contains(colName));
col.put("isIndex", indexes.contains(colName));
col.put("col", colName);
col.put("name",
StringUtils.uncapitalize(
WordUtils.convertToCamelCase(colName, "_")));
int size = rs.getInt("COLUMN_SIZE");
col.put("size", size);
String type = rs.getString("TYPE_NAME").toLowerCase();
String javaType = "String";
if (type.endsWith("char")) {
type = type + "(" + size + ")";
}
else if (type.contains("date") || type.contains("time")) {
javaType = "Date";
}
else if (type.equals("int")) {
javaType = "int";
}
else if (type.equals("bigint")) {
javaType = "long";
}
else if (type.contains("int")) {
javaType = "int";
}
else if (type.equals("float")) {
javaType = "float";
}
else if (type.contains("double")) {
javaType = "double";
}
else if (type.contains("blob")) {
javaType = "byte[]";
}
col.put("sqlType", type);
col.put("javaType", javaType);
col.put("notNull", rs.getInt("NULLABLE") == 0);
cols.add(col);
}
}
catch (Exception e) {
throw new RuntimeException("Get Table Columns Error Caused.", e);
}
finally {
JdbcUtils.closeResultSet(rs);
}
return cols;
}
private Set<String> keys(DatabaseMetaData md, String table) {
ResultSet rs = null;
Set<String> keys = new TreeSet<String>();
try {
rs = md.getPrimaryKeys(null, null, table);
while (rs.next()) {
keys.add(rs.getString("COLUMN_NAME"));
}
}
catch (Exception e) {
throw new RuntimeException("Get Table Keys Error Caused.", e);
}
finally {
JdbcUtils.closeResultSet(rs);
}
// find unique indexes
if (keys.size() == 0) {
keys = indexes(md, table, true);
}
return keys;
}
private Set<String> indexes(DatabaseMetaData md, String table, boolean unique) {
ResultSet rs = null;
Set<String> keys = new TreeSet<String>();
try {
rs = md.getIndexInfo(null, null, table, false, false);
while (rs.next()) {
if (unique && rs.getBoolean("NON_UNIQUE")) {
continue;
}
keys.add(rs.getString("COLUMN_NAME"));
}
}
catch (Exception e) {
throw new RuntimeException("Get Table Indexes Error Caused.", e);
}
finally {
JdbcUtils.closeResultSet(rs);
}
return keys;
}
private void deleteEmptyDir(File file) {
if (file.exists() && file.isDirectory() && file.list().length == 0) {
File fileParent = file.getParentFile();
FileUtils.deleteQuietly(file);
deleteEmptyDir(fileParent);
}
}
private boolean eqauls(Map<String, Object> item, String module, String model) {
return item.get("module").equals(module) && item.get("model").equals(model);
}
/**
* @return the baseCols
*/
public Set<String> getBaseCols() {
return baseCols;
}
/**
* @param baseCols the baseCols to set
*/
public void setBaseCols(Set<String> baseCols) {
this.baseCols = baseCols;
}
}

View File

@ -0,0 +1,42 @@
package me.chyxion.tigon.codegen.service;
import java.util.List;
import java.util.Map;
import me.chyxion.tigon.codegen.controller.CodeGenController.GenForm;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:08:14 PM
*/
public interface CodeGenService {
/**
* process code generation
* @param module
* @param model
* @param cols
* @param table
* @param form
*/
void process(String module, String model, List<?> cols, String table, GenForm form);
/**
* list generated items
* @return items list
*/
List<?> list();
/**
* list tables
* @return
*/
List<Map<String, Object>> tables();
/**
* delete items
* @param items
*/
void delete(List<?> items, boolean dropTable);
}

View File

@ -0,0 +1,68 @@
package me.chyxion.tigon.codegen.service;
import java.io.File;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.CharEncoding;
import me.chyxion.tigon.codegen.CodeGenCustomizer;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import org.springframework.beans.factory.annotation.Autowired;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:10:55 PM
*/
public abstract class CodeGenerator {
@Autowired(required = false)
private List<CodeGenCustomizer> customizers;
@Autowired
protected CodeGenBaseTool baseTool;
protected String codeDir = "src/main/java/";
protected String testDir = "src/test/java/";
protected String resourcesDir = "src/main/resources/";
protected String viewsDir = "src/main/webapp/assets/js/views/";
/**
* @param dataModel
* @param module
* @param model
*/
public abstract String process(Map<String, Object> dataModel, String module, String model);
/**
* @param dataModel
* @return
*/
public boolean accept(Map<String, Object> dataModel) {
return true;
}
/**
* render FreeMarker Tpl
* @param args code gen args
* @return gen result file path
*/
protected String render(CodeGenArgs args) {
try {
// customize
if (customizers != null && customizers.size() > 0) {
for (CodeGenCustomizer customizer : customizers) {
customizer.customize(args);
}
}
// write result
FileUtils.write(new File(baseTool.getProjDir(), args.getFile()),
baseTool.renderFtl(args.getFtl(), args.getModel()),
CharEncoding.UTF_8);
return args.getFile();
}
catch (Exception e) {
throw new IllegalStateException(
"Code Gen Render File Error Caused.", e);
}
}
}

View File

@ -0,0 +1,296 @@
package me.chyxion.tigon.codegen.service.support;
import me.chyxion.tigon.mybatis.Table;
import me.chyxion.tigon.util.WordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import me.chyxion.tigon.codegen.controller.CodeGenController.GenForm;
import me.chyxion.tigon.codegen.service.CodeGenBaseTool;
import me.chyxion.tigon.codegen.service.CodeGenService;
import me.chyxion.tigon.codegen.service.CodeGenerator;
import me.chyxion.tigon.mybatis.BaseMapper;
import me.chyxion.tigon.model.M0;
import me.chyxion.tigon.model.M1;
import me.chyxion.tigon.model.M2;
import me.chyxion.tigon.model.M3;
/*
import me.chyxion.tigon.webmvc.annotations.Mock;
import me.chyxion.tigon.webmvc.controller.BaseController;
import me.chyxion.tigon.webmvc.service.BaseService;
import me.chyxion.tigon.webmvc.service.support.BaseServiceSupport;
*/
import me.chyxion.tigon.webmvc.test.ControllerTestTool;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:10:02 PM
*/
@Service
public class CodeGenServiceSupport implements CodeGenService {
private static final Logger log = LoggerFactory.getLogger(CodeGenServiceSupport.class);
private static final Map<String, String> TYPE_PACKAGES = new HashMap<String, String>() {
private static final long serialVersionUID = 1L;
{
put(Date.class.getSimpleName(), Date.class.getName());
}
};
@Autowired
private CodeGenBaseTool baseTool;
@Autowired
private List<CodeGenerator> codeGen;
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public void process(String module, String model, List<?> columns, String table, GenForm form) {
String minusJoinedModelName = WordUtils.convertCamelCase(model, "-").toLowerCase();
String mappingUrl = minusJoinedModelName;
String pkg = form.getPkg();
if (StringUtils.isBlank(pkg)) {
pkg = baseTool.getPkg();
}
if (StringUtils.isNotBlank(module)) {
mappingUrl = module + "/" + mappingUrl;
pkg += "." + module;
}
else {
module = "";
}
model = StringUtils.capitalize(model);
Map<String, Object> fmDataModel = new HashMap<String, Object>();
fmDataModel.put("genController", form.isGenController());
fmDataModel.put("genService", form.isGenService());
fmDataModel.put("genMapper", form.isGenMapper());
fmDataModel.put("genModel", form.isGenModel());
fmDataModel.put("genTable", form.isGenTable());
fmDataModel.put("genView", form.isGenView());
fmDataModel.put("createTable", form.isCreateTable());
fmDataModel.put("table", table.toLowerCase());
fmDataModel.put("notNull", false);
fmDataModel.put("notBlank", false);
fmDataModel.put("cacheEnabled", baseTool.getConfig("cache.enabled", false));
fmDataModel.put("useGeneratedKeys", false);
// collect col names
String idType = null;
List<String> colNames = new ArrayList<String>(columns.size());
for (Map<String, Object> col : (List<Map<String, Object>>) columns) {
String colName = ((String) col.get("col")).toLowerCase();
colNames.add(colName);
if (M0.ID.equals(colName)) {
String javaType = (String) col.get("javaType");
if (ArrayUtils.contains(
new String[] {"int", "long", "boolean", "double", "byte"},
javaType)) {
javaType = StringUtils.capitalize(javaType);
}
idType = javaType;
}
}
String baseModelName = null;
String baseModelFullName = null;
Collection<String> baseCols = null;
if (colNames.containsAll(new M3<String, String>().cols())) {
baseModelName = M3.class.getSimpleName();
baseModelFullName = M3.class.getName();
baseCols = new M3<String, String>().cols();
}
else if (colNames.containsAll(new M2<String>().cols())) {
baseModelName = M2.class.getSimpleName();
baseModelFullName = M2.class.getName();
baseCols = new M2<String>().cols();
}
else if (colNames.containsAll(new M1<String>().cols())) {
baseModelName = M1.class.getSimpleName();
baseModelFullName = M1.class.getName();
baseCols = new M1<String>().cols();
}
else {
baseModelName = M0.class.getSimpleName();
baseModelFullName = M0.class.getName();
baseCols = new M0<String>().cols();
}
// custom config
String cfgBaseModelName = baseTool.getConfig("super.base.model.name");
if (StringUtils.isNotBlank(cfgBaseModelName)) {
baseCols = baseTool.getBaseCols();
}
String cfgBaseModelFullName =
baseTool.getConfig("super.base.model.full.name");
fmDataModel.put("baseModelName",
baseTool.getConfig("super.base.model.name",
baseModelName + "<" + idType + ">"));
fmDataModel.put("baseModelFullName",
"NONE".equalsIgnoreCase(cfgBaseModelFullName) ? null :
StringUtils.isNotBlank(cfgBaseModelFullName) ?
cfgBaseModelFullName : baseModelFullName);
fmDataModel.put("tableAnnotationClassName", Table.class.getName());
fmDataModel.put("tableAnnotationName", Table.class.getSimpleName());
Set<String> imports = new HashSet<String>();
List<Map<String, Object>> colsWithoutBase =
(List<Map<String, Object>>) columns;
Iterator<Map<String, Object>> colIt =
colsWithoutBase.iterator();
while (colIt.hasNext()) {
Map<String, Object> col = colIt.next();
// col name
String colName = ((String) col.get("col")).toLowerCase();
if (!baseCols.contains(colName)) {
// prop name
String propName = (String) col.get("name");
// for setName
col.put("Name", StringUtils.capitalize(propName));
if ((Boolean) col.get("notNull")) {
if ("String".equals(col.get("javaType"))) {
fmDataModel.put("notBlank", true);
}
else {
fmDataModel.put("notNull", true);
}
}
// imports
String p = TYPE_PACKAGES.get(col.get("javaType"));
if (StringUtils.isNotBlank(p)) {
imports.add(p);
}
}
// remove base col
else {
colIt.remove();
}
}
fmDataModel.put("idType", idType);
fmDataModel.put("cols", colsWithoutBase);
fmDataModel.put("imports", imports);
fmDataModel.put("url", mappingUrl);
fmDataModel.put("pkg", pkg);
fmDataModel.put("pkgDir", pkg.replace('.', '/'));
fmDataModel.put("modelFullName", pkg + "." + model);
fmDataModel.put("module", module);
fmDataModel.put("ModelName", model);
fmDataModel.put("modelName", StringUtils.uncapitalize(model));
fmDataModel.put("minusJoinedModelName", minusJoinedModelName);
/*
// super classes name
fmDataModel.put("baseControllerName", BaseController.class.getSimpleName());
fmDataModel.put("baseControllerFullName", BaseController.class.getName());
// service interface
fmDataModel.put("baseServiceName", BaseService.class.getSimpleName());
fmDataModel.put("baseServiceFullName", BaseService.class.getName());
// server support
fmDataModel.put("baseServiceSupportName", BaseServiceSupport.class.getSimpleName());
fmDataModel.put("baseServiceSupportFullName", BaseServiceSupport.class.getName());
*/
// model
//
// mapper
fmDataModel.put("baseMapperName", BaseMapper.class.getSimpleName());
fmDataModel.put("baseMapperFullName", BaseMapper.class.getName());
// fmDataModel.put("mockMapperName", MockMapper.class.getSimpleName());
// fmDataModel.put("mockMapperFullName", MockMapper.class.getName());
// fmDataModel.put("mockName", Mock.class.getSimpleName());
// fmDataModel.put("mockFullName", Mock.class.getName());
fmDataModel.put("ctrlrTestToolName", ControllerTestTool.class.getSimpleName());
fmDataModel.put("ctrlrTestToolFullName", ControllerTestTool.class.getName());
// Object Doc
Map<String, Object> objDocModel = new HashMap<String, Object>();
// time now
objDocModel.put("now",
DateFormat.getDateTimeInstance(DateFormat.DEFAULT,
DateFormat.DEFAULT, Locale.US).format(new Date()));
// code doc
fmDataModel.put("objDoc",
baseTool.renderFtl("/codegen/obj-doc.ftl", objDocModel));
List<String> files = new LinkedList<String>();
for (CodeGenerator gen : codeGen) {
if (gen.accept(fmDataModel)) {
String genResult = gen.process(fmDataModel, module, model);
if (StringUtils.isNotBlank(genResult)) {
files.addAll(Arrays.asList(genResult.split(";")));
}
}
}
log.info("Save Code Generated Data, Module [{}], Model [{}].", module, model);
Map<String, Object> mapRec = new HashMap<String, Object>();
mapRec.put("cols", columns);
mapRec.put("module", module);
mapRec.put("model", model);
mapRec.put("files", files);
mapRec.put("table", table);
baseTool.saveRecord(mapRec);
}
/**
* {@inheritDoc}
*/
@Override
public List<?> list() {
List<Map<String, Object>> items = baseTool.listAll();
for (Map<String, Object> item : items) {
String text = (String) item.get("model");
String module = (String) item.get("module");
if (StringUtils.isNotBlank(module)) {
text = module + "/" + text;
}
item.put("text", text);
item.put("checked", false);
item.put("leaf", true);
item.remove("files");
}
return items;
}
/**
* {@inheritDoc}
*/
@Override
@SuppressWarnings("unchecked")
public void delete(List<?> items, boolean dropTable) {
for (Map<String, Object> item : (List<Map<String, Object>>) items) {
baseTool.deleteRec((String) item.get("module"), (String) item.get("model"), dropTable);
}
}
/**
* {@inheritDoc}
*/
@Override
public List<Map<String, Object>> tables() {
return baseTool.tables();
}
}

View File

@ -0,0 +1,39 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import me.chyxion.tigon.codegen.service.CodeGenerator;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:17:03 PM
*/
@Service
public class ControllerCodeGen extends CodeGenerator {
/**
* {@inheritDoc}
*/
@Override
public boolean accept(Map<String, Object> dataModel) {
return (Boolean) dataModel.get("genController");
}
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
return render(new CodeGenArgs(
CodeGenArgs.TARGET_CONTROLLER,
"/codegen/controller.ftl",
dataModel,
codeDir + dataModel.get("pkgDir") +
"/controller/" +
model + "Controller.java"));
}
}

View File

@ -0,0 +1,29 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 7, 2014 7:57:07 PM
*/
@Service
public class ControllerTestCodeGen extends ControllerCodeGen {
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
return render(new CodeGenArgs(
CodeGenArgs.TARGET_CONTROLLER_TEST,
"/codegen/controller-test.ftl",
dataModel,
testDir + dataModel.get("pkgDir") +
"/controller/" + model + "ControllerTest.java"));
}
}

View File

@ -0,0 +1,39 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import me.chyxion.tigon.codegen.service.CodeGenerator;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:17:13 PM
*/
@Service
public class MapperCodeGen extends CodeGenerator {
/**
* {@inheritDoc}
*/
@Override
public boolean accept(Map<String, Object> dataModel) {
return (Boolean) dataModel.get("genMapper");
}
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
return render(new CodeGenArgs(
CodeGenArgs.TARGET_MAPPER,
"/codegen/mapper.ftl",
dataModel,
codeDir + dataModel.get("pkgDir") +
"/mapper/" + model + "Mapper.java"));
}
}

View File

@ -0,0 +1,30 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 7, 2014 7:52:21 PM
*/
@Service
public class MapperTestCodeGen extends MapperCodeGen {
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
return render(new CodeGenArgs(
CodeGenArgs.TARGET_MAPPER_TEST,
"/codegen/mapper-test.ftl",
dataModel,
testDir + dataModel.get("pkgDir") +
"/mapper/" + model + "MapperTest.java"));
}
}

View File

@ -0,0 +1,37 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 5:51:27 PM
*/
@Service
public class MapperXmlCodeGen extends MapperCodeGen {
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel,
String module, String model) {
StringBuilder sbFilePath = new StringBuilder(resourcesDir)
.append("mybatis/mappers/");
if (StringUtils.isNotBlank(module)) {
sbFilePath.append(module).append("/");
}
sbFilePath.append(dataModel.get("minusJoinedModelName")).append("-mapper.xml");
return render(new CodeGenArgs(
CodeGenArgs.TARGET_MAPPER_XML,
"/codegen/mapper-xml.ftl",
dataModel,
sbFilePath.toString()));
}
}

View File

@ -0,0 +1,38 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import me.chyxion.tigon.codegen.service.CodeGenerator;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:17:42 PM
*/
@Service
public class ModelCodeGen extends CodeGenerator {
/**
* {@inheritDoc}
*/
@Override
public boolean accept(Map<String, Object> dataModel) {
return (Boolean) dataModel.get("genModel");
}
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
return render(new CodeGenArgs(
CodeGenArgs.TARGET_MODEL,
"/codegen/model.ftl",
dataModel,
codeDir + dataModel.get("pkgDir") +
"/model/" + model + ".java"));
}
}

View File

@ -0,0 +1,53 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import me.chyxion.tigon.codegen.service.CodeGenerator;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:17:30 PM
*/
@Service
public class ServiceCodeGen extends CodeGenerator {
/**
* {@inheritDoc}
*/
@Override
public boolean accept(Map<String, Object> dataModel) {
return (Boolean) dataModel.get("genService");
}
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
String pkgDir = (String) dataModel.get("pkgDir");
// interface
String strRtn = render(new CodeGenArgs(
CodeGenArgs.TARGET_SERVICE,
"/codegen/service.ftl",
dataModel,
codeDir + pkgDir +
"/service/" + model + "Service.java"));
// support
strRtn +=";";
strRtn += render(new CodeGenArgs(
CodeGenArgs.TARGET_SERVICE_SUPPORT,
"/codegen/service-support.ftl",
dataModel,
codeDir + pkgDir +
"/service/support/" + model + "ServiceSupport.java"
));
return strRtn;
}
}

View File

@ -0,0 +1,75 @@
package me.chyxion.tigon.codegen.service.support;
import java.io.File;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.core.annotation.Order;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import me.chyxion.tigon.codegen.service.CodeGenerator;
/**
* @version 0.0.2
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 7, 2014 12:23:13 PM
*/
@Service
@Order(Ordered.LOWEST_PRECEDENCE)
public class TableCodeGen extends CodeGenerator {
private static final Logger log = LoggerFactory.getLogger(TableCodeGen.class);
/**
* {@inheritDoc}
*/
@Override
public boolean accept(Map<String, Object> dataModel) {
return (Boolean) dataModel.get("genTable");
}
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
String table = (String) dataModel.get("table");
log.info("Process Generate Table [{}] SQL File.", table);
StringBuilder filePath = new StringBuilder(resourcesDir)
.append("db/");
if (StringUtils.isNotBlank(module)) {
filePath.append(module).append("/");
}
filePath.append(table).append(".sql");
render(new CodeGenArgs(
CodeGenArgs.TARGET_TABLE,
"/codegen/table.ftl",
dataModel,
filePath.toString()));
if (!Boolean.FALSE.equals(dataModel.get("createTable"))) {
// ignore drop table error
try {
log.info("Execute Drop Table [{}].", table);
baseTool.execSQL("drop table " + table);
}
catch (Exception e) {
log.info("Drop Table Failed, Error Message [{}], Ingore.",
e.getMessage());
}
// ignore execute sql error
try {
log.info("Execut Create Table SQL File [{}].", filePath);
baseTool.execSQL(new File(baseTool.getProjDir(), filePath
.toString()));
}
catch (Exception e) {
log.warn("Database Create Table Error, Ingore.", e);
}
}
return filePath.toString();
}
}

View File

@ -0,0 +1,43 @@
package me.chyxion.tigon.codegen.service.support;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import me.chyxion.tigon.codegen.model.CodeGenArgs;
import me.chyxion.tigon.codegen.service.CodeGenerator;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 6, 2014 1:17:22 PM
*/
@Service
public class ViewCodeGen extends CodeGenerator {
/**
* {@inheritDoc}
*/
@Override
public boolean accept(Map<String, Object> dataModel) {
return (Boolean) dataModel.get("genView");
}
/**
* {@inheritDoc}
*/
@Override
public String process(Map<String, Object> dataModel, String module, String model) {
StringBuilder sbFilePath = new StringBuilder(viewsDir);
if (StringUtils.isNotBlank(module)) {
sbFilePath.append(module).append("/");
}
sbFilePath.append(model).append("/List.js");
return render(new CodeGenArgs(
CodeGenArgs.TARGET_VIEW,
"/codegen/view.ftl",
dataModel,
sbFilePath.toString()));
}
}

View File

@ -0,0 +1,273 @@
package me.chyxion.tigon.codegen.utils;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.LinkedList;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;
/**
* @version 0.0.1
* @since 0.0.1
* @author Shaun Chyxion <br>
* chyxion@163.com <br>
* Oct 30, 2014 5:08:25 PM
*/
public class DbTool {
private static final Logger logger = LoggerFactory.getLogger(DbTool.class);
private static final String DEFAULT_COMMENT_PREFIX = "--";
private static final char DEFAULT_STATEMENT_SEPARATOR = ';';
/**
* Execute the given SQL script.
* <p>The script will typically be loaded from the classpath. Statements
* should be delimited with a semicolon. If statements are not delimited with
* a semicolon then there should be one statement per line. Statements are
* allowed to span lines only if they are delimited with a semicolon. Any
* line comments will be removed.
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
* @param resource the resource to load the SQL script from
* @param continueOnError whether or not to continue without throwing an
* exception in the event of an error
* @throws DataAccessException if there is an error executing a statement
* and {@code continueOnError} is {@code false}
* @see ResourceDatabasePopulator
* @see #executeSqlScript(JdbcTemplate, EncodedResource, boolean)
*/
public static void executeSqlScript(JdbcTemplate jdbcTemplate, Resource resource, boolean continueOnError)
throws DataAccessException {
executeSqlScript(jdbcTemplate, new EncodedResource(resource), continueOnError);
}
/**
* Execute the given SQL script.
* <p>The script will typically be loaded from the classpath. There should
* be one statement per line. Any semicolons and line comments will be removed.
* <p><b>Do not use this method to execute DDL if you expect rollback.</b>
* @param jdbcTemplate the JdbcTemplate with which to perform JDBC operations
* @param resource the resource (potentially associated with a specific encoding)
* to load the SQL script from
* @param continueOnError whether or not to continue without throwing an
* exception in the event of an error
* @throws DataAccessException if there is an error executing a statement
* and {@code continueOnError} is {@code false}
* @see ResourceDatabasePopulator
*/
public static void executeSqlScript(JdbcTemplate jdbcTemplate, EncodedResource resource, boolean continueOnError)
throws DataAccessException {
if (logger.isInfoEnabled()) {
logger.info("Executing SQL script from " + resource);
}
long startTime = System.currentTimeMillis();
List<String> statements = new LinkedList<String>();
LineNumberReader reader = null;
try {
reader = new LineNumberReader(resource.getReader());
String script = readScript(reader);
char delimiter = DEFAULT_STATEMENT_SEPARATOR;
if (!containsSqlScriptDelimiters(script, delimiter)) {
delimiter = '\n';
}
splitSqlScript(script, delimiter, statements);
int lineNumber = 0;
for (String statement : statements) {
lineNumber++;
try {
int rowsAffected = jdbcTemplate.update(statement);
if (logger.isDebugEnabled()) {
logger.debug(rowsAffected + " rows affected by SQL: " + statement);
}
}
catch (DataAccessException ex) {
if (continueOnError) {
if (logger.isWarnEnabled()) {
logger.warn("Failed to execute SQL script statement at line " + lineNumber
+ " of resource " + resource + ": " + statement, ex);
}
}
else {
throw ex;
}
}
}
long elapsedTime = System.currentTimeMillis() - startTime;
if (logger.isInfoEnabled()) {
logger.info(String.format("Executed SQL script from %s in %s ms.", resource, elapsedTime));
}
}
catch (IOException ex) {
throw new DataAccessResourceFailureException("Failed to open SQL script from " + resource, ex);
}
finally {
try {
if (reader != null) {
reader.close();
}
}
catch (IOException ex) {
// ignore
}
}
}
/**
* Read a script from the provided {@code LineNumberReader}, using
* "{@code --}" as the comment prefix, and build a {@code String} containing
* the lines.
* @param lineNumberReader the {@code LineNumberReader} containing the script
* to be processed
* @return a {@code String} containing the script lines
* @see #readScript(LineNumberReader, String)
*/
public static String readScript(LineNumberReader lineNumberReader) throws IOException {
return readScript(lineNumberReader, DEFAULT_COMMENT_PREFIX);
}
/**
* Read a script from the provided {@code LineNumberReader}, using the supplied
* comment prefix, and build a {@code String} containing the lines.
* <p>Lines <em>beginning</em> with the comment prefix are excluded from the
* results; however, line comments anywhere else &mdash; for example, within
* a statement &mdash; will be included in the results.
* @param lineNumberReader the {@code LineNumberReader} containing the script
* to be processed
* @param commentPrefix the prefix that identifies comments in the SQL script &mdash; typically "--"
* @return a {@code String} containing the script lines
*/
public static String readScript(LineNumberReader lineNumberReader, String commentPrefix) throws IOException {
String currentStatement = lineNumberReader.readLine();
StringBuilder scriptBuilder = new StringBuilder();
while (currentStatement != null) {
if (StringUtils.hasText(currentStatement)
&& (commentPrefix != null && !currentStatement.startsWith(commentPrefix))) {
if (scriptBuilder.length() > 0) {
scriptBuilder.append('\n');
}
scriptBuilder.append(currentStatement);
}
currentStatement = lineNumberReader.readLine();
}
return scriptBuilder.toString();
}
/**
* Determine if the provided SQL script contains the specified delimiter.
* @param script the SQL script
* @param delim character delimiting each statement &mdash; typically a ';' character
* @return {@code true} if the script contains the delimiter; {@code false} otherwise
*/
public static boolean containsSqlScriptDelimiters(String script, char delim) {
boolean inLiteral = false;
char[] content = script.toCharArray();
for (int i = 0; i < script.length(); i++) {
if (content[i] == '\'') {
inLiteral = !inLiteral;
}
if (content[i] == delim && !inLiteral) {
return true;
}
}
return false;
}
/**
* Split an SQL script into separate statements delimited by the provided
* delimiter character. Each individual statement will be added to the
* provided {@code List}.
* <p>Within a statement, "{@code --}" will be used as the comment prefix;
* any text beginning with the comment prefix and extending to the end of
* the line will be omitted from the statement. In addition, multiple adjacent
* whitespace characters will be collapsed into a single space.
* @param script the SQL script
* @param delim character delimiting each statement &mdash; typically a ';' character
* @param statements the list that will contain the individual statements
*/
public static void splitSqlScript(String script, char delim, List<String> statements) {
splitSqlScript(script, "" + delim, DEFAULT_COMMENT_PREFIX, statements);
}
/**
* Split an SQL script into separate statements delimited by the provided
* delimiter string. Each individual statement will be added to the provided
* {@code List}.
* <p>Within a statement, the provided {@code commentPrefix} will be honored;
* any text beginning with the comment prefix and extending to the end of the
* line will be omitted from the statement. In addition, multiple adjacent
* whitespace characters will be collapsed into a single space.
* @param script the SQL script
* @param delim character delimiting each statement &mdash; typically a ';' character
* @param commentPrefix the prefix that identifies line comments in the SQL script &mdash; typically "--"
* @param statements the List that will contain the individual statements
*/
private static void splitSqlScript(String script, String delim, String commentPrefix, List<String> statements) {
StringBuilder sb = new StringBuilder();
boolean inLiteral = false;
boolean inEscape = false;
char[] content = script.toCharArray();
for (int i = 0; i < script.length(); i++) {
char c = content[i];
if (inEscape) {
inEscape = false;
sb.append(c);
continue;
}
// MySQL style escapes
if (c == '\\') {
inEscape = true;
sb.append(c);
continue;
}
if (c == '\'') {
inLiteral = !inLiteral;
}
if (!inLiteral) {
if (script.startsWith(delim, i)) {
// we've reached the end of the current statement
if (sb.length() > 0) {
statements.add(sb.toString());
sb = new StringBuilder();
}
i += delim.length() - 1;
continue;
}
else if (script.startsWith(commentPrefix, i)) {
// skip over any content from the start of the comment to the EOL
int indexOfNextNewline = script.indexOf("\n", i);
if (indexOfNextNewline > i) {
i = indexOfNextNewline;
continue;
}
else {
// if there's no newline after the comment, we must be at the end
// of the script, so stop here.
break;
}
}
else if (c == ' ' || c == '\n' || c == '\t') {
// avoid multiple adjacent whitespace characters
if (sb.length() > 0 && sb.charAt(sb.length() - 1) != ' ') {
c = ' ';
}
else {
continue;
}
}
}
sb.append(c);
}
if (StringUtils.hasText(sb)) {
statements.add(sb.toString());
}
}
}

View File

@ -0,0 +1,3 @@
<#function isSelfCol col>
<#return !['id', 'date_created', 'date_updated']?seq_contains(col.col)>
</#function>

View File

@ -0,0 +1,119 @@
package ${pkg}.controllers;
<#list cols as prop>
<#if prop.javaType == 'Date'>
import java.util.Date;
<#break>
</#if>
</#list>
import java.util.Map;
import java.util.HashMap;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import ${ctrlrTestToolFullName};
${objDoc}
@WebAppConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({
"classpath*:spring/spring-*.xml",
"classpath*:spring/servlet-spring-*.xml"
})
public class ${ModelName}ControllerTest {
@Autowired
private ${ctrlrTestToolName} t;
/**
* test list
*/
@Test
public void testList() {
// TODO Modify Mock${ModelName}Mapper#listPage To Complete Test Logic
Map<String, Object> params = new HashMap<String, Object>();
params.put("start", "0");
params.put("limit", "10");
t.assertSuccess(t.print(t.get("/${url}/list")));
}
/**
* test create
*/
@Test
public void testCreate() {
// TODO Modify Mock${ModelName}Mapper#insert To Complete Test Logic
Map<String, Object> params = new HashMap<String, Object>();
<#list cols as prop>
<#if prop.javaType == 'Date'>
params.put("${prop.name}", new Date());
<#elseif prop.javaType == 'String'>
params.put("${prop.name}", "String Value");
<#elseif prop.javaType == 'boolean'>
params.put("${prop.name}", false);
<#elseif prop.javaType == 'int'>
params.put("${prop.name}", 1);
<#elseif prop.javaType == 'long'>
params.put("${prop.name}", 1L);
<#elseif prop.javaType == 'float'>
params.put("${prop.name}", 1.0F);
<#elseif prop.javaType == 'double'>
params.put("${prop.name}", 1.0D);
</#if>
</#list>
t.print(t.put("/${url}/create", params));
}
/**
* test find
*/
@Test
public void testFind() {
// TODO Modify Mock${ModelName}Mapper#find To Complete Test Logic
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", "1");
t.assertSuccess(t.print(t.get("/${url}/find", params)));
}
/**
* test update
*/
@Test
public void testUpdate() {
// TODO Modify Mock${ModelName}Mapper#update To Complete Test Logic
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", 1);
<#list cols as prop>
<#if prop.javaType == 'Date'>
params.put("${prop.name}", new Date());
<#elseif prop.javaType == 'String'>
params.put("${prop.name}", "String Value Updated");
<#elseif prop.javaType == 'boolean'>
params.put("${prop.name}", true);
<#elseif prop.javaType == 'int'>
params.put("${prop.name}", 2);
<#elseif prop.javaType == 'long'>
params.put("${prop.name}", 2L);
<#elseif prop.javaType == 'float'>
params.put("${prop.name}", 2.0F);
<#elseif prop.javaType == 'double'>
params.put("${prop.name}", 2.0D);
</#if>
</#list>
t.print(t.post("/${url}/update", params));
}
/**
* test delete one row
*/
@Test
public void testDelete0() {
// TODO Modify Mock${ModelName}Mapper#delete To Complete Test Logic
Map<String, Object> params = new HashMap<String, Object>();
params.put("id", "1");
t.assertSuccess(t.print(t.post("/${url}/delete", params)));
}
}

View File

@ -0,0 +1,14 @@
package ${pkg}.controller;
import ${pkg}.model.${ModelName};
import org.springframework.stereotype.Controller;
import ${baseControllerFullName};
import org.springframework.web.bind.annotation.RequestMapping;
${objDoc}
@Controller
@RequestMapping("/${url}")
public class ${ModelName}Controller
extends ${baseControllerName}<${ModelName}> {
}

View File

@ -0,0 +1,120 @@
package ${pkg}.mapper;
<#list imports as p>
import ${p};
</#list>
import org.junit.Assert;
import org.junit.Test;
<#if !imports?seq_contains('java.util.Date')>
import java.util.Date;
</#if>
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import ${pkg}.mapper.${ModelName}Mapper;
import ${pkg}.model.${ModelName};
${objDoc}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath*:spring/spring-*.xml")
public class ${ModelName}MapperTest extends AbstractTransactionalJUnit4SpringContextTests {
@Autowired
private ${ModelName}Mapper mapper;
@Test
public void mapperTest() {
// String id = String.valueOf(new Date().getTime());
// init model
${ModelName} m = new ${ModelName}();
String id = "id";
m.setId(id);
m.setDateCreated(new Date());
<#list cols as prop>
<#if prop.javaType == 'Date'>
m.set${prop.Name}(new Date());
<#elseif prop.javaType == 'String'>
m.set${prop.Name}("s");
<#elseif prop.javaType == 'boolean'>
m.set${prop.Name}(false);
<#elseif prop.javaType == 'int'>
m.set${prop.Name}(1);
<#elseif prop.javaType == 'long'>
m.set${prop.Name}(1L);
<#elseif prop.javaType == 'float'>
m.set${prop.Name}(1.0F);
<#elseif prop.javaType == 'double'>
m.set${prop.Name}(1.0D);
</#if>
</#list>
mapper.insert(m);
Assert.assertTrue(mapper.list(null).size() > 0);
/*
// Your Test Logics
${ModelName} m1 = mapper.find(id);
// asserts
Assert.assertEquals(id, m1.getId());
<#list cols as prop>
<#if prop.javaType == 'String'>
Assert.assertEquals("s", m.get${prop.Name}());
<#elseif prop.javaType == 'boolean'>
Assert.assertEquals(false, m.is${prop.Name}());
<#elseif prop.javaType == 'int'>
Assert.assertEquals(1, m.get${prop.Name}());
<#elseif prop.javaType == 'long'>
Assert.assertEquals(1L, m.get${prop.Name}());
<#elseif prop.javaType == 'float'>
Assert.assertEquals(1.0F, m.get${prop.Name}());
<#elseif prop.javaType == 'double'>
Assert.assertEquals(1.0D, m.get${prop.Name}());
</#if>
</#list>
// update
m.setDateUpdated(new Date());
<#list cols as prop>
<#if prop.javaType == 'Date'>
m.set${prop.Name}(new Date());
<#elseif prop.javaType == 'String'>
m.set${prop.Name}("S");
<#elseif prop.javaType == 'boolean'>
m.set${prop.Name}(true);
<#elseif prop.javaType == 'int'>
m.set${prop.Name}(2);
<#elseif prop.javaType == 'long'>
m.set${prop.Name}(2L);
<#elseif prop.javaType == 'float'>
m.set${prop.Name}(2.0F);
<#elseif prop.javaType == 'double'>
m.set${prop.Name}(2.0D);
</#if>
</#list>
mapper.update(m);
m1 = mapper.find(id);
// asserts
Assert.assertEquals(id, m1.getId());
Assert.assertNotNull(m1.getDateUpdated());
<#list cols as prop>
<#if prop.javaType == 'String'>
Assert.assertEquals("S", m.get${prop.Name}());
<#elseif prop.javaType == 'boolean'>
Assert.assertEquals(true, m.is${prop.Name}());
<#elseif prop.javaType == 'int'>
Assert.assertEquals(2, m.get${prop.Name}());
<#elseif prop.javaType == 'long'>
Assert.assertEquals(2L, m.get${prop.Name}());
<#elseif prop.javaType == 'float'>
Assert.assertEquals(2.0F, m.get${prop.Name}());
<#elseif prop.javaType == 'double'>
Assert.assertEquals(2.0D, m.get${prop.Name}());
</#if>
</#list>
// list
Assert.assertTrue(mapper.list(null).size() > 0);
// delete
mapper.delete(id);
m1 = mapper.find(id);
Assert.assertNull(m1);
*/
}
}

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
${objDoc}
-->
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${pkg}.mapper.${ModelName}Mapper">
<#if cacheEnabled>
<!-- Redis Cache -->
<cache type="me.chyxion.tigon.mybatis.cache.RedisCache" />
</#if>
</mapper>

View File

@ -0,0 +1,9 @@
package ${pkg}.mapper;
import ${baseMapperFullName};
import ${pkg}.model.${ModelName};
${objDoc}
public interface ${ModelName}Mapper extends ${baseMapperName}<${idType}, ${ModelName}> {
}

View File

@ -0,0 +1,31 @@
package ${pkg}.model;
<#import "/codegen/commons.ftl" as CodeGen>
import lombok.Getter;
import lombok.Setter;
import ${tableAnnotationClassName};
<#if baseModelFullName?has_content>
import ${baseModelFullName};
</#if>
<#list imports as p>
import ${p};
</#list>
${objDoc}
@Getter
@Setter
@${tableAnnotationName}("${table}")
public class ${ModelName} extends ${baseModelName} {
private static final long serialVersionUID = 1L;
// Column Names
<#list cols as prop>
public static final String ${prop.col?upper_case} = "${prop.col}";
</#list>
// Properties
<#list cols as prop>
private ${prop.javaType} ${prop.name};
</#list>
}

View File

@ -0,0 +1,7 @@
/**
* @version 0.0.1
* @since 0.0.1
* @author Auto Generated <br>
* Tech Support <a href="mailto:chyxion@163.com">Shaun Chyxion</a><br>
* ${now}
*/

View File

@ -0,0 +1,15 @@
package ${pkg}.services.support;
import org.springframework.stereotype.Service;
import ${baseServiceSupportFullName};
import ${pkg}.mappers.${ModelName}Mapper;
import ${pkg}.models.${ModelName};
import ${pkg}.services.${ModelName}Service;
${objDoc}
@Service
public class ${ModelName}ServiceSupport
extends ${baseServiceSupportName}<${ModelName}, ${ModelName}Mapper>
implements ${ModelName}Service {
}

View File

@ -0,0 +1,9 @@
package ${pkg}.services;
import ${baseServiceFullName};
import ${pkg}.models.${ModelName};
${objDoc}
public interface ${ModelName}Service extends ${baseServiceName}<${ModelName}> {
}

View File

@ -0,0 +1,10 @@
${objDoc}
create table ${table} (
id varchar(36) not null primary key,
date_created datetime not null,
date_updated datetime,
<#list cols as col>
${col.col} ${col.sqlType} ${col.notNull?string('not null', '')}<#if col_has_next>,</#if>
</#list>
);

View File

@ -0,0 +1,179 @@
${objDoc}
Ext.define('App.views.${module?matches(r"\s*")?string('', module + '.')}${ModelName}.List', {
extend: 'Tigon.views.Grid',
requires: ['Ext.ux.DataTip'],
title: '${ModelName} List',
selModel: Ext.create('Ext.selection.CheckboxModel'),
paging_bar: true,
store: Store.create({
pageSize: 99,
remoteSort: true,
url: '${url}/list',
fields: ['id',
<#list cols as col>
<#if col.javaType == 'Date'>
{
name: '${col.name}',
type: 'date',
dateFormat: 'time'
}
<#else>
'${col.name}'
</#if>,
</#list>
'dateCreated',
'dateUpdated'
]
}),
columns: [{
xtype: 'rownumberer'
},
<#list cols as col>
{
<#if col.javaType == 'Date'>
renderer: Utils.date_renderer(),
width: 128,
<#else>
flex: 1,
</#if>
dataIndex: '${col.name}',
text: '${col.Name}'
},
</#list>
{
renderer: Utils.date_renderer(),
width: 128,
dataIndex: 'dateCreated',
text: 'Date Created'
},
{
renderer: Utils.date_renderer(),
width: 128,
dataIndex: 'dateUpdated',
text: 'Date Updated'
}],
tbar: [{
text: 'Refresh',
iconCls: 'refresh',
handler: function () {
this.up('grid').getStore().loadPage(1);
}
}, {
text: 'New ${ModelName}',
iconCls: 'add',
handler: function () {
this.up('grid').show_dlg('post');
}
}, {
text: 'Edit ${ModelName}',
iconCls: 'edit',
handler: function () {
var g = this.up('grid'),
rec = g.getSelectionModel().getLastSelected();
if (rec) {
g.show_dlg('put', function() {
this.down('form').loadRecord(rec);
});
}
else {
Message.warn('Please Select ${ModelName} To Edit.');
}
}
}, {
text: 'Remove',
iconCls: 'remove',
handler: function () {
var g = this.up('grid'),
rec = g.getSelectionModel().getLastSelected();
if (rec) {
Dialog.confirm('Are You Sure To Remove The ${ModelName} Selected?', function() {
Ajax.post('${url}/delete', {
id: rec.get('id')
}, function() {
g.getStore().remove(rec);
Message.alert('${ModelName} Removed Successfully.');
});
});
}
else {
Message.warn('Please Select Row To Remove.');
}
}
}],
show_dlg: function(type, fn) {
var me = this,
w, title, icon;
if (type == 'put') {
title = 'Edit ${ModelName}';
icon = 'edit';
}
else {
title = 'New ${ModelName}';
icon = 'add';
}
w = Ext.create('Ext.Window', {
title: title,
iconCls: icon,
closable: true,
modal: true,
plain: true,
layout: 'fit',
items: {
xtype: 'form',
layout: 'form',
url: '${url}/' + (type == 'put' ? 'update' : 'create'),
bodyPadding: '12',
waitMsgTarget: true,
border: 0,
width: 350,
defaultType: 'textfield',
fieldDefaults: {
msgTarget: 'side',
labelWidth: 75
},
plugins: {
ptype: 'datatip'
},
items: [
<#list cols as col>
{
<#if col.javaType == 'Date'>
xtype: 'datefield',
submitFormat: 'Y-m-d H:i:s',
</#if>
<#if col.notNull>
afterLabelTextTpl: me.required,
allowBlank: false,
</#if>
fieldLabel: '${col.Name}',
name: '${col.name}'
},
</#list>
{
xtype: 'hiddenfield',
name: 'id'
}]
},
buttons: [{
text: 'Save',
iconCls: 'ok',
handler: function() {
var w = this.up('window');
Ajax.post(w.down('form'), function() {
Message.alert('${ModelName} Saved Successfully.');
w.close();
me.getStore().load();
me.getSelectionModel().deselectAll();
});
}
}, {
text: 'Cancel',
iconCls: 'cancel',
handler: function() {
this.up('window').close();
}
}]
});
w.show(null, fn, w);
}
});

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- Scan Code Gen -->
<context:component-scan base-package="me.chyxion.tigon.codegen" />
</beans>

View File

@ -0,0 +1,437 @@
/**
* @version 0.0.2
* @since 0.0.1
* @author Shaun Chyxion <br />
* chyxion@163.com
* Dec 05, 2014 11:39:58
*/
Ext.define ('Tigon.views.CodeGen', {
extend: 'Ext.container.Container',
alternateClassName: ['SpringExt.views.CodeGen'],
title: 'Auto Code',
layout: 'border',
items: [{
xtype: 'container',
region: 'west',
split: true,
layout: 'border',
width: 186,
defaults: {
xtype: 'treepanel'
},
items: [{
title: 'Items Generated',
split: true,
height: 286,
region: 'north',
tbar: [{
text: 'Remove Model',
name: 'btn_remove',
disabled: true,
iconCls: 'remove',
handler: function () {
var t = this.up('treepanel');
Ext.MessageBox.show({
title: 'Are You Sure?',
msg: 'Are You Sure To Remove Model(s) Selected Without Drop Tables?',
buttons: Ext.MessageBox.YESNOCANCEL,
fn: function(btn) {
if (btn != 'cancel') {
var items = [];
Ext.Array.each(t.getView().getChecked(), function(rec) {
items.push({
module: rec.get('module'),
model: rec.get('model')
});
});
if (!items.length) {
var rec = t.getSelectionModel().getLastSelected();
items.push({
module: rec.get('module'),
model: rec.get('model')
});
}
Ajax.del('codegen', {
items: items,
dropTable: btn == 'no'
}, function() {
t.getStore().reload();
// right container
var rc = t.up().next('container'),
form = rc.down('form');
form.getForm().reset();
form.down('grid').getStore().removeAll();
// remove demo grid
rc.down('container[name=demo_grid]').removeAll();
Message.alert('Remove Success.');
});
}
},
icon: Ext.MessageBox.QUESTION
});
}
}],
store: Store.tree({
url: 'codegen/list',
fields: ['text', 'name', 'module', 'model', 'cols', 'table'],
root_text: 'Models'
}),
listeners: {
select: function(rm, rec) {
this.down('toolbar')
.down('button[name=btn_remove]')
.setDisabled(!rec.isLeaf());
if (rec.isLeaf()) {
// right container
var rc = this.up().next('container'),
form = rc.down('form');
form.getForm().setValues(rec.getData());
form.down('grid').getStore().loadData(rec.get('cols'));
// show demo grid
var dg = rc.down('container[name=demo_grid]');
dg.removeAll();
// load view
dg.add(Ext.create('App.views.' +
(rec.get('module') ? rec.get('module') + '.' : '') +
rec.get('model') + '.List'));
}
}
}
}, {
title: 'Tables',
split: true,
region: 'center',
store: Store.tree({
url: 'codegen/tables',
fields: ['id', 'text', 'module', 'model', 'cols', 'table'],
root_text: 'Tables'
}),
listeners: {
select: function(rm, rec) {
if (rec.isLeaf()) {
// right container
var rc = this.up().next('container');
form = rc.down('form');
form.getForm().setValues(Ext.merge(rec.getData(), {
createTable: false
}));
form.down('grid').getStore().loadData(rec.get('cols'));
// show demo grid
var dg = rc.down('container[name=demo_grid]');
dg.removeAll();
// load view
dg.add(Ext.create('App.views.' +
(rec.get('module') ? rec.get('module') + '.' : '') +
rec.get('model') + '.List'));
}
}
}
}]
}, {
xtype: 'container',
region: 'center',
layout: 'border',
items: [{
xtype: 'form',
region: 'north',
split: true,
height: 312,
autoScroll: true,
bodyPadding: 12,
layout: 'vbox',
defaults: {
width: '96%',
labelWidth: 86
},
tbar: [{
text: 'New Model',
iconCls: 'add',
handler: function(btn) {
var form = btn.up('form'),
s = form.down('grid').getStore();
s.removeAll();
s.add({
name: 'id',
javaType: 'String',
col: 'id',
sqlType: 'varchar(36)'
}, {
name: 'dateCreated',
javaType: 'Date',
col: 'date_created',
sqlType: 'datetime'
}, {
name: 'dateUpdated',
javaType: 'Date',
col: 'date_updated',
sqlType: 'datetime'
});
}
}, {
text: 'Generate!',
iconCls: 'save',
handler: function(btn) {
var form = btn.up('form');
if (form.isValid()) {
var s = form.down('grid').getStore();
if (s.getCount()) {
var params = form.getForm().getValues(),
columns = [];
s.each(function(rec) {
columns.push(rec.getData());
});
params.columns = columns;
Dialog.confirm(s.collect('isKey').length > 1 ?
'Are You Sure To Submit?' :
'No Primary Key, Are You Sure To Submit?', function() {
Ajax.post('codegen', params, function() {
form.up().previousNode('treepanel')
.previousNode('treepanel')
.getStore()
.reload();
Message.alert('Generate Success.');
});
});
}
else {
Message.warn('No Columns.');
}
}
}
}],
items: [{
xtype: 'box',
html: [
'<span style="color: #333;">Note: </span>',
'Welcome.'
].join(''),
padding: '0 0 12 0',
style: {
fontSize: '12pt',
color: '#00F'
},
}, {
fieldLabel: 'Options',
xtype: 'checkboxgroup',
defaults: {
checked: true,
xtype: 'checkbox',
inputValue: true
},
columns: 3,
items: [{
boxLabel: 'Gen Controller',
name: 'genController'
}, {
boxLabel: 'Gen Service',
name: 'genService'
}, {
boxLabel: 'Gen Mapper',
name: 'genMapper'
}, {
boxLabel: 'Gen Model',
name: 'genModel'
}, {
boxLabel: 'Gen Table',
name: 'genTable'
}, {
boxLabel: 'Gen View',
checked: false,
name: 'genView'
}, {
boxLabel: 'Create Table',
checked: false,
name: 'createTable'
}]
}, {
xtype: 'fieldcontainer',
fieldLabel: 'Columns',
items: {
xtype: 'grid',
minHeight: 128,
plugins: [Ext.create('Ext.grid.plugin.CellEditing', {
clicksToEdit: 1
})],
store: {
store: 'json',
fields: ['name', 'javaType', 'col', 'sqlType',
{name: 'notNull', type: 'boolean', defaultValue: true},
{name: 'isKey', type: 'boolean', defaultValue: false},
{name: 'isIndex', type: 'boolean', defaultValue: false}]
},
columns: [{
xtype: 'rownumberer'
}, {
dataIndex: 'name',
text: 'Property Name',
width: 128,
editor: {
xtype: 'textfield',
allowBlank: false,
listeners: {
change: function(t, nv, ov) {
t.up().up()
.getSelectionModel()
.getLastSelected()
.set('col',
nv.split(/(?=[A-Z])(?=[A-Z][a-z])|(?=[^A-Z])(?=[A-Z])|(?=[^a-zA-Z])(?=[a-z])|(?=[A-Za-z])(?=[^A-Za-z])/)
.join('_').
toLowerCase());
}
}
}
}, {
dataIndex: 'javaType',
text: 'Java Type',
flex: 1,
editor: {
xtype: 'combo',
typeAhead: true,
editable: false,
triggerAction: 'all',
store: [
['String', 'String'],
['int', 'int'],
['Integer', 'Integer'],
['long', 'long'],
['Long', 'Long'],
['double', 'double'],
['Double', 'Double'],
['Date', 'Date'],
['boolean', 'boolean'],
['Boolean', 'Boolean'],
['byte', 'byte'],
['Byte', 'Byte'],
['byte[]', 'byte[]'],
['Byte[]', 'Byte[]']
]
}
}, {
dataIndex: 'col',
text: 'Column Name',
width: 128,
editor: {
xtype: 'textfield'
}
}, {
dataIndex: 'sqlType',
text: 'SQL Type',
flex: 1,
editor: {
allowBlank: false,
xtype: 'combo',
typeAhead: true,
editable: true,
triggerAction: 'all',
store: [
['date', 'date'],
['datetime', 'datetime'],
['char(36)', 'char(36)'],
['varchar(36)', 'varchar(36)'],
['bit', 'bit'],
['bigint', 'bigint'],
['int', 'int'],
['float', 'float']
]
}
}, {
dataIndex: 'notNull',
text: 'Not Null',
width: 76,
renderer: function(v) {
return v || '';
},
editor: {
xtype: 'checkbox',
inputValue: true
}
}, {
dataIndex: 'isKey',
text: 'Primary Key',
width: 76,
renderer: function(v) {
return v || '';
},
editor: {
xtype: 'checkbox',
inputValue: true
}
}],
tbar: [{
text: 'Add Column',
iconCls: 'add',
handler: function () {
var s = this.up('grid').getStore(),
name = 0;
Ext.each(s.collect('name'), function(col) {
var m = col.match(/^name(\d*)$/);
if (m) {
var num = parseInt(m[1]);
if (isNaN(num)) {
name = 1;
}
else if (num + 1 > name) {
name = num + 1;
}
}
});
name = 'name' + (name ? name : '');
s.add({
name: name,
javaType: 'String',
col: name,
sqlType: 'varchar(36)',
notNull: true,
isKey: false
});
}
}, {
text: 'Remove Column',
iconCls: 'remove',
handler: function (btn) {
var g = btn.up('grid'),
ss = g.getSelectionModel().getSelection();
if (ss.length) {
Dialog.confirm(
'Are You Sure To Remove The Column Selected.',
function() {
g.getStore().remove(ss);
});
}
else {
Message.warn('Please Select Column To Remove.');
}
}
}]
}
}, {
xtype: 'textfield',
name: 'pkg',
fieldLabel: 'Base Package',
allowBlank: true,
emptyText: 'Default Base Package (' + pkg + ').'
}, {
xtype: 'textfield',
name: 'module',
fieldLabel: 'Module',
emptyText: 'Subpackage Of Base Package.'
}, {
xtype: 'textfield',
name: 'model',
fieldLabel: 'Model Name',
value: 'ModelName',
allowBlank: false
}, {
xtype: 'textfield',
name: 'table',
fieldLabel: 'Table Name',
allowBlank: false
}]
}, {
xtype: 'container',
region: 'center',
name: 'demo_grid',
layout: 'fit'
}]
}]
});

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
<#include "/commons/extjs-header.ftl" />
<script type="text/javascript">
/**
* @version 1.0
* @author Shaun Chyxion <br />
* chyxion@163.com <br />
* Dec 05, 2014 15:49:16
*/
Ext.onReady(function() {
Ext.QuickTips.init();
Ext.create('Ext.Viewport', {
layout: 'border',
items: [{
xtype: 'box',
region: 'north',
html: '<h1>Super Super Code!</h1>'
},
Ext.create('Tigon.views.CodeGen', {
region: 'center'
})
]
});
Ext.create('Tigon.views.ThemesBar').show();
});
var pkg = '${pkg}';
</script>
<title>Auto Code</title>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,8 @@
/**
* @version 0.0.1
* @since 0.0.1
* @author chyxion <br>
* chyxion@163.com <br>
* Oct 18, 2015 1:09:11 PM
*/
package me.chyxion.tigon.codegen.test;

View File

@ -0,0 +1 @@
# I18n Messages

View File

@ -0,0 +1,13 @@
log4j.rootLogger=debug, console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.Encoding=utf-8
log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%F:%L] %m%n
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%F:%L] %m%n
log4j.appender.file.File=${log.dir}/${project.artifactId}-test.log
log4j.appender.file.Encoding=utf-8

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* @version 0.0.1
* @since 0.0.1
* @author Auto Generated <br />
* Tech Support <a href="mailto:chyxion@163.com">Shaun Chyxion</a><br />
* Apr 11, 2015 11:12:10 AM
*/
-->
<!DOCTYPE mapper PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.com.flaginfo.echat.mappers.TableTestMapper">
<resultMap id="modelMap" type="TableTest">
<id column="id" property="id" />
<id column="name" property="name" />
<result column="date_created" property="dateCreated" />
<result column="date_updated" property="dateUpdated" />
<result column="type" property="type" />
</resultMap>
<!-- variables -->
<sql id="columns">
id, name, date_created, date_updated
</sql>
<sql id="table">
table_test
</sql>
<sql id="updateClause">
update <include refid="table" />
<set>
<if test="model.name != null">
name = #{model.name}
</if>
</set>
</sql>
<!-- /variables -->
<!-- methods -->
<!-- Insert Models -->
<insert id="insert">
insert into <include refid="table" />
(<include refid="columns" />) values
<foreach item="model" collection="models" separator=", ">
(#{model.id}, #{model.name}, #{model.dateCreated}, #{model.dateUpdated})
</foreach>
</insert>
<!-- Update By Key -->
<update id="update">
<foreach item="model" collection="models" separator="; ">
<include refid="updateClause" />
where id = #{model.id}
</foreach>
</update>
<!-- Update By Condition -->
<update id="updateBy">
<bind name="key" value="'id'" />
<include refid="updateClause" />
<include refid="Commons.search" />
</update>
<!-- Delete -->
<delete id="delete">
<bind name="key" value="'id'" />
delete from <include refid="table" />
<include refid="Commons.search" />
</delete>
<!-- Find One -->
<select id="find" resultMap="modelMap">
<bind name="key" value="'id'" />
<include refid="Commons.selectAllFromTable" />
<include refid="Commons.search" />
</select>
<!-- List -->
<select id="list" resultMap="modelMap">
<bind name="key" value="'id'" />
<include refid="Commons.selectAllFromTable" />
<include refid="Commons.search" />
</select>
<!-- List Page All -->
<select id="listPage" resultMap="modelMap">
<!-- Default List All -->
<include refid="Commons.selectAllFromTable" />
</select>
<!-- List Page By Condition -->
<select id="listPageBy" resultMap="modelMap">
<include refid="Commons.selectAllFromTable" />
<include refid="Commons.search" />
<!-- TODO: Your Query Logics Are Here, For Example: -->
<!-- <if test="s != null"> -->
<!-- where name like #{s} -->
<!-- </if> -->
</select>
<!-- /methods -->
</mapper>

View File

@ -0,0 +1,11 @@
# Config Dev
# Database
db.url=jdbc:mysql://10.0.0.31/yxt?useUnicode=true&characterEncoding=utf8
db.user=yxt
db.password=yxt402
# Redis
redis.host=127.0.0.1
redis.port=6379
redis.password=0211

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="byName">
<!-- Scan Mock -->
<context:component-scan base-package="me.chyxion.tigon.webmvc.test"
use-default-filters="false">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Service" />
</context:component-scan>
<bean class="me.chyxion.tigon.webmvc.test.ControllerTestTool" />
</beans>

1
tigon-extjs/README.md Normal file
View File

@ -0,0 +1 @@
# tigon-extjs

19
tigon-extjs/pom.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>tigon-extjs</artifactId>
<packaging>jar</packaging>
<name>Tigon Ext JS</name>
<description>Tigon Ext JS</description>
<parent>
<groupId>me.chyxion.tigon</groupId>
<artifactId>tigon</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../</relativePath>
</parent>
</project>

View File

View File

@ -0,0 +1,74 @@
html {
font-family: 'Microsoft YaHei'
}
/* message styles */
#commons-message-div {
position: absolute;
left: 35%;
top: 10px;
width: 300px;
z-index: 20000;
}
#commons-message-div .msg {
border-radius: 8px;
-moz-border-radius: 8px;
border: 1px solid #ccc;
margin-top: 2px;
font-size: 14px;
padding: 10px 15px;
color: #555;
}
/* normal */
#commons-message-div .bg-alert {
background: #F6F6F6;
}
/* warn */
#commons-message-div .bg-warn {
background: #F6F0F0;
}
/* header */
#commons-message-div .msg h3 {
margin: 0 0 8px;
font-weight: bold;
font-size: 15px;
}
/* content */
#commons-message-div .msg p {
margin: 0;
}
/* end message dlg */
/* tree icons */
.x-grid-tree-node-expanded .x-tree-icon-parent {
background: url(../images/tree-node-expanded.png) no-repeat center center !important;
}
.x-tree-icon-parent {
background: url(../images/tree-node.png) no-repeat center center !important;
}
.x-grid-row .x-tree-icon-leaf {
background-image: url(../images/leaf.png);
}
/* end tree icons */
/* custom icons */
.add {
background-image: url(../images/add.gif);
}
.edit {
background-image: url(../images/edit.png);
}
.refresh {
background-image: url(../images/reload.png);
}
.remove {
background-image: url(../images/delete.gif);
}
.ok {
background-image: url(../images/okay.png);
}
.cancel {
background-image: url(../images/close.png);
}
.save {
background-image: url(../images/save.png);
}
/* end custom icons */

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,295 @@
/*
This file is part of Ext JS 4.2
Copyright (c) 2011-2013 Sencha Inc
Contact: http://www.sencha.com/contact
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.
Build date: 2013-05-16 14:36:50 (f9be68accb407158ba2b1be2c226a6ce1f649314)
*/
/**
* Simplified Chinese translation
* By DavidHu
* 09 April 2007
*
* update by andy_ghg
* 2009-10-22 15:00:57
*/
Ext.onReady(function() {
var parseCodes;
if (Ext.Date) {
Ext.Date.monthNames = ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"];
Ext.Date.dayNames = ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"];
Ext.Date.formatCodes.a = "(this.getHours() < 12 ? '上午' : '下午')";
Ext.Date.formatCodes.A = "(this.getHours() < 12 ? '上午' : '下午')";
parseCodes = {
g: 1,
c: "if (/(上午)/i.test(results[{0}])) {\n"
+ "if (!h || h == 12) { h = 0; }\n"
+ "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
s: "(上午|下午)",
calcAtEnd: true
};
Ext.Date.parseCodes.a = Ext.Date.parseCodes.A = parseCodes;
}
if (Ext.util && Ext.util.Format) {
Ext.apply(Ext.util.Format, {
thousandSeparator: ',',
decimalSeparator: '.',
currencySign: '\u00a5',
// Chinese Yuan
dateFormat: 'y年m月d日'
});
}
});
Ext.define("Ext.locale.zh_CN.view.View", {
override: "Ext.view.View",
emptyText: ""
});
Ext.define("Ext.locale.zh_CN.grid.plugin.DragDrop", {
override: "Ext.grid.plugin.DragDrop",
dragText: "选择了 {0} 行"
});
Ext.define("Ext.locale.zh_CN.tab.Tab", {
override: "Ext.tab.Tab",
closeText: "关闭此标签"
});
Ext.define("Ext.locale.zh_CN.form.field.Base", {
override: "Ext.form.field.Base",
invalidText: "输入值非法"
});
// changing the msg text below will affect the LoadMask
Ext.define("Ext.locale.zh_CN.view.AbstractView", {
override: "Ext.view.AbstractView",
loadingText: "讀取中..."
});
Ext.define("Ext.locale.zh_CN.picker.Date", {
override: "Ext.picker.Date",
todayText: "今天",
minText: "日期必须大于最小允许日期",
//update
maxText: "日期必须小于最大允许日期",
//update
disabledDaysText: "",
disabledDatesText: "",
nextText: '下个月 (Ctrl+Right)',
prevText: '上个月 (Ctrl+Left)',
monthYearText: '选择一个月 (Control+Up/Down 来改变年份)',
//update
todayTip: "{0} (空格键选择)",
format: "y年m月d日",
ariaTitle: '{0}',
ariaTitleDateFormat: 'Y\u5e74m\u6708d\u65e5',
longDayFormat: 'Y\u5e74m\u6708d\u65e5',
monthYearFormat: 'Y\u5e74m\u6708',
getDayInitial: function (value) {
// Grab the last character
return value.substr(value.length - 1);
}
});
Ext.define("Ext.locale.zh_CN.picker.Month", {
override: "Ext.picker.Month",
okText: "确定",
cancelText: "取消"
});
Ext.define("Ext.locale.zh_CN.toolbar.Paging", {
override: "Ext.PagingToolbar",
beforePageText: "第",
//update
afterPageText: "页,共 {0} 页",
//update
firstText: "第一页",
prevText: "上一页",
//update
nextText: "下一页",
lastText: "最后页",
refreshText: "刷新",
displayMsg: "显示 {0} - {1}条,共 {2} 条",
//update
emptyMsg: '没有数据'
});
Ext.define("Ext.locale.zh_CN.form.field.Text", {
override: "Ext.form.field.Text",
minLengthText: "该输入项的最小长度是 {0} 个字符",
maxLengthText: "该输入项的最大长度是 {0} 个字符",
blankText: "该输入项为必输项",
regexText: "",
emptyText: null
});
Ext.define("Ext.locale.zh_CN.form.field.Number", {
override: "Ext.form.field.Number",
minText: "该输入项的最小值是 {0}",
maxText: "该输入项的最大值是 {0}",
nanText: "{0} 不是有效数值"
});
Ext.define("Ext.locale.zh_CN.form.field.Date", {
override: "Ext.form.field.Date",
disabledDaysText: "禁用",
disabledDatesText: "禁用",
minText: "该输入项的日期必须在 {0} 之后",
maxText: "该输入项的日期必须在 {0} 之前",
invalidText: "{0} 是无效的日期 - 必须符合格式: {1}",
format: "y年m月d日"
});
Ext.define("Ext.locale.zh_CN.form.field.ComboBox", {
override: "Ext.form.field.ComboBox",
valueNotFoundText: undefined
}, function() {
Ext.apply(Ext.form.field.ComboBox.prototype.defaultListConfig, {
loadingText: "加载中..."
});
});
Ext.define("Ext.locale.zh_CN.form.field.VTypes", {
override: "Ext.form.field.VTypes",
emailText: '该输入项必须是电子邮件地址,格式如: "user@example.com"',
urlText: '该输入项必须是URL地址格式如 "http:/' + '/www.example.com"',
alphaText: '该输入项只能包含半角字母和_',
alphanumText: '该输入项只能包含半角字母,数字和_'
});
//add HTMLEditor's tips by andy_ghg
Ext.define("Ext.locale.zh_CN.form.field.HtmlEditor", {
override: "Ext.form.field.HtmlEditor",
createLinkText: '添加超级链接:'
}, function() {
Ext.apply(Ext.form.field.HtmlEditor.prototype, {
buttonTips: {
bold: {
title: '粗体 (Ctrl+B)',
text: '将选中的文字设置为粗体',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
italic: {
title: '斜体 (Ctrl+I)',
text: '将选中的文字设置为斜体',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
underline: {
title: '下划线 (Ctrl+U)',
text: '给所选文字加下划线',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
increasefontsize: {
title: '增大字体',
text: '增大字号',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
decreasefontsize: {
title: '缩小字体',
text: '减小字号',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
backcolor: {
title: '以不同颜色突出显示文本',
text: '使文字看上去像是用荧光笔做了标记一样',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
forecolor: {
title: '字体颜色',
text: '更改字体颜色',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
justifyleft: {
title: '左对齐',
text: '将文字左对齐',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
justifycenter: {
title: '居中',
text: '将文字居中对齐',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
justifyright: {
title: '右对齐',
text: '将文字右对齐',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
insertunorderedlist: {
title: '项目符号',
text: '开始创建项目符号列表',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
insertorderedlist: {
title: '编号',
text: '开始创建编号列表',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
createlink: {
title: '转成超级链接',
text: '将所选文本转换成超级链接',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
},
sourceedit: {
title: '代码视图',
text: '以代码的形式展现文本',
cls: Ext.baseCSSPrefix + 'html-editor-tip'
}
}
});
});
Ext.define("Ext.locale.zh_CN.grid.header.Container", {
override: "Ext.grid.header.Container",
sortAscText: "正序",
//update
sortDescText: "倒序",
//update
lockText: "锁定列",
//update
unlockText: "解除锁定",
//update
columnsText: "列"
});
Ext.define("Ext.locale.zh_CN.grid.PropertyColumnModel", {
override: "Ext.grid.PropertyColumnModel",
nameText: "名称",
valueText: "值",
dateFormat: "y年m月d日"
});
Ext.define("Ext.locale.zh_CN.window.MessageBox", {
override: "Ext.window.MessageBox",
buttonText: {
ok: "确定",
cancel: "取消",
yes: "是",
no: "否"
}
});
// This is needed until we can refactor all of the locales into individual files
Ext.define("Ext.locale.zh_CN.Component", {
override: "Ext.Component"
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1010 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1005 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 839 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 208 B

Some files were not shown because too many files have changed in this diff Show More