Skip to content

Commit 4333eb6

Browse files
committed
Merge pull request #868 from christophercurrie/merge-annotations-fix
Annotations are lost in the case of duplicate methods
2 parents c52fb0b + 6cf2bb5 commit 4333eb6

File tree

2 files changed

+81
-9
lines changed

2 files changed

+81
-9
lines changed

src/main/java/com/fasterxml/jackson/databind/introspect/POJOPropertyBuilder.java

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -683,28 +683,28 @@ public void mergeAnnotations(boolean forSerialization)
683683
if (forSerialization) {
684684
if (_getters != null) {
685685
AnnotationMap ann = _mergeAnnotations(0, _getters, _fields, _ctorParameters, _setters);
686-
_getters = _getters.withValue(_getters.value.withAnnotations(ann));
686+
_getters = _applyAnnotations(_getters, ann);
687687
} else if (_fields != null) {
688688
AnnotationMap ann = _mergeAnnotations(0, _fields, _ctorParameters, _setters);
689-
_fields = _fields.withValue(_fields.value.withAnnotations(ann));
689+
_fields = _applyAnnotations(_fields, ann);
690690
}
691691
} else { // for deserialization
692692
if (_ctorParameters != null) {
693693
AnnotationMap ann = _mergeAnnotations(0, _ctorParameters, _setters, _fields, _getters);
694-
_ctorParameters = _ctorParameters.withValue(_ctorParameters.value.withAnnotations(ann));
694+
_ctorParameters = _applyAnnotations(_ctorParameters, ann);
695695
} else if (_setters != null) {
696696
AnnotationMap ann = _mergeAnnotations(0, _setters, _fields, _getters);
697-
_setters = _setters.withValue(_setters.value.withAnnotations(ann));
697+
_setters = _applyAnnotations(_setters, ann);
698698
} else if (_fields != null) {
699699
AnnotationMap ann = _mergeAnnotations(0, _fields, _getters);
700-
_fields = _fields.withValue(_fields.value.withAnnotations(ann));
700+
_fields = _applyAnnotations(_fields, ann);
701701
}
702702
}
703703
}
704704

705705
private AnnotationMap _mergeAnnotations(int index, Linked<? extends AnnotatedMember>... nodes)
706706
{
707-
AnnotationMap ann = nodes[index].value.getAllAnnotations();
707+
AnnotationMap ann = _getAllAnnotations(nodes[index]);
708708
++index;
709709
for (; index < nodes.length; ++index) {
710710
if (nodes[index] != null) {
@@ -713,7 +713,23 @@ private AnnotationMap _mergeAnnotations(int index, Linked<? extends AnnotatedMem
713713
}
714714
return ann;
715715
}
716-
716+
717+
private <T extends AnnotatedMember> AnnotationMap _getAllAnnotations(Linked<T> node) {
718+
AnnotationMap ann = node.value.getAllAnnotations();
719+
if (node.next != null) {
720+
ann = AnnotationMap.merge(ann, _getAllAnnotations(node.next));
721+
}
722+
return ann;
723+
}
724+
725+
private <T extends AnnotatedMember> Linked<T> _applyAnnotations(Linked<T> node, AnnotationMap ann) {
726+
T value = (T) node.value.withAnnotations(ann);
727+
if (node.next != null) {
728+
node = node.withNext(_applyAnnotations(node.next, ann));
729+
}
730+
return node.withValue(value);
731+
}
732+
717733
private <T> Linked<T> _removeIgnored(Linked<T> node)
718734
{
719735
if (node == null) {
@@ -1056,7 +1072,7 @@ public void remove() {
10561072
* Node used for creating simple linked lists to efficiently store small sets
10571073
* of things.
10581074
*/
1059-
private final static class Linked<T>
1075+
protected final static class Linked<T>
10601076
{
10611077
public final T value;
10621078
public final Linked<T> next;

src/test/java/com/fasterxml/jackson/databind/introspect/TestPOJOPropertiesCollector.java

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package com.fasterxml.jackson.databind.introspect;
22

3+
import java.lang.annotation.ElementType;
4+
import java.lang.annotation.Retention;
5+
import java.lang.annotation.RetentionPolicy;
6+
import java.lang.annotation.Target;
37
import java.math.BigDecimal;
48
import java.util.*;
59

@@ -198,7 +202,35 @@ static class PropDescBean
198202
@JsonProperty(required=true, index=B_INDEX, defaultValue="13")
199203
public int getB() { return b; }
200204
}
201-
205+
206+
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
207+
@Retention(RetentionPolicy.RUNTIME)
208+
@JacksonAnnotation
209+
@interface A {}
210+
211+
@Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
212+
@Retention(RetentionPolicy.RUNTIME)
213+
@JacksonAnnotation
214+
@interface B {}
215+
216+
static class DuplicateGetterBean
217+
{
218+
@A
219+
public boolean isBloop() { return true; }
220+
221+
@B
222+
public boolean getBloop() { return true; }
223+
}
224+
225+
static class DuplicateGetterCreatorBean
226+
{
227+
public DuplicateGetterCreatorBean(@JsonProperty("bloop") @A boolean bloop) {}
228+
229+
public boolean isBloop() { return true; }
230+
231+
public boolean getBloop() { return true; }
232+
}
233+
202234
/*
203235
/**********************************************************
204236
/* Unit tests
@@ -433,6 +465,30 @@ public void testPropertyIndex() throws Exception
433465
_verifyProperty(beanDesc, false, true, "13");
434466
}
435467

468+
public void testDuplicateGetters() throws Exception
469+
{
470+
POJOPropertiesCollector coll = collector(MAPPER, DuplicateGetterBean.class, true);
471+
List<BeanPropertyDefinition> props = coll.getProperties();
472+
assertEquals(1, props.size());
473+
BeanPropertyDefinition prop = props.get(0);
474+
assertEquals("bloop", prop.getName());
475+
assertTrue(prop.getGetter().hasAnnotation(A.class));
476+
assertTrue(prop.getGetter().hasAnnotation(B.class));
477+
}
478+
479+
public void testDuplicateGettersCreator() throws Exception
480+
{
481+
POJOPropertiesCollector coll = collector(MAPPER, DuplicateGetterCreatorBean.class, true);
482+
List<BeanPropertyDefinition> props = coll.getProperties();
483+
assertEquals(1, props.size());
484+
POJOPropertyBuilder prop = (POJOPropertyBuilder) props.get(0);
485+
assertEquals("bloop", prop.getName());
486+
// Can't call getGetter or the duplicate will be removed
487+
assertTrue(prop._getters.value.hasAnnotation(A.class));
488+
assertNotNull(prop._getters.next);
489+
assertTrue(prop._getters.next.value.hasAnnotation(A.class));
490+
}
491+
436492
private void _verifyProperty(BeanDescription beanDesc,
437493
boolean verifyDesc, boolean verifyIndex, String expDefaultValue)
438494
{

0 commit comments

Comments
 (0)