idoc, an artifact generated automatically from java documents

Write document

As a developer, everyone has to write code.

At work, almost every developer has to write documents.

Because the work is the cooperation between people, the product needs to write requirements documents, the development needs to write detailed design documents and interface documents.

However, as a lazy person, one of the most annoying things is to write documents.

What annoys me most about writing documents is that the code comments need to be changed again, and then the documents need to be changed again.

All repeated work is the biggest waste of our valuable fishing time.

So, I often think, can you just write it once?

i-doc project introduction

idoc Generate project documents for java projects.

Generate introduction documents as much as possible based on native java annotations. Users can customize their own templates and generate documents they need.

Implementation principle: Based on maven plug-in, similar to javadoc. Can be more flexible, allowing users to customize.

characteristic

(1) Generate metadata containing most of the information based on the maven project

(2) By default, markdown is supported to simplify document generation, and user-defined templates are supported

(3) Support user-defined document generator

(4) Supports user-defined class filters for generated documents

(5) Add field type alias to support user customization

quick get start

need

jdk1.8+

maven 3.x+

maven introduction

Use maven to introduce the current idoc plug-in.

<build>
    <plugins>
        <plugin>
            <groupId>com.github.houbb</groupId>
            <artifactId>idoc-core</artifactId>
            <version>0.3.0</version>
        </plugin>
    </plugins>
</build>

Creation of test object

To demonstrate the document, we created an Address object.

package com.github.houbb.idoc.test.model;

/**
 * address
 * @author binbin.hou
 * @since 0.0.1
 */
public class Address {

    /**
     * city
     */
    private String country;

    /**
     * street
     */
    private String street;

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }
}

Execute plug-in

mvn com.github.houbb:idoc-core:0.3.0:idoc

Command line log information

[INFO] ------------------------------------ Start generate doc
[INFO] A total of [1] files are pending. Please wait patiently. The progress is as follows:
==================================================================================================== 100%
[INFO] Generator doc with docGenerator: com.github.houbb.idoc.core.api.generator.ConsoleDocGenerator
[INFO] ------------------------------------ The document information is as follows:

[Class name] com.github.houbb.idoc.test.model.Address
[Class information] {"comment":"address","docAnnotationList":[],"docFieldList":[{"comment":"city","name":"country","type":"java.lang.String"},{"comment":"street","name":"street","type":"java.lang.String"}],"docMethodList":[{"docMethodParameterList":[],"docMethodReturn":{"fullName":"java.lang.String","name":"String","packageName":"java.lang"},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"getCountry","seeList":[],"signature":"getCountry()"},{"docMethodParameterList":[{"docAnnotationList":[],"name":"country","type":"java.lang.String"}],"docMethodReturn":{},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"setCountry","seeList":[],"signature":"setCountry(country)"},{"docMethodParameterList":[],"docMethodReturn":{"fullName":"java.lang.String","name":"String","packageName":"java.lang"},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"getStreet","seeList":[],"signature":"getStreet()"},{"docMethodParameterList":[{"docAnnotationList":[],"name":"street","type":"java.lang.String"}],"docMethodReturn":{},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"setStreet","seeList":[],"signature":"setStreet(street)"}],"docTagList":[{"lineNum":5,"name":"author","parameters":["binbin.hou"],"value":"binbin.hou"},{"lineNum":6,"name":"since","parameters":["0.0.1"],"value":"0.0.1"}],"fullName":"com.github.houbb.idoc.test.model.Address","modifiers":["public"],"name":"Address","packageName":"com.github.houbb.idoc.test.model"}

[INFO] ------------------------------------ Finish generate doc

More generation methods

Of course, you can find that the metadata is only output to the console, which is of little significance.

We can customize the implementation to generate classes according to our needs.

For example, in the following way, you can use the built-in MarkdownDocGenerator to output to the markdown file.

<plugin>
    <groupId>com.github.houbb</groupId>
    <artifactId>idoc-core</artifactId>
    <version>0.3.0</version>
    <configuration>
        <generates>
            <generate>com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator</generate>
        </generates>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>com.github.houbb</groupId>
            <artifactId>idoc-ftl</artifactId>
            <version>0.3.0</version>
        </dependency>
    </dependencies>
</plugin>

Refer to:

heaven document directory

ps: heaven The project is a toolkit that individuals have sorted out for many years, hundreds of classes, and handwritten documents. It is estimated that it will take a long time.

Original design intention

Saving time

Java documentation has always been a big problem.

Many projects do not write documents. Even if they do, it is very painful for developers.

The disadvantages of not writing documents are not many, and the disadvantages of writing documents manually are also obvious:

  1. It's a waste of time and can make mistakes.

  2. Timely updates cannot be guaranteed. The code has changed, but the document needs to be modified synchronously. People need to be forced to maintain this consistency. It's very hard.

Why not swagger UI

There are several types of java documents:

  1. jdk built-in doc generation. This practice has been used by others before. Others use C #, and it's painful to see the default document of java.

Even we java developers hate reading jdk documents. It looks ugly and tired.

  1. Swagger UI is a document generation tool based on java annotations. Relatively elegant and powerful.

But there are also shortcomings. Developers should write jdk original comments + comments. Too many comments made it painful to write, and most developers chose to give up later.

So here comes the question...? What can we do to make developers and document readers happy to accept it as much as possible?

The doc provided with jdk is based on maven plug-in, and so is this project.

The differences are as follows:

  1. Ensure the consistency with Java Native annotations as much as possible, so that developers can use them easily.

  2. The information is as comprehensive as possible, but the documents are concise. Let document readers enjoy the experience equivalent to handwritten documents.

  3. Distinguish the acquisition and generation of information. It is convenient for users to define their own output mode.

Parameter configuration description

In order to more flexibly generate documents and document metadata, the following parameters are provided

Introduction to plug-in configuration properties

attributeRequiredexplainDefault valueremarks
encodingnoItem codeUTF-8
includesnoFile information contained in metadata**\/*.javaAll java files are scanned by default
excludesnoFile information excluded by metadatanothingNot excluded by default
isOverwriteWhenExistsnoOverwrite when document existstrue
isAllInOnenoWhether all class information generates a single documenttrueCommand line document generator, this property is meaningless.
generatesnoDocument generation classCommand line document generation informationYou can specify multiple at the same time. Full name of the class. See com.github.houbb.idoc.api.core.genenrator.IDocGenerator for user customization
generateFiltersnoDocument generation class filternothingYou can specify multiple at the same time. Full name of the class. See com.github.houbb.idoc.api.core.filter.IDocGenerateFilter for user customization
targetDirnoGenerate target file directorynothingCustom specifies the folder where the document is generated

isAllInOne

Simple documents are recommended to be generated directly in a file.

If it is complex, it can be set to false, and it will be set according to

Issues related to generators

The default command line document is mainly used for demonstration and information viewing, which has no practical significance.

It is recommended to introduce IDoc FTL module and use MarkdownDocGenerator generator.

You can specify multiple at the same time.

IDoc API can be introduced for self definition.

generateFilters recommendations

The actual document is mainly concerned with the defined method.

We can filter the package name of DocClass and only generate Service method documents.

If it is based on the previous, you can add @ since @version and other information filtering.

You can specify multiple at the same time.

IDoc API can be introduced for self definition.

Custom Filter

You can refer to the IDoc test module of the current project.

The overall configuration is as follows:

<build>
    <plugins>
        <plugin>
            <groupId>com.github.houbb</groupId>
            <artifactId>idoc-core</artifactId>
            <version>0.3.0</version>
            <configuration>
                <isAllInOne>true</isAllInOne>
                <generates>
                    <generate>com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator</generate>
                </generates>
                <generateFilters>
                    <generateFilter>com.github.houbb.idoc.test.filter.MyGenerateFilter</generateFilter>
                </generateFilters>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>com.github.houbb</groupId>
                    <artifactId>idoc-test</artifactId>
                    <version>${project.version}</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

Specify document builder

Specifies that you can use the Markdown document generator to specify multiple documents at the same time.

<generates>
    <generate>com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator</generate>
</generates>

Import package

The MarkdownDocGenerator needs to introduce corresponding dependencies in the IDoc FTL module.

Of course, IDoc core relies on IDoc FTL by default.

Specifies the filter for the file generation class

If you do not define your own class generation filter, all class information will be generated.

In general, we only care about the service method, so we add the filter implementation of the class.

The implementation is as follows:

Introducing IDoc API package

<dependency>
    <groupId>com.github.houbb</groupId>
    <artifactId>idoc-api</artifactId>
    <version>${project.version}</version>
</dependency>

Implement IDocGenerateFilter

package com.github.houbb.idoc.test.filter;

import com.github.houbb.idoc.api.core.filter.IDocGenerateFilter;
import com.github.houbb.idoc.api.model.metadata.DocClass;

/**
 * Custom build filter
 * @author binbin.hou
 * @since 0.0.1
 */
public class MyGenerateFilter implements IDocGenerateFilter {

    @Override
    public boolean include(DocClass docClass) {
        if("QueryUserService".equalsIgnoreCase(docClass.getName())) {
            return true;
        }
        return false;
    }

}

Configuration and use in plug-in

<generateFilters>
    <generateFilter>com.github.houbb.idoc.test.filter.MyGenerateFilter</generateFilter>
</generateFilters>

Note that you also need to add dependencies to the jar that defines this filter, otherwise the corresponding class information cannot be found.

<dependencies>
    <dependency>
        <groupId>com.github.houbb</groupId>
        <artifactId>idoc-test</artifactId>
        <version>${project.version}</version>
    </dependency>
</dependencies>

Class code information

User information

/**
 * User information
 * @author binbin.hou
 * @since 0.0.1
 */
public class User {

    /**
     * name
     * @require yes
     * @remark Chinese name, please fill in carefully
     */
    private String name;

    /**
     * Age
     */
    private int age;

    /**
     * birthday
     */
    private Date birthday;

    /**
     * address
     */
    private List<Address> addressList;

    /**
     * partner
     */
    private User mate;
    
    //...
}

i-doc defined tags

@require indicates whether the current field is required. When entering a parameter as a method.

@remark indicates the comment information of the current field.

Method class information

  • QueryUserService.java
/**
 * Query user service class
 * @author binbin.hou
 * @since 0.0.1
 */
public interface QueryUserService {

    /**
     * Query users according to user information
     * @param user User information
     * @return result
     * @since 0.0.2,2019/02/12
     */
    public User queryUser(final User user);

}

Execute plug-in

mvn com.github.houbb:idoc-core:0.3.0:idoc
  • log information
[INFO] ------------------------------------ Start generate doc
[INFO] There are [4] documents to be processed in total. Please wait patiently. The progress is as follows:
==================================================================================================== 100%
[INFO] Generator doc with docGenerator: com.github.houbb.idoc.ftl.api.generator.MarkdownDocGenerator
[INFO] Markdown Generate document file all in one route: /Users/houbinbin/code/_github/idoc/idoc-test/src/main/resources/idoc-gen/idoc-test-All documents.md
[INFO] ------------------------------------ Finish generate doc

document information

The current file path log will be printed. For example, my own test is:

/Users/houbinbin/code/_ GitHub / IDoc / IDoc test / SRC / main / resources / IDoc Gen / IDoc test - all documents.md

Document generation effect

See documentation:

IDoc test - all documents.md

Field type alias support

You can refer to the IDoc test module of the current project.

Why

Sometimes the page display type, I hope it is more friendly.

Therefore, the system has built-in alias display and supports user-defined aliases.

Alias for type field

Built in system

The current version of the system provides common aliases.

See com.github.houbb.idoc.core.util.JavaTypeAliasUtil for details

typeNickname
java.lang.Floatfloat
java.lang.Doublefloat
java.util.Datedate
java.time.LocalDateTimeDate time
java.util.Currencycurrency
floatfloat
java.lang.Integerinteger
longLong integer
java.math.BigDecimalnumber
java.lang.Charactercharacter
java.lang.LongLong integer
java.lang.ShortShort
java.util.Mapmapping
java.time.LocalTimetime
java.lang.BooleanBoolean value
java.math.BigIntegernumber
java.lang.Stringcharacter string
java.lang.Bytebyte
doublefloat
bytebyte
java.util.Collectionaggregate
intinteger
java.util.Listlist
booleanBoolean value
java.time.LocalDatedate
charcharacter
shortShort
voidempty
arrayarray

Custom mode

You can specify custom field nicknames through typeAlias.

<configuration>
    <generateFilters>
        <generateFilter>com.github.houbb.idoc.test.filter.MyGenerateFilter</generateFilter>
    </generateFilters>
    <isAllInOne>true</isAllInOne>
    <typeAliases>
        <typeAlias>
            <key>java.lang.String</key>
            <value>String Custom description</value>
        </typeAlias>
    </typeAliases>
</configuration>

priority

The user-defined field alias has higher priority than the system default.

The alias defined later will directly overwrite the previous alias.

Test code demonstration

Object definition

/**
 * Alias test
 * @author binbin.hou
 * @since 0.0.1
 */
public class TypeAliasSimpleBean {

    /**
     * name
     */
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Test log

The running test log is as follows:

{"comment":"Alias test","docAnnotationList":[],"docFieldList":[{"comment":"name","name":"name","type":"java.lang.String","typeAlias":"String Custom description"}],"docMethodList":[{"docMethodParameterList":[],"docMethodReturn":{"fullName":"java.lang.String","name":"String","packageName":"java.lang"},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"getName","seeList":[],"signature":"getName()"},{"docMethodParameterList":[{"docAnnotationList":[],"name":"name","type":"java.lang.String","typeAlias":"String Custom description"}],"docMethodReturn":{},"docTagList":[],"exceptionList":[],"modifiers":["public"],"name":"setName","seeList":[],"signature":"setName(name)"}],"docTagList":[{"lineNum":5,"name":"author","parameters":["binbin.hou"],"value":"binbin.hou"},{"lineNum":6,"name":"since","parameters":["0.0.1"],"value":"0.0.1"}],"fullName":"com.github.houbb.idoc.test.model.TypeAliasSimpleBean","modifiers":["public"],"name":"TypeAliasSimpleBean","packageName":"com.github.houbb.idoc.test.model"}

typeAlias is the alias of field type, which can be used to display field information more friendly.

Other thoughts

Convenience of customization

It is more convenient to customize the method based on xml.

However, it is not so convenient when there are a large number. Originally, it was considered to add the corresponding configuration attribute interface. Under the balance, the xml configuration method was used.

Use comment information?

If an alias is not specified for a field, do you want to use the comment information instead?

It is recommended to use. The current version will not be processed.

  • Why

Most people prefer to see explanations rather than lengthy class information.

If it is for isomorphic systems (all java language), it can be understood.

If it is aimed at heterogeneous systems (such as PHP in the foreground), it is not easy to understand.

  • Why not deal with it

Most interfaces are common fields with low cost performance.

There may be no comment s in the field, which will lead to the complexity of judgment.

If the user does not want to use an alias

You can directly modify the template and use the original field type attribute.

Open source address

https://github.com/houbb/idoc

Of course, this project still has a long way to go.

If you like, welcome fork star~

Keywords: Java Maven RESTful

Added by sycoj0ker on Thu, 14 Oct 2021 20:36:00 +0300