diff --git a/src/main/java/org/inferred/freebuilder/processor/JacksonSupport.java b/src/main/java/org/inferred/freebuilder/processor/JacksonSupport.java index f3a632ad2..1c65daebf 100644 --- a/src/main/java/org/inferred/freebuilder/processor/JacksonSupport.java +++ b/src/main/java/org/inferred/freebuilder/processor/JacksonSupport.java @@ -3,12 +3,15 @@ import static org.inferred.freebuilder.processor.util.ModelUtils.findAnnotationMirror; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableSet; import org.inferred.freebuilder.processor.Metadata.Property; import org.inferred.freebuilder.processor.util.Excerpt; import org.inferred.freebuilder.processor.util.QualifiedName; import org.inferred.freebuilder.processor.util.SourceBuilder; +import java.util.Set; + import javax.lang.model.element.AnnotationMirror; import javax.lang.model.element.ExecutableElement; import javax.lang.model.element.TypeElement; @@ -19,6 +22,11 @@ class JacksonSupport { "com.fasterxml.jackson.databind.annotation.JsonDeserialize"; private static final QualifiedName JSON_PROPERTY = QualifiedName.of("com.fasterxml.jackson.annotation", "JsonProperty"); + /** Annotations which disable automatic generation of JsonProperty annotations. */ + private static final Set DISABLE_PROPERTY_ANNOTATIONS = ImmutableSet.of( + QualifiedName.of("com.fasterxml.jackson.annotation", "JsonAnyGetter"), + QualifiedName.of("com.fasterxml.jackson.annotation", "JsonUnwrapped"), + QualifiedName.of("com.fasterxml.jackson.annotation", "JsonValue")); public static Optional create(TypeElement userValueType) { if (findAnnotationMirror(userValueType, JSON_DESERIALIZE).isPresent()) { @@ -34,11 +42,23 @@ public void addJacksonAnnotations( Optional annotation = findAnnotationMirror(getterMethod, JSON_PROPERTY); if (annotation.isPresent()) { resultBuilder.addAccessorAnnotations(new AnnotationExcerpt(annotation.get())); - } else { + } else if (generateDefaultAnnotations(getterMethod)) { resultBuilder.addAccessorAnnotations(new JsonPropertyExcerpt(resultBuilder.getName())); } } + private static boolean generateDefaultAnnotations(ExecutableElement getterMethod) { + for (AnnotationMirror annotationMirror : getterMethod.getAnnotationMirrors()) { + TypeElement annotationTypeElement = + (TypeElement) (annotationMirror.getAnnotationType().asElement()); + QualifiedName annotationType = QualifiedName.of(annotationTypeElement); + if (DISABLE_PROPERTY_ANNOTATIONS.contains(annotationType)) { + return false; + } + } + return true; + } + private static class AnnotationExcerpt implements Excerpt { private final AnnotationMirror annotation; diff --git a/src/test/java/org/inferred/freebuilder/processor/JacksonSupportTest.java b/src/test/java/org/inferred/freebuilder/processor/JacksonSupportTest.java index 4d6dcee02..9cb0a9aae 100644 --- a/src/test/java/org/inferred/freebuilder/processor/JacksonSupportTest.java +++ b/src/test/java/org/inferred/freebuilder/processor/JacksonSupportTest.java @@ -18,6 +18,7 @@ import static com.google.common.collect.Iterables.getOnlyElement; import static com.google.common.truth.Truth.assertThat; +import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @@ -35,6 +36,8 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.Map; + import javax.lang.model.element.TypeElement; /** Unit tests for {@link Analyser}. */ @@ -105,6 +108,23 @@ public void jacksonAnnotationAddedWithImplicitName() throws CannotGenerateCodeEx assertPropertyHasJsonPropertyAnnotation(property, "fooBar"); } + @Test + public void jsonAnyGetterAnnotationDisablesImplicitProperty() throws CannotGenerateCodeException { + TypeElement dataType = model.newType( + "package com.example;", + "@" + JsonDeserialize.class.getName() + "(builder = DataType.Builder.class)", + "public interface DataType {", + " @" + JsonAnyGetter.class.getName(), + " " + Map.class.getName() + " getFooBar();", + " class Builder extends DataType_Builder {}", + "}"); + + Metadata metadata = analyser.analyse(dataType); + + Property property = getOnlyElement(metadata.getProperties()); + assertThat(property.getAccessorAnnotations()).named("property accessor annotations").isEmpty(); + } + private static void assertPropertyHasJsonPropertyAnnotation( Property property, String propertyName) { assertThat(property.getAccessorAnnotations()).named("property accessor annotations").hasSize(1);