Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -683,28 +683,28 @@ public void mergeAnnotations(boolean forSerialization)
if (forSerialization) {
if (_getters != null) {
AnnotationMap ann = _mergeAnnotations(0, _getters, _fields, _ctorParameters, _setters);
_getters = _getters.withValue(_getters.value.withAnnotations(ann));
_getters = _applyAnnotations(_getters, ann);
} else if (_fields != null) {
AnnotationMap ann = _mergeAnnotations(0, _fields, _ctorParameters, _setters);
_fields = _fields.withValue(_fields.value.withAnnotations(ann));
_fields = _applyAnnotations(_fields, ann);
}
} else { // for deserialization
if (_ctorParameters != null) {
AnnotationMap ann = _mergeAnnotations(0, _ctorParameters, _setters, _fields, _getters);
_ctorParameters = _ctorParameters.withValue(_ctorParameters.value.withAnnotations(ann));
_ctorParameters = _applyAnnotations(_ctorParameters, ann);
} else if (_setters != null) {
AnnotationMap ann = _mergeAnnotations(0, _setters, _fields, _getters);
_setters = _setters.withValue(_setters.value.withAnnotations(ann));
_setters = _applyAnnotations(_setters, ann);
} else if (_fields != null) {
AnnotationMap ann = _mergeAnnotations(0, _fields, _getters);
_fields = _fields.withValue(_fields.value.withAnnotations(ann));
_fields = _applyAnnotations(_fields, ann);
}
}
}

private AnnotationMap _mergeAnnotations(int index, Linked<? extends AnnotatedMember>... nodes)
{
AnnotationMap ann = nodes[index].value.getAllAnnotations();
AnnotationMap ann = _getAllAnnotations(nodes[index]);
++index;
for (; index < nodes.length; ++index) {
if (nodes[index] != null) {
Expand All @@ -713,7 +713,23 @@ private AnnotationMap _mergeAnnotations(int index, Linked<? extends AnnotatedMem
}
return ann;
}


private <T extends AnnotatedMember> AnnotationMap _getAllAnnotations(Linked<T> node) {
AnnotationMap ann = node.value.getAllAnnotations();
if (node.next != null) {
ann = AnnotationMap.merge(ann, _getAllAnnotations(node.next));
}
return ann;
}

private <T extends AnnotatedMember> Linked<T> _applyAnnotations(Linked<T> node, AnnotationMap ann) {
T value = (T) node.value.withAnnotations(ann);
if (node.next != null) {
node = node.withNext(_applyAnnotations(node.next, ann));
}
return node.withValue(value);
}

private <T> Linked<T> _removeIgnored(Linked<T> node)
{
if (node == null) {
Expand Down Expand Up @@ -1056,7 +1072,7 @@ public void remove() {
* Node used for creating simple linked lists to efficiently store small sets
* of things.
*/
private final static class Linked<T>
protected final static class Linked<T>
{
public final T value;
public final Linked<T> next;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package com.fasterxml.jackson.databind.introspect;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.math.BigDecimal;
import java.util.*;

Expand Down Expand Up @@ -198,7 +202,35 @@ static class PropDescBean
@JsonProperty(required=true, index=B_INDEX, defaultValue="13")
public int getB() { return b; }
}


@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
@interface A {}

@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotation
@interface B {}

static class DuplicateGetterBean
{
@A
public boolean isBloop() { return true; }

@B
public boolean getBloop() { return true; }
}

static class DuplicateGetterCreatorBean
{
public DuplicateGetterCreatorBean(@JsonProperty("bloop") @A boolean bloop) {}

public boolean isBloop() { return true; }

public boolean getBloop() { return true; }
}

/*
/**********************************************************
/* Unit tests
Expand Down Expand Up @@ -433,6 +465,30 @@ public void testPropertyIndex() throws Exception
_verifyProperty(beanDesc, false, true, "13");
}

public void testDuplicateGetters() throws Exception
{
POJOPropertiesCollector coll = collector(MAPPER, DuplicateGetterBean.class, true);
List<BeanPropertyDefinition> props = coll.getProperties();
assertEquals(1, props.size());
BeanPropertyDefinition prop = props.get(0);
assertEquals("bloop", prop.getName());
assertTrue(prop.getGetter().hasAnnotation(A.class));
assertTrue(prop.getGetter().hasAnnotation(B.class));
}

public void testDuplicateGettersCreator() throws Exception
{
POJOPropertiesCollector coll = collector(MAPPER, DuplicateGetterCreatorBean.class, true);
List<BeanPropertyDefinition> props = coll.getProperties();
assertEquals(1, props.size());
POJOPropertyBuilder prop = (POJOPropertyBuilder) props.get(0);
assertEquals("bloop", prop.getName());
// Can't call getGetter or the duplicate will be removed
assertTrue(prop._getters.value.hasAnnotation(A.class));
assertNotNull(prop._getters.next);
assertTrue(prop._getters.next.value.hasAnnotation(A.class));
}

private void _verifyProperty(BeanDescription beanDesc,
boolean verifyDesc, boolean verifyIndex, String expDefaultValue)
{
Expand Down