Skip to content

Commit e0cb5b2

Browse files
authored
Merge pull request #30 from avaje/SentryMan-handle-annotated-types
Fix for annotated fields - e.g. @SiZe @NotNull etc
2 parents 9e93e3a + 6510ef4 commit e0cb5b2

File tree

6 files changed

+108
-24
lines changed

6 files changed

+108
-24
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ build/
33
.idea/
44
*.iml
55
.gradle
6+
*.prefs
7+
jsonb-generator/.classpath
8+
jsonb-generator/.project

blackbox-test/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020

2121
<dependencies>
2222

23+
<!-- for testing fields with third party annotations -->
24+
<dependency>
25+
<groupId>javax.validation</groupId>
26+
<artifactId>validation-api</artifactId>
27+
<version>2.0.1.Final</version>
28+
</dependency>
29+
2330
<dependency>
2431
<groupId>io.avaje</groupId>
2532
<artifactId>avaje-jsonb</artifactId>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package org.example.customer;
2+
3+
import io.avaje.jsonb.Json;
4+
5+
import javax.validation.constraints.NotNull;
6+
import javax.validation.constraints.Size;
7+
8+
@Json
9+
public class WithAnnotations {
10+
11+
@Size(max = 50)
12+
final String one;
13+
14+
@NotNull @Size(min = 5, max = 10)
15+
final String two;
16+
17+
public WithAnnotations(String one, String two) {
18+
this.one = one;
19+
this.two = two;
20+
}
21+
22+
public String one() {
23+
return one;
24+
}
25+
26+
public String two() {
27+
return two;
28+
}
29+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.example.customer;
2+
3+
import io.avaje.jsonb.Jsonb;
4+
import org.junit.jupiter.api.Test;
5+
6+
import static org.assertj.core.api.Assertions.assertThat;
7+
8+
class WithAnnotationsTest {
9+
10+
Jsonb jsonb = Jsonb.builder().build();
11+
12+
@Test
13+
void toJsonFromJson() {
14+
var bean = new WithAnnotations("foo","bar");
15+
String asJson = jsonb.toJson(bean);
16+
assertThat(asJson).isEqualTo("{\"one\":\"foo\",\"two\":\"bar\"}");
17+
18+
WithAnnotations fromJson = jsonb.type(WithAnnotations.class).fromJson(asJson);
19+
20+
assertThat(fromJson.one()).isEqualTo("foo");
21+
assertThat(fromJson.two()).isEqualTo("bar");
22+
}
23+
24+
}

jsonb-generator/src/main/java/io/avaje/jsonb/generator/FieldReader.java

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package io.avaje.jsonb.generator;
22

3-
import javax.lang.model.element.Element;
4-
import javax.lang.model.element.Modifier;
53
import java.util.LinkedHashMap;
64
import java.util.Map;
75
import java.util.Set;
86

7+
import javax.lang.model.element.Element;
8+
import javax.lang.model.element.Modifier;
9+
910
class FieldReader {
1011

1112
private final Map<String, TypeSubTypeMeta> subTypes = new LinkedHashMap<>();
12-
private final Element element;
1313
private final boolean publicField;
1414
private final String rawType;
1515
private final GenericType genericType;
@@ -30,14 +30,13 @@ class FieldReader {
3030
private boolean constructorParam;
3131

3232
FieldReader(Element element, NamingConvention namingConvention, TypeSubTypeMeta subType) {
33-
this.element = element;
3433
addSubType(subType);
3534
this.fieldName = element.getSimpleName().toString();
3635
this.propertyName = PropertyReader.name(namingConvention, fieldName, element);
37-
this.rawType = element.asType().toString();
3836
this.publicField = element.getModifiers().contains(Modifier.PUBLIC);
37+
this.rawType = trimAnnotations(element.asType().toString());
3938

40-
PropertyIgnoreReader ignoreReader = new PropertyIgnoreReader(element);
39+
final PropertyIgnoreReader ignoreReader = new PropertyIgnoreReader(element);
4140
this.unmapped = ignoreReader.unmapped();
4241
this.raw = ignoreReader.raw();
4342
this.serialize = ignoreReader.serialize();
@@ -56,15 +55,23 @@ class FieldReader {
5655
primitive = false;
5756
} else {
5857
genericType = GenericType.parse(rawType);
59-
String shortType = genericType.shortType();
58+
final String shortType = genericType.shortType();
6059
primitive = PrimitiveUtil.isPrimitive(shortType);
6160
defaultValue = !primitive ? "null" : PrimitiveUtil.defaultValue(shortType);
62-
String typeWrapped = PrimitiveUtil.wrap(shortType);
61+
final String typeWrapped = PrimitiveUtil.wrap(shortType);
6362
adapterShortType = "JsonAdapter<" + typeWrapped + ">";
6463
adapterFieldName = (primitive ? "p" : "") + Util.initLower(genericType.shortName()) + "JsonAdapter";
6564
}
6665
}
6766

67+
static String trimAnnotations(String type) {
68+
int pos = type.indexOf("@");
69+
if (pos == -1) {
70+
return type;
71+
}
72+
return type.substring(0, pos) + type.substring(type.lastIndexOf(' ') + 1);
73+
}
74+
6875
void position(int pos) {
6976
position = pos;
7077
}
@@ -118,10 +125,10 @@ void addImports(Set<String> importTypes) {
118125

119126
void cascadeTypes(Set<String> types) {
120127
if (!raw && !unmapped) {
121-
String topType = genericType.topType();
122-
if (topType.equals("java.util.List") || topType.equals("java.util.Set")) {
128+
final String topType = genericType.topType();
129+
if ("java.util.List".equals(topType) || "java.util.Set".equals(topType)) {
123130
types.add(genericType.firstParamType());
124-
} else if (topType.equals("java.util.Map")) {
131+
} else if ("java.util.Map".equals(topType)) {
125132
types.add(genericType.secondParamType());
126133
} else {
127134
types.add(topType);
@@ -152,16 +159,14 @@ void writeDebug(Append writer) {
152159
}
153160
if (!deserialize) {
154161
writer.append(" ignoreDeserialize");
162+
} else if (constructorParam) {
163+
writer.append(" constructor");
164+
} else if (setter != null) {
165+
writer.append(" setter:%s ", setter);
166+
} else if (publicField) {
167+
writer.append(" publicField");
155168
} else {
156-
if (constructorParam) {
157-
writer.append(" constructor");
158-
} else if (setter != null) {
159-
writer.append(" setter:%s ", setter);
160-
} else if (publicField) {
161-
writer.append(" publicField");
162-
} else {
163-
writer.append(" ERROR?? no constructor, setter and not a public field?");
164-
}
169+
writer.append(" ERROR?? no constructor, setter and not a public field?");
165170
}
166171
if (!subTypes.isEmpty()) {
167172
writer.append(" subTypes %s", subTypes.keySet());
@@ -181,7 +186,7 @@ void writeConstructor(Append writer) {
181186
if (raw) {
182187
writer.append(" this.%s = jsonb.rawAdapter();", adapterFieldName).eol();
183188
} else {
184-
String asType = genericType.asTypeDeclaration();
189+
final String asType = genericType.asTypeDeclaration();
185190
writer.append(" this.%s = jsonb.adapter(%s);", adapterFieldName, asType).eol();
186191
}
187192
}
@@ -227,11 +232,11 @@ void writeFromJsonVariables(Append writer) {
227232
}
228233

229234
private String pad(String value) {
230-
int pad = 10 - value.length();
235+
final int pad = 10 - value.length();
231236
if (pad < 1) {
232237
return value;
233238
}
234-
StringBuilder sb = new StringBuilder(10).append(value);
239+
final StringBuilder sb = new StringBuilder(10).append(value);
235240
for (int i = 0; i < pad; i++) {
236241
sb.append(" ");
237242
}
@@ -285,7 +290,7 @@ void writeViewBuilder(Append writer, String shortName) {
285290
if (getter == null) {
286291
writer.append(" builder.add(\"%s\", %s, builder.field(%s.class, \"%s\"));", fieldName, adapterFieldName, shortName, fieldName).eol();
287292
} else {
288-
String topType = genericType.topType();
293+
final String topType = genericType.topType();
289294
writer.append(" builder.add(\"%s\", %s, builder.method(%s.class, \"%s\", %s.class));", fieldName, adapterFieldName, shortName, getter.getName(), topType).eol();
290295
}
291296
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.avaje.jsonb.generator;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import static org.junit.jupiter.api.Assertions.*;
6+
7+
class FieldReaderTest {
8+
9+
@Test
10+
void trimAnnotations() {
11+
assertEquals("java.lang.String", FieldReader.trimAnnotations("java.lang.String"));
12+
assertEquals("java.lang.String", FieldReader.trimAnnotations("java.lang.@javax.validation.constraints.Email String"));
13+
assertEquals("java.lang.String", FieldReader.trimAnnotations("java.lang.@javax.validation.constraints.NotNull,@javax.validation.constraints.Size(min=2, max=150) String"));
14+
assertEquals("java.lang.String", FieldReader.trimAnnotations("java.lang.@javax.validation.constraints.Email,@javax.validation.constraints.Size(max=100) String"));
15+
}
16+
}

0 commit comments

Comments
 (0)