Skip to content

Commit

Permalink
Merge pull request #9 from careem/master
Browse files Browse the repository at this point in the history
Merge master into 0.6.x
  • Loading branch information
aneelkkhatri-careem authored Jun 2, 2020
2 parents 9645e91 + 98e2496 commit 7800bca
Show file tree
Hide file tree
Showing 57 changed files with 248 additions and 547 deletions.
15 changes: 11 additions & 4 deletions .github/workflows/maven-ci.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven

name: ci
name: maven-ci

on:
push:
Expand All @@ -11,7 +11,7 @@ on:
paths-ignore:
- '**.md'
- '.gitignore'
- '.github/workflows/**'
- '.github/workflows/maven-cd.yml'

pull_request:
branches-ignore: [ ]
Expand All @@ -35,11 +35,18 @@ jobs:
with:
java-version: 1.8
- name: Build with Maven
run: mvn -B package --file pom.xml
run: mvn -B clean install -Dmaven.gpg.skip=true org.sonarsource.scanner.maven:sonar-maven-plugin:3.6.0.1398:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.organization=$SONAR_ORGANIZATION -Dsonar.projectKey=$SONAR_PROJECT_KEY
env:
SONAR_LOGIN: ${{ secrets.SONAR_LOGIN }}
SONAR_PROJECT_KEY: 'converter-codegen'
SONAR_ORGANIZATION: 'careem'
SONAR_HOST_URL: 'https://sonarcloud.io'
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

# - name: SonarCloud Scan
# uses: sonarsource/sonarcloud-github-action@master
# with:
# java-version: 1.8
# projectBaseDir: .
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
326 changes: 14 additions & 312 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
![version](https://img.shields.io/badge/version-0.6.19-blue)
# converter-annotation-processor

[![Maven Central](https://img.shields.io/maven-central/v/io.github.careem/converter-annotation-processor.svg?label=Maven%20Central)](https://search.maven.org/artifact/io.github.careem/converter-annotation-processor)
[![javadoc](https://javadoc.io/badge2/io.github.careem/converter-annotation-processor/javadoc.svg)](https://www.javadoc.io/doc/io.github.careem/converter-annotation-processor)
![ci](https://github.com/careem/converter-codegen/workflows/ci/badge.svg?branch=0.6.x)
[![Sonarcloud Status](https://sonarcloud.io/api/project_badges/measure?project=converter-codegen&metric=alert_status)](https://sonarcloud.io/dashboard?id=converter-codegen)
[![SonarCloud Bugs](https://sonarcloud.io/api/project_badges/measure?project=converter-codegen&metric=bugs)](https://sonarcloud.io/component_measures/metric/reliability_rating/list?id=converter-codegen)
[![SonarCloud Vulnerabilities](https://sonarcloud.io/api/project_badges/measure?project=converter-codegen&metric=vulnerabilities)](https://sonarcloud.io/component_measures/metric/security_rating/list?id=converter-codegen)

> A Java library that auto-generates converters.
Generates converters through annotation processing
![screenshots](https://raw.githubusercontent.com/careem/converter-codegen/gh-pages/img/screenshots.gif)

## Setup
Add the following dependency in your `pom.xml` file:
Expand All @@ -14,315 +22,9 @@ Add the following dependency in your `pom.xml` file:
```
That's it, you are ready to generate converters!

## How to use?
Let's go through examples:
### Example 1
Consider the following classes:
```java
package com.careem.dtos;

public class Dto1 {
Integer value;
}
```
```java
package com.careem.a;

import com.careem.dtos.Dto1;
import lombok.Getter;

@Getter
public class ClassA {
Integer field1;
String field2;
Integer field3;
Dto1 field4;
}
```
```java
package com.careem.b;

import lombok.Builder;

@Builder
public class ClassB {
Integer field1;
Integer field2;
String field3;
String field4;
}
```
To generate a `ClassA` to `ClassB` converter, add `@Converter` annotation on `ClassB` as follows:

```java
@Converter(sourceClass = ClassA.class)
@Builder
public class ClassB {
//...
}
```
Compiling the code will generate
```java
package com.careem.a;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import com.careem.b.ClassB;
import com.careem.dtos.Dto1;
import com.google.gson.Gson;

@Component
public class ClassAToClassBConverter implements Converter<ClassA, ClassB> {
private final Gson gson;

public ClassAToClassBConverter(Gson gson) {
this.gson = gson;
}

@NonNull
@Override
public ClassB convert( ClassA from) {
return ClassB.builder()
.field1(from.getField1())
.field3(String.valueOf(from.getField3()))
.field2(Integer.valueOf(from.getField2()))
.field4(this.gson.toJson(from.getField4(), Dto1.class))
.build();
}
}

```

### Example 2 (using hard coded value, and imports)
Consider the following classes:
```java
package com.careem.a;

import com.careem.dtos.Dto1;
import lombok.Getter;

@Getter
public class ClassA {
Integer field1;
String field2;
Integer field3;
}
```
```java
package com.careem.b;

import lombok.Builder;

@Builder
public class ClassB {
Integer field1;
Integer field2;
String field3;
String field4;
}
```
To generate a `ClassA` to `ClassB` converter, and set field4 value from some other source (e.g. com.careem.Constants.FIELD4), add `@Converter` annotation on `ClassB`, and `@ConveterMapping` on `field4` as follows:

```java
@Converter(sourceClass = ClassA.class, imports = @Converter.Import(value = "com.careem.Constants"))
@Builder
public class ClassB {
//...
@ConverterMapping(sourceClass = ClassA.class, value = "Constants.FIELD4")
String field4
}
```
Compiling the code will generate
```java
package com.careem.a;

import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import com.careem.b.ClassB;
import com.careem.dtos.Dto1;
import com.google.gson.Gson;
## Usage

@Component
public class ClassAToClassBConverter implements Converter<ClassA, ClassB> {
private final Gson gson;
Please visit [usage](https://careem.github.io/converter-codegen/usage).

public ClassAToClassBConverter(Gson gson) {
this.gson = gson;
}

@NonNull
@Override
public ClassB convert( ClassA from) {
return ClassB.builder()
.field1(from.getField1())
.field3(String.valueOf(from.getField3()))
.field2(Integer.valueOf(from.getField2()))
.field4(Constants.FIELD4)
.build();
}
}

```
### Example 3 (creating multiple converters)
Consider the following
```java
class ClassA {
String fieldA;
}
```
```java
class ClassB {
String fieldB;
}
```
```java
class ClassC {
String fieldC;
}
```
To generate `ClassB` to `ClassA` converter as well as `ClassC` to `ClassA` converter, we annotate `ClassA` as follows
```java
@Converter(sourceClass = ClassB.class)
@Converter(sourceClass = ClassC.class)
class ClassA{
@ConverterMapping(sourceClass = ClassB.class, field = "fieldB")
@ConverterMapping(sourceClass = ClassC.class, field = "fieldC")
String fieldA;
}
```

### Example 4 (using interfaceTargetClass)
Consider the following
```java
@Getter
class ClassA {
}
```
```java
abstract class ClassB {
}
```
```java
@Builder
@Converter(sourceClass = ClassA.class)
class ClassC extends ClassB {
}
```
then compiling will generate following converter
```java
class ClassAToClassCConverter implements Converter<ClassA, ClassC> {
@NonNull ClassC convert(ClassA from) {
return ClassC.builder()
.build();
}
}
```
but, if we instead annotate ClassC as follows
```java
@Builder
@Converter(sourceClass = ClassA.class, interfaceTargetClass = ClassB.class)
class ClassC extends ClassB {
}
```
then compiling will generate following conveter
```java
class ClassAToClassCConverter implements Converter<ClassA, ClassB> {
@NonNull ClassB convert(ClassA from) {
return ClassC.builder()
.build();
}
}
```

### Example 5 (when `@Builder` is added on constructor)
Consider the following
```java
@AllArgsConstructor
class ClassX {
String field1;
String field2;
}
```
```java
class ClassA {
String field1;
}
```
```java
class ClassB extends ClassA {
String field2;

@Builder
public ClassB(String field1, String field2) {
super(field1);
this.field2 = field2;
}
}
```
then to generate `ClassX` to `ClassB` converter that considers all fields in the builder of `ClassB` (here `field1` and `field2`), we need to add the `@Converter` annotation on the constructor like
```java
class ClassB extends ClassA {
String field2;

@Converter(sourceClass = ClassX.class)
@Builder
public ClassB(String field1, String field2) {
super(field1);
this.field2 = field2;
}
}
```

### Example 6 (assumed converter)
Consider the following:
```java
abstract class ClassA {
}
```
```java
abstract class ClassB {
}
```
```java
class ClassAX extends ClassA {
}
```
```java
class ClassBX extends ClassB {
}
```
assuming there exists (or is auto-generated) `ClassAX` to `ClassBX` converter (with `ClassB` as second type argument in `Converter`) as follows:
```java
class ClassAXToClassBXConverter implements Converter<ClassAX, ClassB> {
@Override
public ClassB convert(ClassAX from) {
return ClassBX.builder()
// ... set properties
.build();
}
}
```
then consider
```java
class ClassC {
ClassA classA; // this will have only derived class objects
}
```
```java
@Converter(sourceClass = ClassC.class)
class ClassD {
ClassB classB; // this will have only derived class objects
}
```
the above will fail the compilation because converter annotation processor won't be able to find `ClassA` to `ClassB` converter, but we already have a converter to convert from `ClassAX` to `ClassBX`. To generate `ClassC` to `ClassD` converter, we will need to make the converter annotation processor assume that there already exists a `ClassA` to `ClassB` converter. Which can be achieved by `assumed` field as follows:
```java
@Converter(sourceClass = ClassA.class, assumed = true)
class ClassB {
//...
}
```
the above will not generate a converter but would allow continuing the annotation processing.
## Contributing
Please visit [contributing](https://careem.github.io/converter-codegen/contributing).

This file was deleted.

This file was deleted.

Loading

0 comments on commit 7800bca

Please sign in to comment.