This plugin is used to create generalized classes based
on multiple versions of this class.
It also generates mappers and a spring-based converter
to convert general classes to versioned ones and vice versa.
Explore the docs »
View Demo
·
Report Bug
·
Request Feature
This plugin is used to create generalized classes based on multiple versions of this class. It also generates mappers, and a spring-based converter to convert general classes to versioned ones and vice versa.
Let's assume we have a long-living project which has a following class.
package mypackage.ver1;
import lombok.Data;
@Data
public class Dog {
private String name;
}
Eventually this project evolves and so does our class. Some fields get added, some removed, but we have to support all versions of this class in our projects. So we end up with multiple version of Dog, located in corresponding packages.
package mypackage.ver2;
import lombok.Data;
@Data
public class Dog {
private String name;
private int age;
}
package mypackage.ver3;
import lombok.Data;
@Data
public class Dog {
private String name;
private int age;
private Breed breed;
private enum Breed {
HUSKY,
POODLE,
SHIBA_INU,
POMERANIAN
}
}
For a developer it is not convenient to write separate logic for working with each version of the Dog class, it would be much simpler to use a single representation of the Dog.
That's where this plugin comes in. This plugin generates a generalized version of the Dog class which looks like this.
package mypackage.general;
import lombok.Data;
import lombok.Getter;
import lombok.EqualsAndHashCode;
import io.github.pinkolik.general_classes_generator.conversion.Generalized;
@Data
public class Dog implements Generalized {
//GENERATED FIELDS START
private int age;
private mypackage.general.Dog.Breed breed;
private java.lang.String name;
//GENERATED FIELDS END
//GENERATED INNER CLASSES START
public static enum Breed implements Generalized {
//GENERATED FIELDS START
HUSKY,
POMERANIAN,
POODLE,
SHIBA_INU
//GENERATED FIELDS END
//GENERATED INNER CLASSES START
//${inner_classes}
//GENERATED INNER CLASSES END
}
//GENERATED INNER CLASSES END
}
As you can see, the generalized version contains all fields of the previous versions, so that basically means that it can be used in code for processing any version of the Dog.
It also generates a set of mappers which will help you to convert generalized class to versioned one and vice versa. Example of a mapper.
package mypackage.mappers.ver1;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import io.github.pinkolik.general_classes_generator.conversion.BaseMapper;
@Mapper(uses = {})
public interface DogMapper extends BaseMapper<mypackage.ver1.Dog, mypackage.general.Dog> {
DogMapper INSTANCE = Mappers.getMapper(DogMapper.class);
}
BaseMapper interface looks like this .
This plugin also generates a spring configuration for BaseConverter which is useful, when you need a universal tool to convert any class from a package. So you don't have to look for a concrete mapper, you can just use this converter.
To get a local copy up and running follow these simple steps.
Tools needed to build this project.
- Maven
- Clone the repo
git clone https://github.com/Pinkolik/general-classes-generator.git
- Build the project
mvn clean install
Add this to your pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<build>
<plugins>
...
<plugin>
<groupId>io.github.pinkolik</groupId>
<artifactId>general-classes-generator-maven-plugin</artifactId>
<version>1.1.3-RELEASE</version>
<executions>
<execution>
<id>generate-general-classes</id>
<goals>
<goal>generate-general-classes</goal>
</goals>
<configuration>
<versionClassesBasePath>
${project.parent.basedir}/versioned-classes/src/main/java/com/my/package/versioned
</versionClassesBasePath>
<versionRegexPattern>ver\d+</versionRegexPattern>
<outputBasePath>
${project.parent.basedir}/general-classes/src/main/java
</outputBasePath>
<makeSerializable>true</makeSerializable>
</configuration>
</execution>
</executions>
<dependencies>
<!-- You have to add dependency to your versioned classes.-->
<dependency>
<groupId>com.my.package</groupId>
<artifactId>versioned-classes</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
</build>
...
</project>
Add this to your pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<properties>
<org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
<lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
<lombok.version>1.18.20</lombok.version>
</properties>
...
<dependencies>
...
<dependency>
<groupId>io.github.pinkolik</groupId>
<artifactId>general-classes-generator-conversion</artifactId>
<version>1.1.3-RELEASE</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
...
</dependencies>
...
<build>
...
<plugins>
...
<plugin>
<groupId>io.github.pinkolik</groupId>
<artifactId>general-classes-generator-maven-plugin</artifactId>
<version>1.1.3-RELEASE</version>
<executions>
<execution>
<id>generate-mappers</id>
<goals>
<goal>generate-mappers</goal>
</goals>
<configuration>
<versionClassesBasePath>
${project.parent.basedir}/versioned-classes/src/main/java/com/my/package/versioned
</versionClassesBasePath>
<versionRegexPattern>ver\d+</versionRegexPattern>
<outputBasePath>
${project.parent.basedir}/mappers/src/main/java/com/my/package/mappers
</outputBasePath>
</configuration>
</execution>
</executions>
<dependencies>
<!-- You have to add dependency to your versioned classes.-->
<dependency>
<groupId>com.my.package</groupId>
<artifactId>versioned-classes</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<!-- See https://maven.apache.org/plugins/maven-compiler-plugin/compile-mojo.html -->
<!-- Classpath elements to supply as annotation processor path. If specified, the compiler -->
<!-- will detect annotation processors only in those classpath elements. If omitted, the -->
<!-- default classpath is used to detect annotation processors. The detection itself depends -->
<!-- on the configuration of annotationProcessors. -->
<!-- -->
<!-- According to this documentation, the provided dependency processor is not considered! -->
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok-mapstruct-binding</artifactId>
<version>${lombok-mapstruct-binding.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</pluginManagement>
...
</build>
...
</project>
Add this to your pom.xml.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<dependencies>
...
<dependency>
<groupId>io.github.pinkolik</groupId>
<artifactId>general-classes-generator-conversion</artifactId>
<version>1.1.3-RELEASE</version>
</dependency>
...
</dependencies>
...
<build>
...
<plugins>
...
<plugin>
<groupId>io.github.pinkolik</groupId>
<artifactId>general-classes-generator-maven-plugin</artifactId>
<version>1.1.3-RELEASE</version>
<executions>
<execution>
<id>generate-base-converters-config</id>
<goals>
<goal>generate-base-converters-config</goal>
</goals>
<configuration>
<versionClassesBasePath>
${project.parent.basedir}/versioned-classes/src/main/java/com/my/package/versioned
</versionClassesBasePath>
<versionRegexPattern>ver\d+</versionRegexPattern>
<mappersBasePath>
${project.parent.basedir}/mappers/src/main/java/com/my/package/mappers
</mappersBasePath>
<outputPath>
${project.parent.basedir}/converter/src/main/java/com/my/package/converter
</outputPath>
</configuration>
</execution>
</executions>
<dependencies>
<!-- You have to add dependency to your versioned classes.-->
<dependency>
<groupId>com.my.package</groupId>
<artifactId>versioned-classes</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
...
</build>
...
</project>
For more examples, please refer to the Documentation
See the open issues for a list of proposed features (and known issues).
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the MIT License. See LICENSE
for more information.
Simon Rusinov - mrpinkolik@gmail.com
Project Link: https://github.com/Pinkolik/general-classes-generator