Skip to content

Commit

Permalink
Merge pull request #521 from tea-dragon/master
Browse files Browse the repository at this point in the history
keep bundle annotations and prevent simple cycles
  • Loading branch information
cowtowncoder committed Aug 25, 2014
2 parents d1f58c6 + 21df384 commit e585a8f
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -908,13 +908,13 @@ private void _addAnnotationsIfNotPresent(AnnotationMap result, Annotation[] anns
if (anns != null) {
List<Annotation[]> bundles = null;
for (Annotation ann : anns) { // first: direct annotations
if (_isAnnotationBundle(ann)) {
// note: we will NOT filter out non-Jackson anns any more
boolean wasNotPresent = result.addIfNotPresent(ann);
if (wasNotPresent && _isAnnotationBundle(ann)) {
if (bundles == null) {
bundles = new LinkedList<Annotation[]>();
}
bundles.add(ann.annotationType().getDeclaredAnnotations());
} else { // note: we will NOT filter out non-Jackson anns any more
result.addIfNotPresent(ann);
}
}
if (bundles != null) { // and secondarily handle bundles, if any found: precedence important
Expand All @@ -930,13 +930,13 @@ private void _addAnnotationsIfNotPresent(AnnotatedMember target, Annotation[] an
if (anns != null) {
List<Annotation[]> bundles = null;
for (Annotation ann : anns) { // first: direct annotations
if (_isAnnotationBundle(ann)) {
// note: we will NOT filter out non-Jackson anns any more
boolean wasNotPresent = target.addIfNotPresent(ann);
if (wasNotPresent && _isAnnotationBundle(ann)) {
if (bundles == null) {
bundles = new LinkedList<Annotation[]>();
}
bundles.add(ann.annotationType().getDeclaredAnnotations());
} else { // note: we will NOT filter out non-Jackson anns any more
target.addIfNotPresent(ann);
}
}
if (bundles != null) { // and secondarily handle bundles, if any found: precedence important
Expand All @@ -952,13 +952,13 @@ private void _addOrOverrideAnnotations(AnnotatedMember target, Annotation[] anns
if (anns != null) {
List<Annotation[]> bundles = null;
for (Annotation ann : anns) { // first: direct annotations
if (_isAnnotationBundle(ann)) {
// note: we will NOT filter out non-Jackson anns any more
boolean wasModified = target.addOrOverride(ann);
if (wasModified && _isAnnotationBundle(ann)) {
if (bundles == null) {
bundles = new LinkedList<Annotation[]>();
}
bundles.add(ann.annotationType().getDeclaredAnnotations());
} else { // note: no filtering by jackson-annotations
target.addOrOverride(ann);
}
}
if (bundles != null) { // and then bundles, if any: important for precedence
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,17 @@ protected AnnotationMap getAllAnnotations() {
* annotation masking or overriding an annotation 'real' constructor
* has.
*/
public final void addOrOverride(Annotation a) {
_annotations.add(a);
public final boolean addOrOverride(Annotation a) {
return _annotations.add(a);
}

/**
* Method called to augment annotations, by adding specified
* annotation if and only if it is not yet present in the
* annotation map we have.
*/
public final void addIfNotPresent(Annotation a) {
_annotations.addIfNotPresent(a);
public final boolean addIfNotPresent(Annotation a) {
return _annotations.addIfNotPresent(a);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,18 +71,20 @@ public int size() {
* Method called to add specified annotation in the Map, but
* only if it didn't yet exist.
*/
public void addIfNotPresent(Annotation ann)
public boolean addIfNotPresent(Annotation ann)
{
if (_annotations == null || !_annotations.containsKey(ann.annotationType())) {
_add(ann);
return true;
}
return false;
}

/**
* Method called to add specified annotation in the Map.
*/
public void add(Annotation ann) {
_add(ann);
public boolean add(Annotation ann) {
return _add(ann);
}

@Override
Expand All @@ -99,11 +101,12 @@ public String toString() {
/**********************************************************
*/

protected final void _add(Annotation ann) {
protected final boolean _add(Annotation ann) {
if (_annotations == null) {
_annotations = new HashMap<Class<? extends Annotation>,Annotation>();
}
_annotations.put(ann.annotationType(), ann);
Annotation previous = _annotations.put(ann.annotationType(), ann);
return (previous != null) && previous.equals(ann);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyName;

/* Tests mostly for [JACKSON-754]: ability to create "annotation bundles"
*/
Expand Down Expand Up @@ -51,15 +55,65 @@ public class NoAutoDetect {
public class Bean92 {
@Bundle92
protected String id = "abc";
}
}

@HolderB
@JacksonAnnotationsInside
@Retention(RetentionPolicy.RUNTIME)
static @interface HolderA {}

@HolderA
@JacksonAnnotationsInside
@Retention(RetentionPolicy.RUNTIME)
static @interface HolderB {}

static class RecursiveHolder {
@HolderA public int unimportant = 42;
}

@JsonProperty
@JacksonAnnotationsInside
@Retention(RetentionPolicy.RUNTIME)
static @interface InformativeHolder {
// doesn't really contribute to the test, but would be impossible without this feature
boolean important() default true;
}

static class InformingHolder {
@InformativeHolder public int unimportant = 42;
}

static class BundleAnnotationIntrospector extends JacksonAnnotationIntrospector {
@Override
public PropertyName findNameForSerialization(Annotated a)
{
InformativeHolder informativeHolder = a.getAnnotation(InformativeHolder.class);
if ((informativeHolder != null) && informativeHolder.important()) {
return new PropertyName("important");
}
return super.findNameForSerialization(a);
}
}

/*
/**********************************************************
/* Test methods
/**********************************************************
*/

private final ObjectMapper MAPPER = new ObjectMapper();


public void testKeepAnnotationBundle() throws Exception
{
MAPPER.setAnnotationIntrospector(new BundleAnnotationIntrospector());
assertEquals("{\"important\":42}", MAPPER.writeValueAsString(new InformingHolder()));
}

public void testRecursiveBundles() throws Exception
{
assertEquals("{\"unimportant\":42}", MAPPER.writeValueAsString(new RecursiveHolder()));
}

public void testBundledIgnore() throws Exception
{
assertEquals("{\"foobar\":13}", MAPPER.writeValueAsString(new Bean()));
Expand Down

0 comments on commit e585a8f

Please sign in to comment.