You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by ni...@apache.org on 2019/07/22 02:54:07 UTC

[servicecomb-toolkit] 01/02: SCB-1384 refact the code to optimize user experience

This is an automated email from the ASF dual-hosted git repository.

ningjiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-toolkit.git

commit 95a0fc9088c3dfc0977878fa91e386d9250d58ca
Author: MabinGo <bi...@huawei.com>
AuthorDate: Thu Jul 18 00:06:06 2019 +0800

    SCB-1384 refact the code to optimize user experience
    
    Signed-off-by: MabinGo <bi...@huawei.com>
---
 README-ZH.md                                       | 183 +++++++++++++--------
 README.md                                          | 182 ++++++++++++--------
 .../toolkit/codegen/ServiceCombCodegen.java        |  13 +-
 .../resources/ServiceComb/project/pom.mustache     |   7 -
 .../servicecomb/toolkit/common}/ClassMaker.java    |   2 +-
 .../toolkit/common/ContractFileType.java}          |  30 ++--
 .../servicecomb/toolkit/common/ContractsUtils.java |  72 --------
 .../servicecomb/toolkit/common/FileUtils.java      | 104 ++++++++++++
 .../servicecomb/toolkit/common/FileUtilsTest.java  |  64 +++++++
 ...g.apache.servicecomb.toolkit.ContractsGenerator |  18 --
 {toolkit-maven-plugin => contractgen}/pom.xml      |  84 ++--------
 .../contractgen}/DefaultContractsGenerator.java    |  60 ++++---
 ...g.apache.servicecomb.toolkit.ContractsGenerator |   2 +-
 .../contractgen/DefaultContractsGeneratorTest.java | 150 +++++++++++++++++
 .../src/test/projects/demo/pom.xml                 |  14 --
 .../demo}/src/main/java/demo/Application.java      |   0
 .../demo/src/main/java/demo/HelloEndPoint.java     |  34 ++--
 .../docgen/ContractsSwaggerUIGenerator.java        |   7 +-
 .../docgen/ContractsSwaggerUIGeneratorTest.java}   |  31 ++--
 pom.xml                                            |   8 +
 toolkit-maven-plugin/pom.xml                       |  10 ++
 .../toolkit/plugin/ContractGenerator.java          |  69 --------
 .../toolkit/plugin/GenerateContractsDocMojo.java   | 138 ----------------
 .../toolkit/plugin/GenerateContractsMojo.java      |  59 -------
 .../servicecomb/toolkit/plugin/GenerateMojo.java   | 107 ++++++++++++
 .../servicecomb/toolkit/plugin/GenerateUtil.java   |  90 ++++++++++
 .../{VerifyContractsMojo.java => VerifyMojo.java}  |  65 ++++----
 .../toolkit/plugin/GenerateMojoTest.java           | 145 ++++++++++++++++
 .../toolkit/plugin/GenerateUtilTest.java           |  77 +++++++++
 .../java/plugin/GenerateContractsDocMojoTest.java  | 172 -------------------
 .../java/plugin/GenerateContractsMojoTest.java     |  91 ----------
 .../demo-with-contract/pom-gencontract.xml         |   4 -
 .../src/test/projects/demo-with-contract/pom.xml   |   5 +-
 .../pom-gencontract.xml                            |   0
 .../pom.xml                                        |   5 +-
 .../src/main/java/demo/Application.java            |   0
 36 files changed, 1135 insertions(+), 967 deletions(-)

diff --git a/README-ZH.md b/README-ZH.md
index 8f65b21..8cb2023 100755
--- a/README-ZH.md
+++ b/README-ZH.md
@@ -1,4 +1,4 @@
-# Toolkit | [English](./README.md) [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![Gitter](https://img.shields.io/badge/ServiceComb-Gitter-ff69b4.svg)](https://gitter.im/ServiceCombUsers/Lobby)
+# Toolkit | [English](./README.md) [![Build Status](https://travis-ci.org/apache/servicecomb-toolkit.svg?branch=master)](https://travis-ci.org/apache/servicecomb-toolkit?branch=master)[![Coverage Status](https://coveralls.io/repos/github/apache/servicecomb-toolkit/badge.svg?branch=master)](https://coveralls.io/github/apache/servicecomb-toolkit?branch=master)[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) [![Gitter [...]
 
 Apache ServiceComb Toolkit 是基于契约的微服务开发工具套件
 
@@ -22,7 +22,7 @@ Apache ServiceComb Toolkit 是基于契约的微服务开发工具套件
 
 * 契约与代码一致性校验
 
-  校验应用的实际实现(如数据和服务API)是否与达成共识的服务契约描述一致。
+  校验应用的实际实现(如数据和服务API)是否与样本服务契约描述一致。
 
 * 契约/代码生成文档
 
@@ -85,12 +85,121 @@ $ cd toolkit
 $ mvn clean install
 ```
 
-### 3.2 使用toolkit cli工具
+
+### 3.2 使用toolkit-maven-plugin插件
+#### 3.2.1 配置
+在maven项目的pom文件中配置
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- 输入源。设置为 code,表示解析当前代码;设置为 contract,表示解析指定目录的契约文件。不设置则默认为 code -->
+        <sourceType>code</sourceType>
+        <!-- 生成契约文件的类型,不设置则默认为 yaml -->
+        <contractFileType>yaml</contractFileType>
+        <!-- 生成文档的类型,不设置则默认为 html -->
+        <documentType>html</documentType>
+        <!-- 生成契约文件、文档的根目录,不设置则默认为运行命令所在目录下的 target 目录,生成的契约文件在 contract 目录,生成的文档在 document 目录 -->
+        <outputDirectory>./target</outputDirectory>
+        <!-- 被解析的契约文件路径,在 sourceType 设置为 contract 时有效,且必须设置 -->
+        <contractLocation>./contract</contractLocation>
+        <!-- 被校验的契约文件目录,在 sourceType 设置为 contract 时有效,且必须设置 -->
+        <sourceContractPath>./target/contract</sourceContractPath>
+        <!-- 样本契约文件目录,必须设置 -->
+        <destinationContractPath>./contract</destinationContractPath>
+    </configuration>
+</plugin>
+```
+
+#### 3.2.2 命令
+```shell
+# 生成契约,文档和微服务工程
+mvn toolkit:generate
+
+# 校验代码和契约一致性
+mvn toolkit:verify
+```
+
+#### 3.2.2.1 解析代码,生成OpenAPI规范契约、文档
+
+配置项(不显式设置 `<configuration>` 则使用默认配置)
+例:
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- 输入源。设置为 code,表示解析当前代码;设置为 contract,表示解析指定目录的契约文件。不设置则默认为 code -->
+        <sourceType>code</sourceType>
+        <!-- 生成契约文件、文档的根目录,不设置则默认为运行命令所在目录下的 target 目录,生成的契约文件在 contract 目录,生成的文档在 document 目录 -->
+        <outputDirectory>./target</outputDirectory>
+    </configuration>
+</plugin>
+```
+
+运行命令
+```shell
+mvn toolkit:generate
+```
+
+#### 3.2.2.2 解析契约,生成文档
+
+配置项(不显式设置 `<configuration>` 则使用默认配置)
+例:
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- 输入源。设置为 code,表示解析当前代码;设置为 contract,表示解析指定目录的契约文件。不设置则默认为 code -->
+        <sourceType>contract</sourceType>
+        <!-- 被解析的契约文件路径,在 sourceType 设置为 contract 时有效,且必须设置 -->
+        <contractLocation>./contract</contractLocation>
+        <!-- 生成契约文件、文档的根目录,不设置则默认为运行命令所在目录下的 target 目录,生成的契约文件在 contract 目录,生成的文档在 document 目录 -->
+        <outputDirectory>./target</outputDirectory>
+    </configuration>
+</plugin>
+```
+
+运行命令
+```shell
+mvn toolkit:generate
+```
+
+#### 3.2.2.3 代码和契约一致性校验
+
+配置项
+例:
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- 输入源。设置为 code,表示解析当前代码;设置为 contract,表示解析指定目录的契约文件。不设置则默认为 code -->
+        <sourceType>code</sourceType>
+        <!-- 样本契约文件目录,必须设置 -->
+        <destinationContractPath>./contract</destinationContractPath>
+    </configuration>
+</plugin>
+```
+
+运行命令
+```shell
+mvn toolkit:verify
+```
+
+
+### 3.3 使用toolkit cli工具
 可执行jar包位于toolkit/cli/target/bin目录下
 ```shell
 $ java -jar toolkit-cli-{version}.jar help
 ```
-#### 3.2.1 契约生成微服务工程
+#### 3.3.1 契约生成微服务工程
 ```shell
 $ java -jar toolkit-cli-{version}.jar  codegenerate -m ServiceComb -i swagger.yaml -o ./project -p SpringMVC
 ```
@@ -116,7 +225,7 @@ $ java -jar toolkit-cli-{version}.jar  codegenerate -m ServiceComb -i swagger.ya
 * -t, --service-type : 指定生成的微服务项目的微服务类型。可选值为provider,consumer,all                  
 例:--service-type provider  
 
-#### 3.2.2 契约生成文档
+#### 3.3.2 契约生成文档
 ```shell
 $ java -jar toolkit-cli-{version}.jar docgenerate -i swagger.yaml -o ./document
 ```
@@ -128,70 +237,6 @@ $ java -jar toolkit-cli-{version}.jar docgenerate -i swagger.yaml -o ./document
 * -f, --format : 指定输出文档风格,现支持swagger-ui
 例:-f swagger-ui
 
-### 3.3 使用toolkit-maven-plugin插件
-#### 3.3.1 配置
-在maven项目的pom文件中配置
-```xml
-<plugin>
-    <groupId>org.apache.servicecomb.toolkit</groupId>
-    <artifactId>toolkit-maven-plugin</artifactId>
-    <version>0.1.0-SNAPSHOT</version>
-    <configuration>
-        <!-- 契约生成目录 -->
-        <outputDir>./contracts</outputDir>
-        <!-- 标准的契约放置的目录  -->
-        <sourceContractsDir>./sourceContracts</sourceContractsDir>  
-        <!-- 文档生成目录 -->
-        <docOutputDir>./documents</docOutputDir>
-    </configuration>
-</plugin>
-```
-#### 3.3.2 从代码提取契约
-
-运行
-```shell
-mvn toolkit:generateContracts
-```
-
-配置项
-* outputDir : 生成的契约文件输出路径
-例:
-```xml
-<outputDir>./contracts</outputDir>
-```
-
-#### 3.3.3 从代码生成文档
-
-运行
-```shell
-mvn toolkit:generateDoc
-```
-
-配置项
-* outputDir : 生成的契约文件输出路径
-* docOutputDir : 生成的契约文档输出路径
-
-例:
-```xml
-<outputDir>./contracts</outputDir>
-<docOutputDir>./documents</docOutputDir>
-```
-
-#### 3.3.4 契约校验
-
-运行
-```shell
-mvn toolkit:verifyContracts
-```
-
-配置项
-* outputDir : 生成的契约文件输出路径
-* sourceContractsDir : 共识契约存放路径
-例:
-```xml
-<outputDir>./contracts</outputDir>
-<sourceContractsDir>./sourceContracts</sourceContractsDir>
-```
 
 ## 4 社区互动
 
diff --git a/README.md b/README.md
index 7c6ab5a..55405cf 100755
--- a/README.md
+++ b/README.md
@@ -84,12 +84,124 @@ $ cd toolkit
 $ mvn clean install
 ```
 
-### 3.2 Use the toolkit cli
+### 3.2 Use the toolkit-maven-plugin plugin
+#### 3.2.1 configuration
+Configured in the pom file of the maven project
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- Set to 'code' to resolve the current project. Set to 'contract' to resolve the contract file for the specified path.If not set, the default is 'code' -->
+        <sourceType>code</sourceType>
+        <!-- The type of the contract file is generated. If it is not set, the default is 'yaml' -->
+        <contractFileType>yaml</contractFileType>
+        <!-- The type of the generated document. If not set, the default is 'html' -->
+        <documentType>html</documentType>
+        <!-- The root directory to save contract file and document. If it is not set, the default is the 'target' under the directory where the command is run -->
+        <outputDirectory>./target</outputDirectory>
+        <!-- Input contract file path. Valid when sourceType is set to 'contract', must be set -->
+        <contractLocation>./contract</contractLocation>
+        <!-- Checked contract file path. Valid when sourceType is set to 'contract', must be set -->
+        <sourceContractPath>./target/contract</sourceContractPath>
+        <!-- Sample contract file path, must be set -->
+        <destinationContractPath>./contract</destinationContractPath>
+    </configuration>
+</plugin>
+```
+
+#### 3.2.2 Command
+```shell
+# Generating contract, document and microservice project
+mvn toolkit:generate
+
+# Verify code and contract consistency
+mvn toolkit:verify
+```
+
+#### 3.2.2.1 Extract the OpenAPI contract file and document from the code
+
+Configuration(use default configuration if not set `<configuration>`)
+
+example
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- Set to 'code' to resolve the current project. Set to 'contract' to resolve the contract file for the specified path.If not set, the default is 'code' -->
+        <sourceType>code</sourceType>
+        <!-- The root directory to save contract file and document. If it is not set, the default is the 'target' under the directory where the command is run -->
+        <outputDirectory>./target</outputDirectory>
+    </configuration>
+</plugin>
+```
+
+Run in shell
+```shell
+mvn toolkit:generate
+```
+
+
+#### 3.2.2.2 Generate document from contract
+
+Configuration(use default configuration if not set `<configuration>`)
+
+example
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- Set to 'code' to resolve the current project. Set to 'contract' to resolve the contract file for the specified path.If not set, the default is 'code' -->
+        <sourceType>code</sourceType>
+        <!-- The root directory to save contract file and document. If it is not set, the default is the 'target' under the directory where the command is run -->
+        <outputDirectory>./target</outputDirectory>
+        <!-- Input contract file path. Valid when sourceType is set to 'contract', must be set -->
+        <contractLocation>./contract</contractLocation>
+    </configuration>
+</plugin>
+```
+
+Run in shell
+```shell
+mvn toolkit:generate
+```
+
+#### 3.2.2.3 Contract verify
+
+Configuration
+
+example
+```xml
+<plugin>
+    <groupId>org.apache.servicecomb.toolkit</groupId>
+    <artifactId>toolkit-maven-plugin</artifactId>
+    <version>0.1.0-SNAPSHOT</version>
+    <configuration>
+        <!-- Set to 'code' to resolve the current project. Set to 'contract' to resolve the contract file for the specified path.If not set, the default is 'code' -->
+        <sourceType>code</sourceType>
+        <!-- Sample contract file path, must be set -->
+        <destinationContractPath>./contract</destinationContractPath>
+    </configuration>
+</plugin>
+```
+
+Run in shell
+```shell
+mvn toolkit:verify
+```
+
+
+### 3.3 Use the toolkit cli
 The executable jar package is located in the toolkit/cli/target/bin directory
 ```shell
 $ java -jar toolkit-cli-{version}.jar help
 ```
-#### 3.2.1 Service contract generation microservice project
+#### 3.3.1 Service contract generation microservice project
 ```shell
 $ java -jar toolkit-cli-{version}.jar  codegenerate -m ServiceComb -i swagger.yaml -o ./project -p SpringMVC
 ```
@@ -115,7 +227,7 @@ e.g.:--model-package com.demo.model
 * -t, --service-type : Specify microservice type of generated microservice project. optional value is provider,consumer,all               
 e.g.:--service-type provider  
 
-#### 3.2.2 Service contract generation document
+#### 3.3.2 Service contract generation document
 ```shell
 $ java -jar toolkit-cli-{version}.jar docgenerate -i swagger.yaml -o ./document
 ```
@@ -127,70 +239,6 @@ $ java -jar toolkit-cli-{version}.jar docgenerate -i swagger.yaml -o ./document
 * -f, --format. Specifies the output document format, now supports swagger-ui
 例:-f swagger-ui
 
-### 3.3 Use the toolkit-maven-plugin plugin
-#### 3.3.1 configuration
-Configured in the pom file of the maven project
-```xml
-<plugin>
-    <groupId>org.apache.servicecomb.toolkit</groupId>
-    <artifactId>toolkit-maven-plugin</artifactId>
-    <version>0.1.0-SNAPSHOT</version>
-    <configuration>
-        <!-- Contracts generation directory -->
-        <outputDir>./contracts</outputDir>
-        <!-- SourceContracts placement directory -->
-        <sourceContractsDir>./sourceContracts</sourceContractsDir>  
-        <!-- Document generation directory -->
-        <docOutputDir>./documents</docOutputDir>
-    </configuration>
-</plugin>
-```
-#### 3.3.2 Extract the contract from the code
-
-Run in shell
-```shell
-mvn toolkit:generateContracts
-```
-
-Configuration
-* outputDir: contract generation directory
-example
-```xml
-<outputDir>./contracts</outputDir>
-```
-
-#### 3.3.3 Generate documentation from code
-
-Run in shell
-```shell
-mvn toolkit:generateDoc
-```
-
-Configuration
-* outputDir : Contract generation directory
-* docOutputDir : Generated contract document output path
-
-example
-```xml
-<outputDir>./contracts</outputDir>
-<docOutputDir>./documents</docOutputDir>
-```
-
-#### 3.3.4 Contract verify
-
-Run in shell
-```shell
-mvn toolkit:verifyContracts
-```
-
-Configuration
-* outputDir - The generated contract file output path.
-* sourceContractsDir - Consensus contract storage path.
-example
-```xml
-<outputDir>./contracts</outputDir>
-<sourceContractsDir>./sourceContracts</sourceContractsDir>
-```
 
 ## 4 Contact us
 
diff --git a/codegen/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombCodegen.java b/codegen/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombCodegen.java
index 325f58e..ae1df67 100755
--- a/codegen/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombCodegen.java
+++ b/codegen/src/main/java/org/apache/servicecomb/toolkit/codegen/ServiceCombCodegen.java
@@ -22,6 +22,8 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 
+import org.apache.commons.lang3.StringUtils;
+
 import io.swagger.codegen.CliOption;
 import io.swagger.codegen.CodegenConfig;
 import io.swagger.codegen.CodegenConstants;
@@ -174,14 +176,21 @@ public class ServiceCombCodegen extends AbstractJavaCodegen implements CodegenCo
 
     importMapping.put("OffsetDateTime", "java.time.OffsetDateTime");
     additionalProperties.put("dateLibrary", "java8");
-    additionalProperties.put("mainClassPackage", mainClassPackage);
+    if (StringUtils.isEmpty((String) additionalProperties.get("mainClassPackage"))) {
+      additionalProperties.put("mainClassPackage", mainClassPackage);
+    } else {
+      mainClassPackage = (String) additionalProperties.get("mainClassPackage");
+    }
     additionalProperties.put("camelcase", new CamelCaseLambda());
     additionalProperties.put("getGenericClassType", new GetGenericClassTypeLambda());
     additionalProperties.put("removeImplSuffix", new RemoveImplSuffixLambda());
     additionalProperties.put("applicationId", applicationId);
     additionalProperties.put("microserviceName", microserviceName);
 
-    processParentProjectOpts();
+    boolean isMultipleModule = (boolean) Optional.ofNullable(additionalProperties.get("isMultipleModule")).orElse(true);
+    if (isMultipleModule) {
+      processParentProjectOpts();
+    }
     switch ((String) Optional.ofNullable(additionalProperties.get(ProjectMetaConstant.SERVICE_TYPE)).orElse("")) {
       case "provider":
         processProviderProjectOpts();
diff --git a/codegen/src/main/resources/ServiceComb/project/pom.mustache b/codegen/src/main/resources/ServiceComb/project/pom.mustache
index b1acd44..19b43fb 100755
--- a/codegen/src/main/resources/ServiceComb/project/pom.mustache
+++ b/codegen/src/main/resources/ServiceComb/project/pom.mustache
@@ -33,11 +33,4 @@
     </dependencies>
   </dependencyManagement>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.hibernate.validator</groupId>
-      <artifactId>hibernate-validator</artifactId>
-    </dependency>
-  </dependencies>
-
 </project>
\ No newline at end of file
diff --git a/toolkit-maven-plugin/src/test/java/util/ClassMaker.java b/common/src/main/java/org/apache/servicecomb/toolkit/common/ClassMaker.java
similarity index 98%
rename from toolkit-maven-plugin/src/test/java/util/ClassMaker.java
rename to common/src/main/java/org/apache/servicecomb/toolkit/common/ClassMaker.java
index 2ea7822..1fb0f63 100755
--- a/toolkit-maven-plugin/src/test/java/util/ClassMaker.java
+++ b/common/src/main/java/org/apache/servicecomb/toolkit/common/ClassMaker.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package util;
+package org.apache.servicecomb.toolkit.common;
 
 import java.io.IOException;
 import java.io.InputStream;
diff --git a/common/src/test/java/org/apache/servicecomb/toolkit/common/OtherContractsGenerator.java b/common/src/main/java/org/apache/servicecomb/toolkit/common/ContractFileType.java
similarity index 67%
rename from common/src/test/java/org/apache/servicecomb/toolkit/common/OtherContractsGenerator.java
rename to common/src/main/java/org/apache/servicecomb/toolkit/common/ContractFileType.java
index ef8eb34..02b3b01 100755
--- a/common/src/test/java/org/apache/servicecomb/toolkit/common/OtherContractsGenerator.java
+++ b/common/src/main/java/org/apache/servicecomb/toolkit/common/ContractFileType.java
@@ -17,27 +17,25 @@
 
 package org.apache.servicecomb.toolkit.common;
 
-import java.util.Map;
+import java.util.Objects;
 
-import org.apache.servicecomb.toolkit.ContractsGenerator;
+public enum ContractFileType {
 
-public class OtherContractsGenerator implements ContractsGenerator {
+  YAML(".yaml");
 
-  @Override
-  public boolean canProcess(String type) {
-    if ("other".equals(type)) {
-      return true;
-    }
-    return false;
+  private String suffix;
+
+  ContractFileType(String suffix) {
+    this.suffix = suffix;
   }
 
-  @Override
-  public void configure(Map<String, Object> config) {
-    return;
+  public String getFileSuffix() {
+    return this.suffix;
   }
 
-  @Override
-  public boolean generate() {
-    return false;
+  public static ContractFileType getValue(String name) {
+
+    name = Objects.requireNonNull(name).toUpperCase();
+    return valueOf(name);
   }
-}
\ No newline at end of file
+}
diff --git a/common/src/main/java/org/apache/servicecomb/toolkit/common/ContractsUtils.java b/common/src/main/java/org/apache/servicecomb/toolkit/common/ContractsUtils.java
deleted file mode 100755
index 3dabb7b..0000000
--- a/common/src/main/java/org/apache/servicecomb/toolkit/common/ContractsUtils.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.toolkit.common;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.servicecomb.swagger.SwaggerUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import io.swagger.models.Swagger;
-
-public class ContractsUtils {
-
-  private static Logger LOGGER = LoggerFactory.getLogger(ContractsUtils.class);
-
-  public static Map<String, Swagger> getContractsFromFileSystem(String dir) throws IOException {
-
-    Map<String, Swagger> contracts = new HashMap<>();
-    File outputDir = new File(dir);
-
-    Files.walkFileTree(Paths.get(outputDir.toURI()), new SimpleFileVisitor<Path>() {
-      @Override
-      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-        contracts.put(file.toFile().getName(), SwaggerUtils.parseSwagger(file.toUri().toURL()));
-        return super.visitFile(file, attrs);
-      }
-    });
-
-    return contracts;
-  }
-
-  public static Map<String, byte[]> getFilesGroupByFilename(String dir) throws IOException {
-
-    Map<String, byte[]> contracts = new HashMap<>();
-    File outputDir = new File(dir);
-
-    Files.walkFileTree(Paths.get(outputDir.toURI()), new SimpleFileVisitor<Path>() {
-      @Override
-      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-        contracts.put(file.toFile().getName(), Files.readAllBytes(file));
-        return super.visitFile(file, attrs);
-      }
-    });
-
-    return contracts;
-  }
-}
diff --git a/common/src/main/java/org/apache/servicecomb/toolkit/common/FileUtils.java b/common/src/main/java/org/apache/servicecomb/toolkit/common/FileUtils.java
new file mode 100755
index 0000000..d133034
--- /dev/null
+++ b/common/src/main/java/org/apache/servicecomb/toolkit/common/FileUtils.java
@@ -0,0 +1,104 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.common;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+public class FileUtils {
+
+  public static void createDirectory(String pathName) throws IOException {
+
+    if (pathName == null) {
+      throw new IOException("path is null");
+    }
+
+    File path = new File(pathName);
+    if (path.exists()) {
+      deleteDirectory(pathName);
+    }
+
+    if (!path.mkdirs()) {
+      throw new IOException("failed to create directory");
+    }
+  }
+
+  public static Path createTempDirectory(String pathName) throws IOException {
+
+    createDirectory((pathName));
+
+    return Files.createTempDirectory(Paths.get(new File(pathName).toURI()), "");
+  }
+
+  public static Map<String, byte[]> getFilesGroupByFilename(String pathName) throws IOException {
+
+    if (pathName == null) {
+      throw new IOException("path is null");
+    }
+
+    if (!new File(pathName).exists()) {
+      throw new IOException("path " + pathName + " is not exists");
+    }
+
+    Map<String, byte[]> filesGroup = new HashMap<>();
+    File path = new File(pathName);
+
+    Files.walkFileTree(Paths.get(path.toURI()), new SimpleFileVisitor<Path>() {
+      @Override
+      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+        filesGroup.put(file.toFile().getName(), Files.readAllBytes(file));
+        return super.visitFile(file, attrs);
+      }
+    });
+
+    return filesGroup;
+  }
+
+  private static void deleteDirectory(String pathName) throws IOException {
+
+    File path = new File(pathName);
+
+/*
+    if (!path.exists()) {
+      return;
+    }
+*/
+
+    if (!path.isDirectory()) {
+      Files.delete(Paths.get(pathName));
+      return;
+    }
+
+    File[] files = path.listFiles();
+
+    for (File file : Objects.requireNonNull(files)) {
+      deleteDirectory(file.getCanonicalPath());
+    }
+
+    Files.delete(Paths.get(pathName));
+  }
+}
diff --git a/common/src/test/java/org/apache/servicecomb/toolkit/common/FileUtilsTest.java b/common/src/test/java/org/apache/servicecomb/toolkit/common/FileUtilsTest.java
new file mode 100644
index 0000000..290a9df
--- /dev/null
+++ b/common/src/test/java/org/apache/servicecomb/toolkit/common/FileUtilsTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.common;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import org.junit.Test;
+
+public class FileUtilsTest {
+
+  @Test
+  public void createDirectoryTest() {
+    try {
+      FileUtils.createDirectory(null);
+    } catch (IOException e) {
+      assertEquals("path is null", e.getMessage());
+    }
+
+    Path path;
+    try {
+      path = Files.createTempDirectory("");
+      FileUtils.createDirectory(path.toFile().getCanonicalPath());
+    } catch (IOException e) {
+      fail();
+    }
+  }
+
+  @Test
+  public void getFilesGroupByFilenameTest() {
+    try {
+      FileUtils.getFilesGroupByFilename(null);
+    } catch (IOException e) {
+      assertEquals("path is null", e.getMessage());
+    }
+
+    try {
+      FileUtils.getFilesGroupByFilename("");
+    } catch (IOException e) {
+      assertThat(e.getMessage(), containsString("is not exists"));
+    }
+  }
+}
\ No newline at end of file
diff --git a/common/src/test/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator b/common/src/test/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
deleted file mode 100755
index 0bbcaee..0000000
--- a/common/src/test/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
+++ /dev/null
@@ -1,18 +0,0 @@
-#
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF licenses this file to You under the Apache License, Version 2.0
-# (the "License"); you may not use this file except in compliance with
-# the License.  You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-org.apache.servicecomb.toolkit.common.OtherContractsGenerator
\ No newline at end of file
diff --git a/toolkit-maven-plugin/pom.xml b/contractgen/pom.xml
old mode 100755
new mode 100644
similarity index 57%
copy from toolkit-maven-plugin/pom.xml
copy to contractgen/pom.xml
index b46c38e..f019611
--- a/toolkit-maven-plugin/pom.xml
+++ b/contractgen/pom.xml
@@ -25,45 +25,15 @@
     <version>0.1.0-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
-  <packaging>maven-plugin</packaging>
-  <artifactId>toolkit-maven-plugin</artifactId>
 
-  <dependencies>
-    <dependency>
-      <groupId>org.apache.servicecomb.toolkit</groupId>
-      <artifactId>docgen</artifactId>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-plugin-api</artifactId>
-      <version>3.6.0</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.maven.plugin-tools</groupId>
-      <artifactId>maven-plugin-annotations</artifactId>
-      <version>3.6.0</version>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-core</artifactId>
-      <version>3.6.0</version>
-      <exclusions>
-        <exclusion>
-          <groupId>org.checkerframework</groupId>
-          <artifactId>checker-compat-qual</artifactId>
-        </exclusion>
-      </exclusions>
-    </dependency>
+  <artifactId>contractgen</artifactId>
 
+  <dependencies>
     <dependency>
       <groupId>org.apache.servicecomb.toolkit</groupId>
       <artifactId>common</artifactId>
     </dependency>
 
-    <!-- for test -->
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
@@ -72,30 +42,23 @@
     </dependency>
 
     <dependency>
-      <groupId>org.apache.maven.plugin-testing</groupId>
-      <artifactId>maven-plugin-testing-harness</artifactId>
-      <version>3.3.0</version>
-      <scope>test</scope>
-    </dependency>
-
-    <dependency>
-      <groupId>org.apache.maven</groupId>
-      <artifactId>maven-aether-provider</artifactId>
-      <version>3.2.2</version>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <version>2.25.0</version>
       <scope>test</scope>
     </dependency>
 
     <dependency>
       <groupId>org.apache.maven</groupId>
-      <artifactId>maven-compat</artifactId>
-      <version>3.2.2</version>
+      <artifactId>maven-core</artifactId>
+      <version>3.6.0</version>
       <scope>test</scope>
     </dependency>
 
     <dependency>
-      <groupId>org.mockito</groupId>
-      <artifactId>mockito-core</artifactId>
-      <version>2.25.0</version>
+      <groupId>org.apache.maven.plugin-testing</groupId>
+      <artifactId>maven-plugin-testing-harness</artifactId>
+      <version>3.3.0</version>
       <scope>test</scope>
     </dependency>
   </dependencies>
@@ -111,32 +74,7 @@
           <target>1.8</target>
         </configuration>
       </plugin>
-
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-plugin-plugin</artifactId>
-        <version>3.5</version>
-        <configuration>
-          <goalPrefix>toolkit</goalPrefix>
-          <skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
-        </configuration>
-        <executions>
-          <execution>
-            <id>generate-descriptor</id>
-            <goals>
-              <goal>descriptor</goal>
-            </goals>
-          </execution>
-          <execution>
-            <id>generated-helpmojo</id>
-            <goals>
-              <goal>helpmojo</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
     </plugins>
   </build>
 
-
-</project>
+</project>
\ No newline at end of file
diff --git a/common/src/main/java/org/apache/servicecomb/toolkit/common/DefaultContractsGenerator.java b/contractgen/src/main/java/org/apache/servicecomb/toolkit/contractgen/DefaultContractsGenerator.java
similarity index 74%
rename from common/src/main/java/org/apache/servicecomb/toolkit/common/DefaultContractsGenerator.java
rename to contractgen/src/main/java/org/apache/servicecomb/toolkit/contractgen/DefaultContractsGenerator.java
index d3f5973..6bc01a5 100755
--- a/common/src/main/java/org/apache/servicecomb/toolkit/common/DefaultContractsGenerator.java
+++ b/contractgen/src/main/java/org/apache/servicecomb/toolkit/contractgen/DefaultContractsGenerator.java
@@ -15,14 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.toolkit.common;
+package org.apache.servicecomb.toolkit.contractgen;
+
+import static org.apache.servicecomb.toolkit.common.ContractFileType.YAML;
 
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.Field;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Paths;
+import java.util.List;
 import java.util.Map;
 import java.util.Vector;
 
@@ -33,6 +37,8 @@ import org.apache.servicecomb.swagger.generator.core.CompositeSwaggerGeneratorCo
 import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
 import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;
 import org.apache.servicecomb.toolkit.ContractsGenerator;
+import org.apache.servicecomb.toolkit.common.ContractFileType;
+import org.apache.servicecomb.toolkit.common.ImmediateClassLoader;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -40,17 +46,17 @@ import org.springframework.web.bind.annotation.RestController;
 
 public class DefaultContractsGenerator implements ContractsGenerator {
 
-  private static Logger LOGGER = LoggerFactory.getLogger(ContractsUtils.class);
+  private static Logger LOGGER = LoggerFactory.getLogger(DefaultContractsGenerator.class);
 
   private static CompositeSwaggerGeneratorContext compositeSwaggerGeneratorContext = new CompositeSwaggerGeneratorContext();
 
   private Map<String, Object> config;
 
-  private URL[] classpathUrls;
+  private List<String> classpathUrls;
 
   private String outputDir = ".";
 
-  private String format = ".yaml";
+  private ContractFileType contractfileType = YAML;
 
   @Override
   public boolean canProcess(String type) {
@@ -66,23 +72,42 @@ public class DefaultContractsGenerator implements ContractsGenerator {
     }
 
     Object classpathUrlsObj = config.get("classpathUrls");
-    if (classpathUrlsObj instanceof URL[]) {
-      classpathUrls = (URL[]) classpathUrlsObj;
+    if (classpathUrlsObj instanceof List) {
+      //noinspection unchecked
+      classpathUrls = (List<String>) classpathUrlsObj;
     }
 
     Object outputDirObj = config.get("outputDir");
     if (outputDirObj instanceof String) {
       outputDir = (String) outputDirObj;
     }
+
+    Object contractFileTypeObj = config.get("contractFileType");
+    if (contractFileTypeObj instanceof String) {
+      contractfileType = ContractFileType.getValue((String) contractFileTypeObj);
+    }
   }
 
   @Override
-  public boolean generate() {
+  public boolean generate() throws RuntimeException {
+
+    URL[] runtimeUrls = new URL[classpathUrls.size()];
+    for (int i = 0; i < classpathUrls.size(); i++) {
+
+      String element = classpathUrls.get(i);
+
+      try {
+        runtimeUrls[i] = new File(element).toURI().toURL();
+      } catch (MalformedURLException e) {
+        throw new RuntimeException("wrong element in classpath", e);
+      }
+    }
 
     if (!checkConfig()) {
       return false;
     }
-    ImmediateClassLoader immediateClassLoader = new ImmediateClassLoader(classpathUrls,
+
+    ImmediateClassLoader immediateClassLoader = new ImmediateClassLoader(runtimeUrls,
         Thread.currentThread().getContextClassLoader());
 
     try {
@@ -103,7 +128,8 @@ public class DefaultContractsGenerator implements ContractsGenerator {
 
         String swaggerString = SwaggerUtils.swaggerToString(generator.generate());
 
-        File outputFile = new File(outputDir + File.separator + loadClass.getSimpleName() + format);
+        File outputFile = new File(
+            outputDir + File.separator + loadClass.getSimpleName() + contractfileType.getFileSuffix());
 
         if (!outputFile.exists()) {
           if (!outputFile.getParentFile().exists()) {
@@ -115,23 +141,13 @@ public class DefaultContractsGenerator implements ContractsGenerator {
         Files.write(Paths.get(outputFile.toURI()), swaggerString.getBytes());
       }
     } catch (IOException e) {
-      LOGGER.error(e.getMessage());
-      return false;
+      throw new RuntimeException(e);
     }
-
     return true;
   }
 
   private boolean checkConfig() {
-    if (config == null) {
-      return false;
-    }
-
-    if (classpathUrls == null) {
-      return false;
-    }
-
-    return true;
+    return config != null && classpathUrls != null;
   }
 
   private static boolean canProcess(Class<?> loadClass) {
@@ -172,7 +188,7 @@ public class DefaultContractsGenerator implements ContractsGenerator {
         return (Vector) classesField.get(classLoader);
       }
     } catch (Exception e) {
-      LOGGER.warn("cannot get all class from ClassLoader " + classLoader.getClass());
+      throw new RuntimeException("cannot get class from ClassLoader " + classLoader.getClass());
     }
     return new Vector<>();
   }
diff --git a/common/src/main/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator b/contractgen/src/main/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
old mode 100755
new mode 100644
similarity index 92%
rename from common/src/main/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
rename to contractgen/src/main/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
index e465598..3b7761f
--- a/common/src/main/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
+++ b/contractgen/src/main/resources/META-INF/services/org.apache.servicecomb.toolkit.ContractsGenerator
@@ -15,4 +15,4 @@
 # limitations under the License.
 #
 
-org.apache.servicecomb.toolkit.common.DefaultContractsGenerator
\ No newline at end of file
+org.apache.servicecomb.toolkit.contractgen.DefaultContractsGenerator
\ No newline at end of file
diff --git a/contractgen/src/test/java/org/apache/servicecomb/toolkit/contractgen/DefaultContractsGeneratorTest.java b/contractgen/src/test/java/org/apache/servicecomb/toolkit/contractgen/DefaultContractsGeneratorTest.java
new file mode 100644
index 0000000..a4f16a4
--- /dev/null
+++ b/contractgen/src/test/java/org/apache/servicecomb/toolkit/contractgen/DefaultContractsGeneratorTest.java
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.contractgen;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeoutException;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.testing.resources.TestResources;
+import org.apache.maven.project.MavenProject;
+import org.apache.servicecomb.provider.rest.common.RestSchema;
+import org.apache.servicecomb.toolkit.ContractsGenerator;
+import org.apache.servicecomb.toolkit.GeneratorFactory;
+import org.apache.servicecomb.toolkit.common.ClassMaker;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class DefaultContractsGeneratorTest {
+
+  @Rule
+  public TestResources resources = new TestResources();
+
+  private static final String TEST_PROJECT = "demo";
+
+  @Test
+  public void testCanProcess() {
+    assertTrue(new DefaultContractsGenerator().canProcess("default"));
+    assertFalse(new DefaultContractsGenerator().canProcess("others"));
+  }
+
+  @Test
+  public void testConfigure() throws DependencyResolutionRequiredException {
+    Map<String, Object> config = new HashMap<>();
+
+    MavenProject project = new MavenProject();
+    config.put("classpathUrls", project.getRuntimeClasspathElements());
+    config.put("outputDir", "target");
+    config.put("contractfileType", "yaml");
+  }
+
+  @Test
+  public void testGenerate()
+      throws DependencyResolutionRequiredException, IOException, TimeoutException, InterruptedException {
+
+    File demoPath = this.resources.getBasedir(TEST_PROJECT);
+    ClassMaker.compile(demoPath.getCanonicalPath());
+    MavenProject project = mock(MavenProject.class);
+
+    List<String> runtimeUrlPath = new ArrayList<>();
+    runtimeUrlPath.add(demoPath + File.separator + "target/classes");
+
+    Map<String, Object> config = new HashMap<>();
+    given(project.getRuntimeClasspathElements()).willReturn(runtimeUrlPath);
+    config.put("classpathUrls", project.getRuntimeClasspathElements());
+    config.put("outputDir", "target");
+    config.put("contractfileType", "yaml");
+
+    DefaultContractsGenerator defaultContractsGenerator = new DefaultContractsGenerator();
+    defaultContractsGenerator.configure(config);
+    assertTrue(defaultContractsGenerator.generate());
+  }
+
+  @Test
+  public void testCheckConfig() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException,
+      DependencyResolutionRequiredException {
+    DefaultContractsGenerator defaultContractsGenerator = new DefaultContractsGenerator();
+    Method method = defaultContractsGenerator.getClass().getDeclaredMethod("checkConfig", new Class[] {});
+    method.setAccessible(true);
+
+    defaultContractsGenerator.configure(null);
+    assertFalse((boolean) method.invoke(defaultContractsGenerator, new Object[] {}));
+
+    Map<String, Object> config = new HashMap<>();
+    config.put("classpathUrls", null);
+    defaultContractsGenerator.configure(config);
+    assertFalse((boolean) method.invoke(defaultContractsGenerator, new Object[] {}));
+
+    MavenProject project = new MavenProject();
+    config.put("classpathUrls", project.getRuntimeClasspathElements());
+    defaultContractsGenerator.configure(config);
+    assertTrue((boolean) method.invoke(defaultContractsGenerator, new Object[] {}));
+  }
+
+  @Test
+  public void testPrivateCanProcess() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+    DefaultContractsGenerator defaultContractsGenerator = new DefaultContractsGenerator();
+    Method method = defaultContractsGenerator.getClass().getDeclaredMethod("canProcess", new Class[] {Class.class});
+    method.setAccessible(true);
+
+    assertFalse((boolean) method.invoke(defaultContractsGenerator, new Object[] {null}));
+
+//    Class<Runnable> mockRunnableaClass = (Class<Runnable>)mock(Class.class);
+//    RestSchema restSchema = mock(RestSchema.class);
+//    given(mockRunnableaClass.getAnnotation(RestSchema.class)).willReturn(restSchema);
+//    assertTrue((boolean) method.invoke(defaultContractsGenerator, new Object[] {mockRunnableaClass}));
+  }
+
+  @Test
+  public void testgetAllClass() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+    DefaultContractsGenerator defaultContractsGenerator = new DefaultContractsGenerator();
+    Method method = defaultContractsGenerator.getClass()
+        .getDeclaredMethod("getAllClass", new Class[] {ClassLoader.class});
+    method.setAccessible(true);
+
+    try {
+      method.invoke(defaultContractsGenerator, new Object[] {null});
+    } catch (Exception e) {
+      assertTrue(true);
+    }
+  }
+
+  @Test
+  public void getContractsGeneratorInstance() {
+
+    ContractsGenerator defaultGenerator = GeneratorFactory.getGenerator(ContractsGenerator.class, "default");
+    assertNotNull(defaultGenerator);
+
+    ContractsGenerator unknownGenerator = GeneratorFactory.getGenerator(ContractsGenerator.class, "unknown");
+    assertNull(unknownGenerator);
+  }
+}
\ No newline at end of file
diff --git a/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml b/contractgen/src/test/projects/demo/pom.xml
similarity index 79%
copy from toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml
copy to contractgen/src/test/projects/demo/pom.xml
index 99bebfe..a20e1cc 100755
--- a/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml
+++ b/contractgen/src/test/projects/demo/pom.xml
@@ -48,18 +48,4 @@
 
   </dependencies>
 
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.servicecomb.toolkit</groupId>
-        <artifactId>toolkit-maven-plugin</artifactId>
-        <version>${project.version}</version>
-        <extensions>true</extensions>
-        <configuration>
-          <outputDir>target/test_output_contracts</outputDir>
-          <format>.yaml</format>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
 </project>
\ No newline at end of file
diff --git a/toolkit-maven-plugin/src/test/projects/demo-non-contract/src/main/java/demo/Application.java b/contractgen/src/test/projects/demo/src/main/java/demo/Application.java
similarity index 100%
copy from toolkit-maven-plugin/src/test/projects/demo-non-contract/src/main/java/demo/Application.java
copy to contractgen/src/test/projects/demo/src/main/java/demo/Application.java
diff --git a/common/src/test/java/org/apache/servicecomb/toolkit/common/ContractsGeneratorTest.java b/contractgen/src/test/projects/demo/src/main/java/demo/HelloEndPoint.java
similarity index 51%
rename from common/src/test/java/org/apache/servicecomb/toolkit/common/ContractsGeneratorTest.java
rename to contractgen/src/test/projects/demo/src/main/java/demo/HelloEndPoint.java
index d5ed5e6..69e40c5 100755
--- a/common/src/test/java/org/apache/servicecomb/toolkit/common/ContractsGeneratorTest.java
+++ b/contractgen/src/test/projects/demo/src/main/java/demo/HelloEndPoint.java
@@ -15,27 +15,25 @@
  * limitations under the License.
  */
 
-package org.apache.servicecomb.toolkit.common;
+package demo;
 
-import static org.junit.Assert.*;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
-import org.apache.servicecomb.toolkit.ContractsGenerator;
-import org.apache.servicecomb.toolkit.GeneratorFactory;
-import org.junit.Test;
-
-public class ContractsGeneratorTest {
-
-  @Test
-  public void getContractsGeneratorInstance() {
-
-    ContractsGenerator defaultGenerator = GeneratorFactory.getGenerator(ContractsGenerator.class,"default");
-    assertNotNull(defaultGenerator);
+@RestController
+@RequestMapping({"/hello"})
+public class HelloEndPoint {
+  public HelloEndPoint() {
+  }
 
-    ContractsGenerator unknownGenerator = GeneratorFactory.getGenerator(ContractsGenerator.class,"unknown");
-    assertNull(unknownGenerator);
+  @GetMapping({"/sayHello"})
+  public String sayHello(String name) {
+    return "Hello, " + name;
+  }
 
-    ContractsGenerator other = GeneratorFactory.getGenerator(ContractsGenerator.class,"other");
-    assertNotNull(other);
-    assertTrue(other.canProcess("other"));
+  @GetMapping({"/sayHi"})
+  public String sayHi(String name) {
+    return "Hi, " + name;
   }
 }
diff --git a/docgen/src/main/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGenerator.java b/docgen/src/main/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGenerator.java
index 925a371..6110f0e 100755
--- a/docgen/src/main/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGenerator.java
+++ b/docgen/src/main/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGenerator.java
@@ -41,8 +41,6 @@ public class ContractsSwaggerUIGenerator implements DocGenerator {
 
   private static Pattern variablePattern = Pattern.compile("(?<=\\{\\{)[a-zA-Z0-9_-]*(?=\\}\\})");
 
-  private final static String DOC_FORMAT = "html";
-
   private final static String DOC_SUFFIX = ".html";
 
   private Swagger contractContent;
@@ -52,7 +50,7 @@ public class ContractsSwaggerUIGenerator implements DocGenerator {
   @Override
 
   public boolean canProcess(String type) {
-    return DOC_FORMAT.equals(type);
+    return "default".equals(type);
   }
 
   @Override
@@ -92,8 +90,7 @@ public class ContractsSwaggerUIGenerator implements DocGenerator {
 
       Files.write(outputFile, swaggerUiHtml.getBytes());
     } catch (IOException e) {
-      LOGGER.error(e.getMessage());
-      return false;
+      throw new RuntimeException(e);
     }
 
     return true;
diff --git a/docgen/src/test/java/docgen/DocGeneratorTest.java b/docgen/src/test/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGeneratorTest.java
old mode 100755
new mode 100644
similarity index 87%
rename from docgen/src/test/java/docgen/DocGeneratorTest.java
rename to docgen/src/test/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGeneratorTest.java
index f7d4de5..02e4843
--- a/docgen/src/test/java/docgen/DocGeneratorTest.java
+++ b/docgen/src/test/java/org/apache/servicecomb/toolkit/docgen/ContractsSwaggerUIGeneratorTest.java
@@ -15,16 +15,7 @@
  * limitations under the License.
  */
 
-package docgen;
-
-import io.swagger.models.Swagger;
-import io.swagger.parser.Swagger20Parser;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.servicecomb.toolkit.GeneratorFactory;
-import org.apache.servicecomb.toolkit.DocGenerator;
-import org.junit.Assert;
-import org.junit.Test;
+package org.apache.servicecomb.toolkit.docgen;
 
 import java.io.File;
 import java.io.IOException;
@@ -34,15 +25,25 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Objects;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.servicecomb.toolkit.DocGenerator;
+import org.apache.servicecomb.toolkit.GeneratorFactory;
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.swagger.models.Swagger;
+import io.swagger.parser.Swagger20Parser;
 
-public class DocGeneratorTest {
+public class ContractsSwaggerUIGeneratorTest {
 
   @Test
   public void contractTransferToSwaggerUI() throws IOException {
 
     Swagger20Parser swagger20Parser = new Swagger20Parser();
 
-    InputStream in = DocGeneratorTest.class.getClassLoader().getResourceAsStream("HelloEndPoint.yaml");
+    InputStream in = ContractsSwaggerUIGeneratorTest.class.getClassLoader().getResourceAsStream("HelloEndPoint.yaml");
 
     StringBuilder sb = new StringBuilder();
     byte[] bytes = new byte[1024];
@@ -56,11 +57,11 @@ public class DocGeneratorTest {
     Path tempDir = Files.createTempDirectory(null);
     Path outputPath = Paths.get(tempDir.toFile().getAbsolutePath()
         + File.separator + "swagger-ui.html");
-    DocGenerator docGenerator = GeneratorFactory.getGenerator(DocGenerator.class, "html");
+    DocGenerator docGenerator = GeneratorFactory.getGenerator(DocGenerator.class, "default");
     Map<String, Object> docGeneratorConfig = new HashMap<>();
     docGeneratorConfig.put("contractContent", swagger);
     docGeneratorConfig.put("outputPath", outputPath.toFile().getCanonicalPath());
-    docGenerator.configure(docGeneratorConfig);
+    Objects.requireNonNull(docGenerator).configure(docGeneratorConfig);
     docGenerator.generate();
 
     Assert.assertTrue(Files.exists(outputPath));
@@ -73,4 +74,4 @@ public class DocGeneratorTest {
     DocGenerator docGenerator = GeneratorFactory.getGenerator(DocGenerator.class, "other");
     Assert.assertNull(docGenerator);
   }
-}
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 6a92af8..1a1dda1 100755
--- a/pom.xml
+++ b/pom.xml
@@ -63,6 +63,7 @@
     <module>toolkit-maven-plugin</module>
     <module>core</module>
     <module>integration-tests</module>
+    <module>contractgen</module>
   </modules>
 
   <dependencyManagement>
@@ -99,6 +100,12 @@
 
       <dependency>
         <groupId>org.apache.servicecomb.toolkit</groupId>
+        <artifactId>contractgen</artifactId>
+        <version>${project.version}</version>
+      </dependency>
+
+      <dependency>
+        <groupId>org.apache.servicecomb.toolkit</groupId>
         <artifactId>toolkit-maven-plugin</artifactId>
         <version>${project.version}</version>
       </dependency>
@@ -232,6 +239,7 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-remote-resources-plugin</artifactId>
+        <version>1.6.0</version>
         <executions>
           <execution>
             <id>process-resource-bundles</id>
diff --git a/toolkit-maven-plugin/pom.xml b/toolkit-maven-plugin/pom.xml
index b46c38e..247c829 100755
--- a/toolkit-maven-plugin/pom.xml
+++ b/toolkit-maven-plugin/pom.xml
@@ -35,6 +35,16 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.servicecomb.toolkit</groupId>
+      <artifactId>contractgen</artifactId>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.servicecomb.toolkit</groupId>
+      <artifactId>codegen</artifactId>
+    </dependency>
+
+    <dependency>
       <groupId>org.apache.maven</groupId>
       <artifactId>maven-plugin-api</artifactId>
       <version>3.6.0</version>
diff --git a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/ContractGenerator.java b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/ContractGenerator.java
deleted file mode 100755
index 227899f..0000000
--- a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/ContractGenerator.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.toolkit.plugin;
-
-import java.io.File;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.maven.artifact.DependencyResolutionRequiredException;
-import org.apache.maven.project.MavenProject;
-import org.apache.servicecomb.toolkit.ContractsGenerator;
-import org.apache.servicecomb.toolkit.GeneratorFactory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ContractGenerator {
-
-  private static Logger LOGGER = LoggerFactory.getLogger(ContractGenerator.class);
-
-  private MavenProject project;
-
-  public ContractGenerator(MavenProject project) {
-    this.project = project;
-  }
-
-  public void generateAndOutput(String outputDir, String format) {
-
-    List runtimeClasspaths = null;
-    try {
-      runtimeClasspaths = project.getRuntimeClasspathElements();
-    } catch (DependencyResolutionRequiredException e) {
-      LOGGER.error(e.getMessage());
-    }
-    URL[] runtimeUrls = new URL[runtimeClasspaths.size()];
-    for (int i = 0; i < runtimeClasspaths.size(); i++) {
-      String element = (String) runtimeClasspaths.get(i);
-      try {
-        runtimeUrls[i] = new File(element).toURI().toURL();
-      } catch (MalformedURLException e) {
-        LOGGER.error(e.getMessage());
-      }
-    }
-
-    ContractsGenerator contractGenerator = GeneratorFactory.getGenerator(ContractsGenerator.class,"default");
-    Map<String,Object> contractConfig = new HashMap<>();
-    contractConfig.put("classpathUrls",runtimeUrls);
-    contractConfig.put("outputDir",outputDir);
-    contractGenerator.configure(contractConfig);
-    contractGenerator.generate();
-  }
-}
diff --git a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateContractsDocMojo.java b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateContractsDocMojo.java
deleted file mode 100755
index 866419c..0000000
--- a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateContractsDocMojo.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.toolkit.plugin;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugins.annotations.Execute;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
-import org.apache.servicecomb.swagger.SwaggerUtils;
-import org.apache.servicecomb.toolkit.DocGenerator;
-import org.apache.servicecomb.toolkit.GeneratorFactory;
-import org.apache.servicecomb.toolkit.common.SourceType;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Mojo(name = "generateDoc", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE)
-@Execute(goal = "generateDoc",
-    phase = LifecyclePhase.COMPILE
-)
-public class GenerateContractsDocMojo extends AbstractMojo {
-
-  private static Logger LOGGER = LoggerFactory.getLogger(GenerateContractsDocMojo.class);
-
-  @Parameter(defaultValue = "${project}")
-  private MavenProject project;
-
-  @Parameter(defaultValue = "code")
-  private String sourceType;
-
-  @Parameter(defaultValue = "contractLocation")
-  private String contractLocation;
-
-  @Parameter(defaultValue = "html")
-  private String documentType;
-
-  @Parameter(defaultValue = "documentOutput")
-  private String documentOutput;
-
-  @Override
-  public void execute() throws MojoExecutionException, MojoFailureException {
-
-    try {
-
-      switch (SourceType.valueOf(sourceType.toUpperCase())) {
-        case CODE:
-          File tmpFileDir = new File("target/tmp-contract-dir");
-          if (!tmpFileDir.exists()) {
-            if (!tmpFileDir.mkdirs()) {
-              throw new MojoFailureException("fail to create directory to save contract");
-            }
-          }
-
-          Path tmpPath = Files.createTempDirectory(Paths.get(tmpFileDir.toURI()), "");
-          contractLocation = tmpPath.toFile().getCanonicalPath();
-          LOGGER.debug("temporary contract location is " + contractLocation);
-
-          ContractGenerator contractGenerator = new ContractGenerator(project);
-          contractGenerator.generateAndOutput(contractLocation, "");
-          if (Objects.requireNonNull(tmpPath.toFile().listFiles()).length == 0) {
-            LOGGER.info("no contract in the code");
-            return;
-          }
-
-          break;
-        case CONTRACT:
-          File file = new File(contractLocation);
-          if (!file.exists()) {
-            throw new MojoFailureException("contract location is not exists");
-          }
-
-          if (Objects.requireNonNull(file.listFiles()).length == 0) {
-            throw new MojoFailureException(contractLocation + " has no contract files");
-          }
-
-          break;
-        default:
-          throw new MojoFailureException(sourceType + " is not supported now");
-      }
-
-      DocGenerator docGenerator = GeneratorFactory.getGenerator(DocGenerator.class, documentType);
-      if (docGenerator == null) {
-        throw new MojoFailureException("DocGenerator's implementation is not found");
-      }
-
-      Files.walkFileTree(Paths.get(contractLocation), new SimpleFileVisitor<Path>() {
-
-        @Override
-        public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
-
-          Map<String, Object> docGeneratorConfig = new HashMap<>();
-          docGeneratorConfig.put("contractContent", SwaggerUtils.parseSwagger(file.toUri().toURL()));
-          docGeneratorConfig.put("outputPath", documentOutput + File.separator
-              + file.toFile().getName().substring(0, file.toFile().getName().indexOf(".")));
-          docGenerator.configure(docGeneratorConfig);
-          if (!docGenerator.generate()) {
-            throw new RuntimeException("Failed to generate doc base on file " + file.toFile().getName());
-          }
-
-          return super.visitFile(file, attrs);
-        }
-      });
-    } catch (IOException e) {
-      LOGGER.error(e.getMessage());
-    }
-  }
-}
diff --git a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateContractsMojo.java b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateContractsMojo.java
deleted file mode 100755
index 9d1b599..0000000
--- a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateContractsMojo.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.servicecomb.toolkit.plugin;
-
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugins.annotations.Execute;
-import org.apache.maven.plugins.annotations.LifecyclePhase;
-import org.apache.maven.plugins.annotations.Mojo;
-import org.apache.maven.plugins.annotations.Parameter;
-import org.apache.maven.plugins.annotations.ResolutionScope;
-import org.apache.maven.project.MavenProject;
-
-@Mojo(name = "generateContracts", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.RUNTIME)
-@Execute(goal = "generateContracts",
-    phase = LifecyclePhase.COMPILE
-)
-public class GenerateContractsMojo
-    extends AbstractMojo {
-
-  @Parameter(defaultValue = "${project}", required = true, readonly = true)
-  private MavenProject project;
-
-  @Parameter(defaultValue = "contracts")
-  private String outputDir;
-
-  @Parameter(defaultValue = ".yaml")
-  private String format;
-
-  @Override
-  public void execute()
-      throws MojoExecutionException {
-
-    ContractGenerator contractGenerator = new ContractGenerator(project);
-    contractGenerator.generateAndOutput(outputDir, format);
-  }
-
-  /**
-   * @param project the project to set
-   */
-  public void setProject(MavenProject project) {
-    this.project = project;
-  }
-}
diff --git a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateMojo.java b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateMojo.java
new file mode 100755
index 0000000..1569019
--- /dev/null
+++ b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateMojo.java
@@ -0,0 +1,107 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Objects;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugins.annotations.Execute;
+import org.apache.maven.plugins.annotations.LifecyclePhase;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.plugins.annotations.ResolutionScope;
+import org.apache.maven.project.MavenProject;
+import org.apache.servicecomb.toolkit.common.FileUtils;
+import org.apache.servicecomb.toolkit.common.SourceType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Mojo(name = "generate", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE)
+@Execute(goal = "generate", phase = LifecyclePhase.COMPILE)
+public class GenerateMojo extends AbstractMojo {
+
+  private static Logger LOGGER = LoggerFactory.getLogger(GenerateMojo.class);
+
+  @Parameter(defaultValue = "${project}")
+  private MavenProject project;
+
+  @Parameter(defaultValue = "code")
+  private String sourceType;
+
+  @Parameter(defaultValue = "yaml")
+  private String contractFileType;
+
+  @Parameter(defaultValue = "html")
+  private String documentType;
+
+  @Parameter
+  private String contractLocation;
+
+  @Parameter(defaultValue = "./target")
+  private String outputDirectory;
+
+  @Override
+  public void execute() {
+
+    switch (SourceType.valueOf(sourceType.toUpperCase())) {
+      case CODE:
+        // generate contract file
+        if (outputDirectory == null) {
+          throw new RuntimeException("output directory setting is invalid");
+        }
+        String contractOutput = outputDirectory + File.separator + "contract";
+        try {
+          FileUtils.createDirectory(contractOutput);
+        } catch (IOException e) {
+          throw new RuntimeException("failed to generate contract.", e);
+        }
+
+        GenerateUtil.generateContract(project, contractOutput, contractFileType, "default");
+        contractLocation = contractOutput;
+        if (Objects.requireNonNull(new File(contractOutput).listFiles()).length == 0) {
+          LOGGER.info("No contract in the code");
+          return;
+        }
+
+        break;
+      case CONTRACT:
+        if (contractLocation == null) {
+          throw new RuntimeException("contract location is invalid or not set");
+        }
+
+        if (!new File(contractLocation).exists()) {
+          throw new RuntimeException("contract path " + contractLocation + " is not exists");
+        }
+
+        break;
+      default:
+        throw new RuntimeException("source type " + sourceType + " is not supported");
+    }
+
+    //generate document
+    String documentOutput = outputDirectory + File.separator + "document";
+    try {
+      FileUtils.createDirectory(documentOutput);
+      GenerateUtil.generateDocument(contractLocation, documentOutput, "default");
+    } catch (IOException e) {
+      throw new RuntimeException("failed to generate document", e);
+    }
+  }
+}
diff --git a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateUtil.java b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateUtil.java
new file mode 100755
index 0000000..7747fef
--- /dev/null
+++ b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/GenerateUtil.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.plugin;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.project.MavenProject;
+import org.apache.servicecomb.swagger.SwaggerUtils;
+import org.apache.servicecomb.toolkit.ContractsGenerator;
+import org.apache.servicecomb.toolkit.DocGenerator;
+import org.apache.servicecomb.toolkit.GeneratorFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GenerateUtil {
+
+  private static Logger LOGGER = LoggerFactory.getLogger(GenerateUtil.class);
+
+  public static void generateContract(MavenProject project, String contractOutput, String contractFileType,
+      String type) {
+
+    Map<String, Object> contractConfig = new HashMap<>();
+    try {
+      contractConfig.put("classpathUrls", project.getRuntimeClasspathElements());
+    } catch (DependencyResolutionRequiredException e) {
+      throw new RuntimeException("failed to get runtime class elements", e);
+    }
+    contractConfig.put("outputDir", contractOutput);
+    contractConfig.put("contractFileType", contractFileType);
+
+    // TODO: support users to add other getGenerator type soon
+    ContractsGenerator contractGenerator = GeneratorFactory.getGenerator(ContractsGenerator.class, type);
+    Objects.requireNonNull(contractGenerator).configure(contractConfig);
+    contractGenerator.generate();
+  }
+
+  public static void generateDocument(String contractLocation, String documentOutput, String type)
+      throws IOException {
+
+    // TODO: support users to add other getGenerator type soon
+    DocGenerator docGenerator = GeneratorFactory.getGenerator(DocGenerator.class, type);
+    if (docGenerator == null) {
+      throw new RuntimeException("DocGenerator's implementation is not found");
+    }
+
+    Files.walkFileTree(Paths.get(contractLocation), new SimpleFileVisitor<Path>() {
+
+      @Override
+      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
+
+        Map<String, Object> docGeneratorConfig = new HashMap<>();
+
+        docGeneratorConfig.put("contractContent", SwaggerUtils.parseSwagger(file.toUri().toURL()));
+        docGeneratorConfig.put("outputPath", documentOutput + File.separator + file.toFile().getName()
+            .substring(0, file.toFile().getName().indexOf(".")));
+
+        docGenerator.configure(docGeneratorConfig);
+        docGenerator.generate();
+
+        return super.visitFile(file, attrs);
+      }
+    });
+  }
+}
diff --git a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/VerifyContractsMojo.java b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/VerifyMojo.java
similarity index 50%
rename from toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/VerifyContractsMojo.java
rename to toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/VerifyMojo.java
index c548d62..f6d7376 100755
--- a/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/VerifyContractsMojo.java
+++ b/toolkit-maven-plugin/src/main/java/org/apache/servicecomb/toolkit/plugin/VerifyMojo.java
@@ -21,8 +21,6 @@ import java.io.IOException;
 import java.util.Map;
 
 import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoExecutionException;
-import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugins.annotations.Execute;
 import org.apache.maven.plugins.annotations.LifecyclePhase;
 import org.apache.maven.plugins.annotations.Mojo;
@@ -30,61 +28,72 @@ import org.apache.maven.plugins.annotations.Parameter;
 import org.apache.maven.plugins.annotations.ResolutionScope;
 import org.apache.maven.project.MavenProject;
 import org.apache.servicecomb.toolkit.common.ContractComparator;
-import org.apache.servicecomb.toolkit.common.ContractsUtils;
+import org.apache.servicecomb.toolkit.common.FileUtils;
+import org.apache.servicecomb.toolkit.common.SourceType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-@Mojo(name = "verifyContracts", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE)
-@Execute(goal = "verifyContracts",
-    phase = LifecyclePhase.COMPILE
-)
-public class VerifyContractsMojo extends AbstractMojo {
+@Mojo(name = "verify", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE)
+@Execute(goal = "verify", phase = LifecyclePhase.COMPILE)
+public class VerifyMojo extends AbstractMojo {
 
-  private final static Logger LOGGER = LoggerFactory.getLogger(VerifyContractsMojo.class);
+  private final static Logger LOGGER = LoggerFactory.getLogger(VerifyMojo.class);
 
   @Parameter(defaultValue = "${project}", required = true, readonly = true)
   private MavenProject project;
 
-  @Parameter(defaultValue = "contracts")
-  private String outputDir;
+  @Parameter(defaultValue = "code")
+  private String sourceType;
 
-  @Parameter(defaultValue = ".yaml")
-  private String format;
+  @Parameter
+  private String sourceContractPath;
 
-  @Parameter(defaultValue = "sourceContracts")
-  private String sourceContractsDir;
+  @Parameter
+  private String destinationContractPath;
 
 
   @Override
-  public void execute() throws MojoExecutionException, MojoFailureException {
+  public void execute() {
 
-    getLog().info("outputDir : " + outputDir);
+    String contractFileType = "yaml";
 
-    ContractGenerator contractGenerator = new ContractGenerator(project);
+    switch (SourceType.valueOf(sourceType.toUpperCase())) {
+      case CODE:
+        try {
+          sourceContractPath = FileUtils.createTempDirectory("target/tmp-contract").toFile().getCanonicalPath();
+          GenerateUtil.generateContract(project, sourceContractPath, contractFileType,"default");
+        } catch (IOException e) {
+          throw new RuntimeException("failed to generate contract from code.", e);
+        }
 
-    contractGenerator.generateAndOutput(outputDir, format);
+        break;
+      case CONTRACT:
 
-    try {
+        break;
+      default:
+        throw new RuntimeException("source type " + sourceType + " is not supported");
+    }
 
-      Map<String, byte[]> currentContracts = ContractsUtils.getFilesGroupByFilename(outputDir);
-      Map<String, byte[]> sourceContracts = ContractsUtils.getFilesGroupByFilename(sourceContractsDir);
+    try {
+      Map<String, byte[]> sourceContractGroup = FileUtils.getFilesGroupByFilename(sourceContractPath);
+      Map<String, byte[]> destinationContractGroup = FileUtils.getFilesGroupByFilename(destinationContractPath);
 
-      currentContracts.forEach((contractName, swagger) -> {
+      sourceContractGroup.forEach((contractName, swagger) -> {
 
-        byte[] sourceSwagger = sourceContracts.get(contractName);
+        byte[] sourceSwagger = destinationContractGroup.get(contractName);
 
         ContractComparator contractComparator = new ContractComparator(new String(sourceSwagger), new String(swagger));
 
         if (!contractComparator.equals()) {
-          getLog().info("contract is not matched, difference is as follows");
-          getLog().info(sourceContractsDir + "/" + contractName + " vs " + outputDir + "/" + contractName);
+          LOGGER.info("contract is not matched, difference is as follows");
+          LOGGER.info(destinationContractPath + "/" + contractName + " vs " + sourceContractPath + "/" + contractName);
           contractComparator.splitPrintToScreen();
         } else {
-          getLog().info("succee, contract verification passed");
+          LOGGER.info("succee, contract verification passed");
         }
       });
     } catch (IOException e) {
-      LOGGER.error(e.getMessage());
+      throw new RuntimeException("failed to verify contract", e);
     }
   }
 }
diff --git a/toolkit-maven-plugin/src/test/java/org/apache/servicecomb/toolkit/plugin/GenerateMojoTest.java b/toolkit-maven-plugin/src/test/java/org/apache/servicecomb/toolkit/plugin/GenerateMojoTest.java
new file mode 100644
index 0000000..fdbde2f
--- /dev/null
+++ b/toolkit-maven-plugin/src/test/java/org/apache/servicecomb/toolkit/plugin/GenerateMojoTest.java
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.plugin;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Mockito.mock;
+
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugin.testing.MojoRule;
+import org.apache.maven.plugin.testing.resources.TestResources;
+import org.apache.maven.project.MavenProject;
+import org.apache.servicecomb.toolkit.common.ClassMaker;
+import org.junit.Rule;
+import org.junit.Test;
+
+
+public class GenerateMojoTest {
+
+  private static final String PLUGIN_GOAL = "generate";
+
+  private static final String TEST_PROJECT_WITHCONTRACT = "demo-with-contract";
+
+  private static final String TEST_PROJECT_WITHOUTCONTRACT = "demo-without-contract";
+
+  static final String TEST_PROJECT_CONTRACTLOCATION = "contract";
+
+  @Rule
+  public MojoRule rule = new MojoRule();
+
+  @Rule
+  public TestResources resources = new TestResources();
+
+  @Test
+  public void testGenerateMojo() throws Exception {
+    File baseDir = this.resources.getBasedir(TEST_PROJECT_WITHCONTRACT);
+    File baseDirWithoutContract = this.resources.getBasedir(TEST_PROJECT_WITHOUTCONTRACT);
+    File contractLocation = this.resources.getBasedir(TEST_PROJECT_CONTRACTLOCATION);
+
+    File pom = new File(baseDir, "pom.xml");
+    AbstractMojo generateMojo = (AbstractMojo) this.rule.lookupMojo(PLUGIN_GOAL, pom);
+    assertNotNull(generateMojo);
+
+    String testDir = baseDir + File.separator;
+    String testDirWithoutContract = baseDirWithoutContract + File.separator;
+    String classesPath = "target/classes";
+
+    final MavenProject project = mock(MavenProject.class);
+
+    // code has no contract
+    ClassMaker.compile(testDirWithoutContract);
+
+    List<String> runtimeUrlPath = new ArrayList<>();
+    runtimeUrlPath.add(testDirWithoutContract + classesPath);
+
+    given(project.getRuntimeClasspathElements()).willReturn(runtimeUrlPath);
+    rule.setVariableValueToObject(generateMojo, "project", project);
+
+    try {
+      rule.setVariableValueToObject(generateMojo, "sourceType", "code");
+      rule.setVariableValueToObject(generateMojo, "outputDirectory", "./target");
+      generateMojo.execute();
+
+      assertEquals(0, Objects.requireNonNull(
+          Paths.get(rule.getVariableValueFromObject(generateMojo, "contractLocation").toString()).toFile()
+              .listFiles()).length);
+    } catch (MojoFailureException e) {
+      fail();
+    }
+
+    // code has contract
+    ClassMaker.compile(testDir);
+
+    runtimeUrlPath.remove(0);
+    runtimeUrlPath.add(testDir + classesPath);
+    given(project.getRuntimeClasspathElements()).willReturn(runtimeUrlPath);
+
+    rule.setVariableValueToObject(generateMojo, "project", project);
+
+    try {
+      rule.setVariableValueToObject(generateMojo, "sourceType", "code");
+      rule.setVariableValueToObject(generateMojo, "outputDirectory", "./target");
+      rule.setVariableValueToObject(generateMojo, "contractFileType", "yaml");
+      rule.setVariableValueToObject(generateMojo, "documentType", "html");
+      generateMojo.execute();
+    } catch (RuntimeException e) {
+      fail();
+    }
+
+    try {
+      rule.setVariableValueToObject(generateMojo, "sourceType", "code");
+      generateMojo.execute();
+
+      rule.setVariableValueToObject(generateMojo, "outputDirectory", null);
+      generateMojo.execute();
+    } catch (RuntimeException e) {
+      assertEquals("output directory setting is invalid", e.getMessage());
+    }
+
+    try {
+      rule.setVariableValueToObject(generateMojo, "sourceType", "contract");
+      rule.setVariableValueToObject(generateMojo, "contractLocation", null);
+      generateMojo.execute();
+    } catch (RuntimeException e) {
+      assertEquals("contract location is invalid or not set", e.getMessage());
+    }
+
+    try {
+      rule.setVariableValueToObject(generateMojo, "sourceType", "contract");
+      rule.setVariableValueToObject(generateMojo, "contractLocation", "");
+      generateMojo.execute();
+
+      rule.setVariableValueToObject(generateMojo, "contractLocation", "nonexists");
+      generateMojo.execute();
+    } catch (RuntimeException e) {
+      assertThat(e.getMessage(), containsString("is not exists"));
+    }
+  }
+}
\ No newline at end of file
diff --git a/toolkit-maven-plugin/src/test/java/org/apache/servicecomb/toolkit/plugin/GenerateUtilTest.java b/toolkit-maven-plugin/src/test/java/org/apache/servicecomb/toolkit/plugin/GenerateUtilTest.java
new file mode 100644
index 0000000..eaf6d1d
--- /dev/null
+++ b/toolkit-maven-plugin/src/test/java/org/apache/servicecomb/toolkit/plugin/GenerateUtilTest.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.servicecomb.toolkit.plugin;
+
+import static org.apache.servicecomb.toolkit.plugin.GenerateUtil.generateContract;
+import static org.apache.servicecomb.toolkit.plugin.GenerateUtil.generateDocument;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.maven.artifact.DependencyResolutionRequiredException;
+import org.apache.maven.plugin.testing.resources.TestResources;
+import org.apache.maven.project.MavenProject;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class GenerateUtilTest {
+
+  private static final String TEST_PROJECT_CONTRACTLOCATION = "contract";
+
+  @Rule
+  public TestResources resources = new TestResources();
+
+  public GenerateUtilTest() throws IOException {
+  }
+
+
+  @Test
+  public void testGenerateContract() throws DependencyResolutionRequiredException {
+
+    MavenProject project = mock(MavenProject.class);
+
+    generateContract(project, "target/contract", "yaml", "default");
+
+    when(project.getRuntimeClasspathElements()).thenThrow(DependencyResolutionRequiredException.class);
+    try {
+      generateContract(project, "target/contract", "yaml", "default");
+    } catch (RuntimeException e) {
+      assertEquals("failed to get runtime class elements", e.getMessage());
+      return;
+    }
+    fail();
+  }
+
+  @Test
+  public void testGenerateDocument() throws IOException {
+    File contractLocation = resources.getBasedir(TEST_PROJECT_CONTRACTLOCATION);
+    generateDocument(contractLocation.getCanonicalPath(), "target/document", "default");
+
+    try {
+      generateDocument(contractLocation.getCanonicalPath(), "target/document", "others");
+    } catch (RuntimeException e) {
+      assertEquals("DocGenerator's implementation is not found", e.getMessage());
+      return;
+    }
+    fail();
+  }
+}
\ No newline at end of file
diff --git a/toolkit-maven-plugin/src/test/java/plugin/GenerateContractsDocMojoTest.java b/toolkit-maven-plugin/src/test/java/plugin/GenerateContractsDocMojoTest.java
deleted file mode 100755
index 6237d7c..0000000
--- a/toolkit-maven-plugin/src/test/java/plugin/GenerateContractsDocMojoTest.java
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package plugin;
-
-import static org.hamcrest.CoreMatchers.containsString;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.MojoFailureException;
-import org.apache.maven.plugin.testing.MojoRule;
-import org.apache.maven.plugin.testing.resources.TestResources;
-import org.apache.maven.project.MavenProject;
-import org.junit.Rule;
-import org.junit.Test;
-
-import util.ClassMaker;
-
-
-public class GenerateContractsDocMojoTest {
-
-  private static final String PLUGIN_GOAL = "generateDoc";
-
-  private static final String TEST_PROJECT_WITHCONTRACT = "demo-with-contract";
-
-  private static final String TEST_PROJECT_NOCONTRACT = "demo-non-contract";
-
-  private static final String TEST_PROJECT_CONTRACTLOCATION = "contract";
-
-  @Rule
-  public MojoRule rule = new MojoRule();
-
-  @Rule
-  public TestResources resources = new TestResources();
-
-  @Test
-  public void testGenerateContractsDoc() throws Exception {
-
-    File baseDir = this.resources.getBasedir(TEST_PROJECT_WITHCONTRACT);
-    File baseDirNonContract = this.resources.getBasedir(TEST_PROJECT_NOCONTRACT);
-    File contractLocation = this.resources.getBasedir(TEST_PROJECT_CONTRACTLOCATION);
-
-    File pom = new File(baseDir, "pom.xml");
-    AbstractMojo generateContractsDocMojo = (AbstractMojo) this.rule.lookupMojo(PLUGIN_GOAL, pom);
-    assertNotNull(generateContractsDocMojo);
-
-    String testDir = baseDir + File.separator;
-    String testDirNonContract = baseDirNonContract + File.separator;
-    String classesPath = "target/classes";
-    String testDocumentDir = testDir + "document";
-    String testContractDir = contractLocation.getCanonicalPath();
-
-    if (!new File(testDocumentDir).exists()) {
-      assertTrue((new File(testDocumentDir)).mkdirs());
-    }
-
-    final MavenProject project = mock(MavenProject.class);
-
-    // code has no contract
-    ClassMaker.compile(testDirNonContract);
-
-    List<String> runtimeUrlPath = new ArrayList<>();
-    runtimeUrlPath.add(testDirNonContract + classesPath);
-
-    given(project.getRuntimeClasspathElements()).willReturn(runtimeUrlPath);
-    rule.setVariableValueToObject(generateContractsDocMojo, "project", project);
-
-    try {
-      rule.setVariableValueToObject(generateContractsDocMojo, "sourceType", "code");
-      generateContractsDocMojo.execute();
-
-      assertEquals(0, Objects.requireNonNull(
-          Paths.get(rule.getVariableValueFromObject(generateContractsDocMojo, "contractLocation").toString()).toFile()
-              .listFiles()).length);
-    } catch (MojoFailureException e) {
-      fail();
-    }
-
-    // code has contract
-    ClassMaker.compile(testDir);
-
-    runtimeUrlPath.remove(0);
-    runtimeUrlPath.add(testDir + classesPath);
-    given(project.getRuntimeClasspathElements()).willReturn(runtimeUrlPath);
-    rule.setVariableValueToObject(generateContractsDocMojo, "project", project);
-
-    try {
-      rule.setVariableValueToObject(generateContractsDocMojo, "sourceType", "code");
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentOutput", testDocumentDir);
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", "html");
-      generateContractsDocMojo.execute();
-
-      assertNotEquals(0, Files.list(Paths.get(testDocumentDir)).count());
-    } catch (MojoFailureException | IOException e) {
-      fail();
-    }
-
-    try {
-      rule.setVariableValueToObject(generateContractsDocMojo, "sourceType", "contract");
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", "html");
-      rule.setVariableValueToObject(generateContractsDocMojo, "contractLocation", "");
-      generateContractsDocMojo.execute();
-
-      rule.setVariableValueToObject(generateContractsDocMojo, "contractLocation", "nonexitstdir");
-      generateContractsDocMojo.execute();
-    } catch (MojoFailureException e) {
-      assertEquals("contract location is not exists", e.getMessage());
-    }
-
-    String testEmptyDir = testDir + "emptyDir";
-    if (!new File(testEmptyDir).exists()) {
-      assertTrue((new File(testEmptyDir)).mkdirs());
-    }
-    try {
-      rule.setVariableValueToObject(generateContractsDocMojo, "sourceType", "contract");
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", "html");
-      rule.setVariableValueToObject(generateContractsDocMojo, "contractLocation", testEmptyDir);
-      generateContractsDocMojo.execute();
-    } catch (MojoFailureException e) {
-      assertThat(e.getMessage(), containsString("has no contract files"));
-    }
-
-    try {
-      rule.setVariableValueToObject(generateContractsDocMojo, "sourceType", "contract");
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", "html");
-      rule.setVariableValueToObject(generateContractsDocMojo, "contractLocation", testContractDir);
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", "nonImpl");
-      generateContractsDocMojo.execute();
-    } catch (MojoFailureException e) {
-      assertEquals("DocGenerator's implementation is not found", e.getMessage());
-    }
-
-    try {
-      rule.setVariableValueToObject(generateContractsDocMojo, "sourceType", "contract");
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", "html");
-      rule.setVariableValueToObject(generateContractsDocMojo, "contractLocation", testContractDir);
-      rule.setVariableValueToObject(generateContractsDocMojo, "documentType", testDocumentDir);
-      generateContractsDocMojo.execute();
-    } catch (MojoFailureException e) {
-      assertEquals("DocGenerator's implementation is not found", e.getMessage());
-    }
-  }
-}
diff --git a/toolkit-maven-plugin/src/test/java/plugin/GenerateContractsMojoTest.java b/toolkit-maven-plugin/src/test/java/plugin/GenerateContractsMojoTest.java
deleted file mode 100755
index 0475a45..0000000
--- a/toolkit-maven-plugin/src/test/java/plugin/GenerateContractsMojoTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package plugin;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.BDDMockito.given;
-import static org.mockito.Mockito.mock;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.maven.plugin.AbstractMojo;
-import org.apache.maven.plugin.testing.MojoRule;
-import org.apache.maven.plugin.testing.resources.TestResources;
-import org.apache.maven.project.MavenProject;
-import org.apache.servicecomb.toolkit.plugin.GenerateContractsMojo;
-import org.junit.Rule;
-import org.junit.Test;
-
-import util.ClassMaker;
-
-public class GenerateContractsMojoTest {
-
-  private static final String PLUGIN_GOAL = "generateContracts";
-
-  private static final String TEST_PROJECT_CONTRACT = "demo-with-contract";
-
-  @Rule
-  public MojoRule rule = new MojoRule();
-
-  @Rule
-  public TestResources resources = new TestResources();
-
-  @Test
-  public void testGenerateContracts() throws Exception {
-    executeMojo(TEST_PROJECT_CONTRACT, PLUGIN_GOAL);
-  }
-
-  protected void executeMojo(String projectName, String goalName) throws Exception {
-
-    File baseDir = this.resources.getBasedir(projectName);
-    assertNotNull(baseDir);
-    assertTrue(baseDir.exists());
-    assertTrue(baseDir.isDirectory());
-
-    String pomFile = "pom-gencontract.xml";
-    File pom = new File(baseDir, pomFile);
-    AbstractMojo generateContractsMojo = (AbstractMojo) this.rule.lookupMojo(goalName, pom);
-
-    assertNotNull(generateContractsMojo);
-    assertEquals(GenerateContractsMojo.class, generateContractsMojo.getClass());
-
-    final MavenProject project = mock(MavenProject.class);
-    given(project.getFile()).willReturn(pom);
-
-    ClassMaker.compile(baseDir + File.separator + pomFile);
-
-    List<String> runtimeUrlPath = new ArrayList<>();
-    runtimeUrlPath.add(baseDir + File.separator + "target/classes");
-    given(project.getRuntimeClasspathElements()).willReturn(runtimeUrlPath);
-
-    rule.setVariableValueToObject(generateContractsMojo, "project", project);
-    assertNotNull(this.rule.getVariableValueFromObject(generateContractsMojo, "project"));
-
-    assertEquals("target/test_output_contracts",
-        this.rule.getVariableValueFromObject(generateContractsMojo, "outputDir"));
-    assertEquals(".yaml", this.rule.getVariableValueFromObject(generateContractsMojo, "format"));
-
-    generateContractsMojo.execute();
-
-    assertTrue(new File("target/test_output_contracts").exists());
-  }
-}
diff --git a/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml b/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml
index 99bebfe..2999e45 100755
--- a/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml
+++ b/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom-gencontract.xml
@@ -55,10 +55,6 @@
         <artifactId>toolkit-maven-plugin</artifactId>
         <version>${project.version}</version>
         <extensions>true</extensions>
-        <configuration>
-          <outputDir>target/test_output_contracts</outputDir>
-          <format>.yaml</format>
-        </configuration>
       </plugin>
     </plugins>
   </build>
diff --git a/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom.xml b/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom.xml
index 6c799da..66bc85f 100755
--- a/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom.xml
+++ b/toolkit-maven-plugin/src/test/projects/demo-with-contract/pom.xml
@@ -56,9 +56,8 @@
         <version>${project.version}</version>
         <extensions>true</extensions>
         <configuration>
-          <contractLocation>./contract</contractLocation>
-          <documentOutput>./document</documentOutput>
-          <documentType>html</documentType>
+          <!-- Set to 'code' to resolve the current project. Set to 'contract' to resolve the contract file for the specified path.If not set, the default is 'code' -->
+          <sourceType>code</sourceType>
         </configuration>
       </plugin>
     </plugins>
diff --git a/toolkit-maven-plugin/src/test/projects/demo-non-contract/pom-gencontract.xml b/toolkit-maven-plugin/src/test/projects/demo-without-contract/pom-gencontract.xml
similarity index 100%
rename from toolkit-maven-plugin/src/test/projects/demo-non-contract/pom-gencontract.xml
rename to toolkit-maven-plugin/src/test/projects/demo-without-contract/pom-gencontract.xml
diff --git a/toolkit-maven-plugin/src/test/projects/demo-non-contract/pom.xml b/toolkit-maven-plugin/src/test/projects/demo-without-contract/pom.xml
similarity index 89%
rename from toolkit-maven-plugin/src/test/projects/demo-non-contract/pom.xml
rename to toolkit-maven-plugin/src/test/projects/demo-without-contract/pom.xml
index 025fe44..d5d8cea 100755
--- a/toolkit-maven-plugin/src/test/projects/demo-non-contract/pom.xml
+++ b/toolkit-maven-plugin/src/test/projects/demo-without-contract/pom.xml
@@ -51,9 +51,8 @@
         <version>${project.version}</version>
         <extensions>true</extensions>
         <configuration>
-          <contractLocation>./contract</contractLocation>
-          <documentOutput>./document</documentOutput>
-          <documentType>html</documentType>
+          <!-- Set to 'code' to resolve the current project. Set to 'contract' to resolve the contract file for the specified path.If not set, the default is 'code' -->
+          <sourceType>code</sourceType>
         </configuration>
       </plugin>
     </plugins>
diff --git a/toolkit-maven-plugin/src/test/projects/demo-non-contract/src/main/java/demo/Application.java b/toolkit-maven-plugin/src/test/projects/demo-without-contract/src/main/java/demo/Application.java
similarity index 100%
rename from toolkit-maven-plugin/src/test/projects/demo-non-contract/src/main/java/demo/Application.java
rename to toolkit-maven-plugin/src/test/projects/demo-without-contract/src/main/java/demo/Application.java