Skip to content
This repository was archived by the owner on Jun 11, 2023. It is now read-only.

Commit d0232bd

Browse files
committed
<feature/nested_field> Implemented recursive mapping generation
1 parent d5902ee commit d0232bd

File tree

12 files changed

+159
-36
lines changed

12 files changed

+159
-36
lines changed

library/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ buildscript {
1010
apply plugin: 'java'
1111
apply plugin: 'com.novoda.bintray-release'
1212

13+
targetCompatibility = '1.7'
14+
sourceCompatibility = '1.7'
15+
1316
dependencies {
1417
testCompile 'junit:junit:4.11'
1518
}

library/library.iml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
</configuration>
1414
</facet>
1515
</component>
16-
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="false">
16+
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
1717
<output url="file://$MODULE_DIR$/build/classes/java/main" />
1818
<output-test url="file://$MODULE_DIR$/build/classes/java/test" />
1919
<exclude-output />

processor/src/main/java/com/devindi/mapper/MapperGenerator.java

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@
77
import com.squareup.javapoet.TypeSpec;
88

99
import java.util.ArrayList;
10+
import java.util.Collections;
1011
import java.util.HashMap;
12+
import java.util.HashSet;
1113
import java.util.List;
1214
import java.util.Map;
15+
import java.util.Set;
1316

1417
import javax.annotation.processing.ProcessingEnvironment;
1518
import javax.lang.model.element.Element;
@@ -35,14 +38,11 @@ static MapperGenerator create(TypeElement element, ProcessingEnvironment env) {
3538

3639
private final TypeElement element;
3740
private final ProcessingEnvironment processingEnv;
38-
private List<MappingInfo> mappings;
39-
private List<MappingInfo> autoMappings;
41+
private Set<MappingInfo> mappings;
4042

4143
private MapperGenerator(TypeElement mapperElement, ProcessingEnvironment processingEnvironment) {
4244
this.processingEnv = processingEnvironment;
4345
this.element = mapperElement;
44-
mappings = new ArrayList<>();
45-
autoMappings = new ArrayList<>();
4646
}
4747

4848
public TypeSpec generate() {
@@ -57,23 +57,59 @@ public TypeSpec generate() {
5757
implBuilder.addMethod(methodSpec);
5858
}
5959

60-
for (MappingInfo autoMapping : autoMappings) {
61-
MethodSpec methodSpec = generateMappingMethod(autoMapping);
62-
implBuilder.addMethod(methodSpec);
63-
}
64-
65-
6660
return implBuilder.build();
6761
}
6862

6963
private void collectMappings() {
64+
mappings = new HashSet<>();
7065
for (ExecutableElement method : ElementFilter.methodsIn(element.getEnclosedElements())) {
7166
try {
7267
mappings.add(new MappingInfo(method));
7368
} catch (IllegalArgumentException exc) {
7469
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, exc.getMessage(), method);
7570
}
7671
}
72+
73+
Set<MappingInfo> lastRow = mappings;
74+
Set<MappingInfo> nextRow = new HashSet<>();
75+
do {
76+
for (MappingInfo mappingInfo : lastRow) {
77+
nextRow.addAll(createDependencies(mappingInfo));
78+
}
79+
mappings.addAll(nextRow);
80+
lastRow = nextRow;
81+
nextRow = new HashSet<>();
82+
} while (!lastRow.isEmpty());
83+
84+
System.out.println("mappings = " + mappings);
85+
}
86+
87+
private List<MappingInfo> createDependencies(MappingInfo info) {
88+
List<MappingInfo> result = new ArrayList<>();
89+
ExecutableElement constructorElement = getConstructorElement(info.getTargetType().toString());
90+
List<? extends VariableElement> constructorParameters = constructorElement.getParameters();
91+
92+
Map<String, ExecutableElement> argumentGetters = getGetters(info.getSourceType().toString());
93+
94+
if (constructorParameters.size() != argumentGetters.size()) {
95+
processingEnv.getMessager().printMessage(Diagnostic.Kind.MANDATORY_WARNING, "Target constructor have different arguments count", info.getMethod());
96+
}
97+
98+
for (VariableElement parameter : constructorParameters) {
99+
String sourceFieldName = info.getSourceFieldName(parameter.getSimpleName().toString().toLowerCase());
100+
ExecutableElement getter = argumentGetters.get(sourceFieldName.toLowerCase());
101+
if (getter == null) {
102+
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Failed to find getter at source for target field", parameter);
103+
return Collections.emptyList();
104+
}
105+
if (!parameter.asType().equals(getter.getReturnType())) {
106+
MappingInfo fieldMapping = findMapping(getter.getReturnType(), parameter.asType());
107+
if (fieldMapping == null) {
108+
result.add(new MappingInfo(getter.getReturnType(), parameter.asType()));
109+
}
110+
}
111+
}
112+
return result;
77113
}
78114

79115
private MethodSpec generateMappingMethod(MappingInfo mapping) {
@@ -99,16 +135,14 @@ private MethodSpec generateMappingMethod(MappingInfo mapping) {
99135
for (VariableElement constructorParameter : constructorParameters) {
100136
String sourceFieldName = mapping.getSourceFieldName(constructorParameter.getSimpleName().toString().toLowerCase());
101137
ExecutableElement getter = argumentGetters.get(sourceFieldName.toLowerCase());
102-
if (getter == null) {
103-
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "Failed to find getter at source for target field", constructorParameter);
104-
return null;
105-
}
138+
System.out.println("constructorParameter = " + constructorParameter);
139+
System.out.println("getter = " + getter);
106140
if (!constructorParameter.asType().equals(getter.getReturnType())) {
107141
//getter and constructor parameter have different types
108142
MappingInfo depMapping = findMapping(getter.getReturnType(), constructorParameter.asType());
109143
if (depMapping == null) {
110-
depMapping = new MappingInfo(getter.getReturnType(), constructorParameter.asType());
111-
autoMappings.add(depMapping);
144+
processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, "ERROR 1. Failed to find generated mapping info", constructorParameter);
145+
return null;
112146
}
113147
statementBuilder
114148
.append(separator)
@@ -143,6 +177,7 @@ private MethodSpec generateMappingMethod(MappingInfo mapping) {
143177
}
144178

145179
private ExecutableElement getConstructorElement(String className) {
180+
System.out.println("finding constructor for = " + className);
146181
TypeElement element = processingEnv.getElementUtils().getTypeElement(className);
147182
List<? extends Element> enclosedElements = element.getEnclosedElements();
148183
List<ExecutableElement> constructors = ElementFilter.constructorsIn(enclosedElements);

processor/src/main/java/com/devindi/mapper/MappingInfo.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,4 +77,28 @@ public String getSourceFieldName(String defaultName) {
7777
}
7878
return defaultName;
7979
}
80+
81+
@Override
82+
public String toString() {
83+
return targetType + " " + mappingName + "(" + sourceType + " " + sourceName + ")";
84+
}
85+
86+
@Override
87+
public boolean equals(Object o) {
88+
if (this == o) return true;
89+
if (o == null || getClass() != o.getClass()) return false;
90+
91+
MappingInfo that = (MappingInfo) o;
92+
93+
if (!sourceType.equals(that.sourceType)) return false;
94+
return targetType.equals(that.targetType);
95+
96+
}
97+
98+
@Override
99+
public int hashCode() {
100+
int result = sourceType.hashCode();
101+
result = 31 * result + targetType.hashCode();
102+
return result;
103+
}
80104
}

sample/sample.iml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,20 @@
7676
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
7777
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
7878
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
79+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
7980
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
8081
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
8182
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
8283
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
84+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
8385
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
86+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
8487
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
8588
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
89+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
8690
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
91+
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
8792
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
88-
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
89-
<excludeFolder url="file://$MODULE_DIR$/build/test-results" />
9093
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
9194
</content>
9295
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />

sample/src/main/java/com/example/nested/Driver.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ public class Driver {
55
private final String name;
66
private final int age;
77
private final DriverLicense license;
8+
private final Photo photo;
89

9-
public Driver(int age, String name, DriverLicense license) {
10+
public Driver(int age, String name, DriverLicense license, Photo photo) {
1011
this.name = name;
1112
this.age = age;
1213
this.license = license;
14+
this.photo = photo;
1315
}
1416

1517
public String getName() {
@@ -23,4 +25,8 @@ public int getAge() {
2325
public DriverLicense getLicense() {
2426
return license;
2527
}
28+
29+
public Photo getPhoto() {
30+
return photo;
31+
}
2632
}

sample/src/main/java/com/example/nested/DriverDto.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ public class DriverDto {
55
private String name;
66
private int age;
77
private LicenseDto licenseDto;
8+
private PhotoDto photo;
89

9-
public DriverDto(String name, int age, LicenseDto licenseDto) {
10+
public DriverDto(String name, int age, LicenseDto licenseDto, PhotoDto photo) {
1011
this.name = name;
1112
this.age = age;
1213
this.licenseDto = licenseDto;
14+
this.photo = photo;
1315
}
1416

1517
public String getName() {
@@ -32,6 +34,10 @@ public LicenseDto getLicenseDto() {
3234
return licenseDto;
3335
}
3436

37+
public PhotoDto getPhoto() {
38+
return photo;
39+
}
40+
3541
public void setLicenseDto(LicenseDto licenseDto) {
3642
this.licenseDto = licenseDto;
3743
}

sample/src/main/java/com/example/nested/DriverLicense.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,21 @@
44

55
public class DriverLicense {
66
private final String id;
7-
private final String photoUrl;
7+
private final Photo photo;
88
private final Date validUntil;
99

10-
public DriverLicense(String id, String photoUrl, Date validUntil) {
10+
public DriverLicense(String id, Photo photo, Date validUntil) {
1111
this.id = id;
12-
this.photoUrl = photoUrl;
12+
this.photo = photo;
1313
this.validUntil = validUntil;
1414
}
1515

1616
public String getId() {
1717
return id;
1818
}
1919

20-
public String getPhotoUrl() {
21-
return photoUrl;
20+
public Photo getPhoto() {
21+
return photo;
2222
}
2323

2424
public Date getValidUntil() {

sample/src/main/java/com/example/nested/LicenseDto.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,21 +5,21 @@
55
public class LicenseDto {
66

77
private String id;
8-
private String photoUrl;
8+
private PhotoDto photoDto;
99
private Date validUntil;
1010

11-
public LicenseDto(String id, String photoUrl, Date validUntil) {
11+
public LicenseDto(String id, PhotoDto photo, Date validUntil) {
1212
this.id = id;
13-
this.photoUrl = photoUrl;
13+
this.photoDto = photo;
1414
this.validUntil = validUntil;
1515
}
1616

1717
public String getId() {
1818
return id;
1919
}
2020

21-
public String getPhotoUrl() {
22-
return photoUrl;
21+
public PhotoDto getPhoto() {
22+
return photoDto;
2323
}
2424

2525
public Date getValidUntil() {
@@ -30,7 +30,7 @@ public Date getValidUntil() {
3030
public String toString() {
3131
return "LicenseDto{" +
3232
"id='" + id + '\'' +
33-
", photoUrl='" + photoUrl + '\'' +
33+
", photo='" + photoDto + '\'' +
3434
", validUntil=" + validUntil +
3535
'}';
3636
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.example.nested;
2+
3+
import java.util.Date;
4+
5+
public class Photo {
6+
7+
private String url;
8+
private Date createdAt;
9+
10+
public Photo(String url, Date createdAt) {
11+
this.url = url;
12+
this.createdAt = createdAt;
13+
}
14+
15+
public String getUrl() {
16+
return url;
17+
}
18+
19+
public Date getCreatedAt() {
20+
return createdAt;
21+
}
22+
}

0 commit comments

Comments
 (0)