Skip to content
This repository was archived by the owner on Oct 16, 2024. It is now read-only.

Commit 3a38f58

Browse files
authored
Add support for JsonAlias annotation (#462)
Copy JsonAlias annotations to the generated getter/setter methods.
2 parents 1ea0a69 + f04970a commit 3a38f58

File tree

4 files changed

+87
-12
lines changed

4 files changed

+87
-12
lines changed

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ guava=com.google.guava:guava:16.0
44
guavaTestlib=com.google.guava:guava-testlib:17.0
55
gwtUser=com.google.gwt:gwt-user:2.8.0
66
hamcrest=org.hamcrest:hamcrest-all:1.3
7-
jacksonVersion=2.6.1
7+
jacksonVersion=2.9.3
88
javassist=org.javassist:javassist:3.19.0-GA
99
jsr305=com.google.code.findbugs:jsr305:3.0.0
1010
junit=junit:junit:4.12

src/main/java/org/inferred/freebuilder/processor/JacksonSupport.java

+16-11
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ private enum GenerateAnnotation {
3131
QualifiedName.of("com.fasterxml.jackson.annotation", "JsonProperty");
3232
private static final String JACKSON_XML_ANNOTATION_PACKAGE =
3333
"com.fasterxml.jackson.dataformat.xml.annotation";
34+
private static final String JSON_ALIAS =
35+
"com.fasterxml.jackson.annotation.JsonAlias";
3436
private static final QualifiedName JSON_ANY_GETTER =
35-
QualifiedName.of("com.fasterxml.jackson.annotation", "JsonAnyGetter");
37+
QualifiedName.of("com.fasterxml.jackson.annotation", "JsonAnyGetter");
3638
private static final QualifiedName JSON_ANY_SETTER =
37-
QualifiedName.of("com.fasterxml.jackson.annotation", "JsonAnySetter");
39+
QualifiedName.of("com.fasterxml.jackson.annotation", "JsonAnySetter");
3840
/** Annotations which disable automatic generation of JsonProperty annotations. */
3941
private static final Set<QualifiedName> DISABLE_PROPERTY_ANNOTATIONS = ImmutableSet.of(
4042
QualifiedName.of("com.fasterxml.jackson.annotation", "JsonIgnore"),
@@ -55,15 +57,15 @@ private JacksonSupport(Elements elements) {
5557
public void addJacksonAnnotations(
5658
Property.Builder resultBuilder,
5759
ExecutableElement getterMethod) {
58-
Optional<AnnotationMirror> jsonPropertyAnnotation = findAnnotationMirror(getterMethod,
59-
JSON_PROPERTY);
60+
Optional<AnnotationMirror> jsonPropertyAnnotation =
61+
findAnnotationMirror(getterMethod, JSON_PROPERTY);
6062
if (jsonPropertyAnnotation.isPresent()) {
6163
resultBuilder.addAccessorAnnotations(Excerpts.add("%s%n", jsonPropertyAnnotation.get()));
6264
} else {
6365
switch (generateDefaultAnnotations(getterMethod)) {
6466
case DEFAULT:
65-
resultBuilder.addAccessorAnnotations(Excerpts.add(
66-
"@%s(\"%s\")%n", JSON_PROPERTY, resultBuilder.getName()));
67+
resultBuilder.addAccessorAnnotations(
68+
Excerpts.add("@%s(\"%s\")%n", JSON_PROPERTY, resultBuilder.getName()));
6769
break;
6870
case JSON_ANY:
6971
resultBuilder.addPutAnnotations(Excerpts.add("@%s%n", JSON_ANY_SETTER));
@@ -78,15 +80,18 @@ public void addJacksonAnnotations(
7880
getterMethod
7981
.getAnnotationMirrors()
8082
.stream()
81-
.filter(this::isXmlAnnotation)
83+
.filter(this::shouldCopyAnnotation)
8284
.forEach(annotation -> {
83-
resultBuilder.addAccessorAnnotations(code -> code.addLine("%s", annotation));
85+
resultBuilder.addAccessorAnnotations(Excerpts.add("%s%n", annotation));
8486
});
8587
}
8688

87-
private boolean isXmlAnnotation(AnnotationMirror mirror) {
88-
Name pkg = elements.getPackageOf(mirror.getAnnotationType().asElement()).getQualifiedName();
89-
return pkg.contentEquals(JACKSON_XML_ANNOTATION_PACKAGE);
89+
private boolean shouldCopyAnnotation(AnnotationMirror mirror) {
90+
TypeElement annotationTypeElement = (TypeElement) mirror.getAnnotationType().asElement();
91+
Name qualifiedName = annotationTypeElement.getQualifiedName();
92+
Name pkg = elements.getPackageOf(annotationTypeElement).getQualifiedName();
93+
return pkg.contentEquals(JACKSON_XML_ANNOTATION_PACKAGE)
94+
|| qualifiedName.contentEquals(JSON_ALIAS);
9095
}
9196

9297
private static GenerateAnnotation generateDefaultAnnotations(ExecutableElement getterMethod) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package org.inferred.freebuilder.processor;
2+
3+
import com.fasterxml.jackson.annotation.JsonAlias;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
6+
7+
import org.inferred.freebuilder.FreeBuilder;
8+
import org.inferred.freebuilder.processor.source.SourceBuilder;
9+
import org.inferred.freebuilder.processor.source.feature.FeatureSet;
10+
import org.inferred.freebuilder.processor.source.feature.StaticFeatureSet;
11+
import org.inferred.freebuilder.processor.source.testing.BehaviorTester;
12+
import org.inferred.freebuilder.processor.source.testing.ParameterizedBehaviorTestFactory.Shared;
13+
import org.inferred.freebuilder.processor.source.testing.TestBuilder;
14+
import org.junit.Test;
15+
16+
public class JacksonIntegrationTest {
17+
18+
@Shared public BehaviorTester behaviorTester;
19+
20+
@Test
21+
public void testJsonAliasSupport() {
22+
FeatureSet featureSet = new StaticFeatureSet();
23+
BehaviorTester.create(featureSet)
24+
.with(new Processor(featureSet))
25+
.with(SourceBuilder.forTesting()
26+
.addLine("package com.example;")
27+
.addLine("@%s", FreeBuilder.class)
28+
.addLine("@%s(builder = DataType.Builder.class)", JsonDeserialize.class)
29+
.addLine("public abstract class DataType {")
30+
.addLine(" @%s({\"a\", \"theagame\"})", JsonAlias.class)
31+
.addLine(" public abstract int propertyA();")
32+
.addLine("")
33+
.addLine(" public static class Builder extends DataType_Builder {}")
34+
.addLine("}"))
35+
.with(testBuilder()
36+
.addLine("DataType expected = new DataType.Builder().propertyA(13).build();")
37+
.addLine("%1$s mapper = new %1$s();", ObjectMapper.class)
38+
.addLine("String canonicalJson = \"{ \\\"propertyA\\\": 13 }\";")
39+
.addLine("DataType canonical = mapper.readValue(canonicalJson, DataType.class);")
40+
.addLine("assertEquals(expected, canonical);")
41+
.addLine("String alternative1Json = \"{ \\\"a\\\": 13 }\";")
42+
.addLine("DataType alternative1 = mapper.readValue(canonicalJson, DataType.class);")
43+
.addLine("assertEquals(expected, alternative1);")
44+
.addLine("String alternative2Json = \"{ \\\"theagame\\\": 13 }\";")
45+
.addLine("DataType alternative2 = mapper.readValue(canonicalJson, DataType.class);")
46+
.addLine("assertEquals(expected, alternative2);")
47+
.build())
48+
.runTest();
49+
}
50+
51+
private static TestBuilder testBuilder() {
52+
return new TestBuilder().addImport("com.example.DataType");
53+
}
54+
}

src/test/java/org/inferred/freebuilder/processor/JacksonSupportTest.java

+16
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import static com.google.common.collect.Iterables.getOnlyElement;
1919
import static com.google.common.truth.Truth.assertThat;
2020

21+
import com.fasterxml.jackson.annotation.JsonAlias;
2122
import com.fasterxml.jackson.annotation.JsonAnyGetter;
2223
import com.fasterxml.jackson.annotation.JsonProperty;
2324
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
@@ -145,6 +146,21 @@ public void jsonAnyGetterAnnotationDisablesImplicitProperty() throws CannotGener
145146
assertThat(property.getAccessorAnnotations()).named("property accessor annotations").isEmpty();
146147
}
147148

149+
@Test
150+
public void jsonAliasAnnotationCopied() throws CannotGenerateCodeException {
151+
GeneratedBuilder builder = (GeneratedBuilder) analyser.analyse(model.newType(
152+
"package com.example;",
153+
"@" + JsonDeserialize.class.getName() + "(builder = DataType.Builder.class)",
154+
"public interface DataType {",
155+
" @" + JsonAlias.class.getName() + "({\"foo\", \"bar\"}) int getFooBar();",
156+
" class Builder extends DataType_Builder {}",
157+
"}"));
158+
159+
Property property = getOnlyElement(builder.getGeneratorsByProperty().keySet());
160+
assertPropertyHasAnnotation(property, JsonProperty.class, "@JsonProperty(\"fooBar\")");
161+
assertPropertyHasAnnotation(property, JsonAlias.class, "@JsonAlias({\"foo\", \"bar\"})");
162+
}
163+
148164
private static void assertPropertyHasAnnotation(
149165
Property property, Class<? extends Annotation> annotationClass, String annotationString) {
150166
Excerpt annotationExcerpt = property.getAccessorAnnotations()

0 commit comments

Comments
 (0)