Skip to content

Commit

Permalink
Fixed #1376
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Nov 22, 2016
1 parent 6155a19 commit 89662b1
Show file tree
Hide file tree
Showing 11 changed files with 171 additions and 108 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ Project: jackson-databind
by passing `MappingConfig`
#1371: Add `MapperFeature.INFER_CREATOR_FROM_CONSTRUCTOR_PROPERTIES` to allow
disabling use of `@CreatorProperties` as explicit `@JsonCreator` equivalent
#1376: Add ability to disable JsonAnySetter/JsonAnyGetter via mixin
(suggested by brentryan@github)
#1399: Add support for `@JsonSetter(merge=OptBoolean.TRUE`) to allow "deep update"
#1406: `ObjectMapper.readTree()` methods do not return `null` on end-of-input
(reported by Fabrizio C)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1189,8 +1189,10 @@ public PropertyName findNameForDeserialization(Annotated a) {
*
* @return True if such annotation is found (and is not disabled),
* false otherwise
*
* @since 2.9
*/
public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
public Boolean hasAnySetter(Annotated a) {
return false;
}

Expand Down Expand Up @@ -1263,6 +1265,14 @@ public JsonCreator.Mode findCreatorBinding(Annotated a) {
return null;
}

/**
* @deprecated Since 2.9 use {@link #hasAnySetter} instead.
*/
@Deprecated // since 2.9
public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
return false;
}

/*
/**********************************************************
/* Overridable methods: may be used as low-level extension
Expand Down
67 changes: 44 additions & 23 deletions src/main/java/com/fasterxml/jackson/databind/BeanDescription.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public abstract class BeanDescription
{
/**
* Bean type information, including raw class and possible
* * generics information
* generics information
*/
protected final JavaType _type;

Expand Down Expand Up @@ -155,42 +155,63 @@ protected BeanDescription(JavaType type) {
/* Basic API for finding property accessors
/**********************************************************
*/


/**
* Method for locating accessor (readable field, or "getter" method)
* that has
* {@link com.fasterxml.jackson.annotation.JsonValue} annotation,
* if any. If multiple ones are found,
* an error is reported by throwing {@link IllegalArgumentException}
*
* @since 2.9
*/
public abstract AnnotatedMember findJsonValueAccessor();

public abstract AnnotatedMember findAnyGetter();

/**
* Method used to locate the method of introspected class that
* implements {@link com.fasterxml.jackson.annotation.JsonAnySetter}. If no such method exists
* null is returned. If more than one are found, an exception
* is thrown.
* Method used to locate a mutator (settable field, or 2-argument set method)
* of introspected class that
* implements {@link com.fasterxml.jackson.annotation.JsonAnySetter}.
* If no such mutator exists null is returned. If more than one are found,
* an exception is thrown.
* Additional checks are also made to see that method signature
* is acceptable: needs to take 2 arguments, first one String or
* Object; second any can be any type.
*
* @since 2.9
*/
public abstract AnnotatedMethod findAnySetter();
public abstract AnnotatedMember findAnySetterAccessor();

public abstract AnnotatedMethod findMethod(String name, Class<?>[] paramTypes);

@Deprecated // since 2.9
public abstract AnnotatedMethod findJsonValueMethod();

/**
* Method used to locate the field of the class that implements
* {@link com.fasterxml.jackson.annotation.JsonAnySetter} If no such method
* exists null is returned. If more than one are found, an exception is thrown.
*
* @since 2.8
* @deprecated Since 2.9: use {@link #findAnySetterAccessor} instead
*/
public abstract AnnotatedMember findAnySetterField();
@Deprecated
public AnnotatedMethod findAnySetter() {
AnnotatedMember m = findAnySetterAccessor();
if (m instanceof AnnotatedMethod) {
return (AnnotatedMethod) m;
}
return null;
}

/**
* Method for locating the getter method that is annotated with
* {@link com.fasterxml.jackson.annotation.JsonValue} annotation,
* if any. If multiple ones are found,
* an error is reported by throwing {@link IllegalArgumentException}
* @deprecated Since 2.9: use {@link #findAnySetterAccessor} instead
*/
public abstract AnnotatedMember findJsonValueAccessor();

@Deprecated // since 2.9
public abstract AnnotatedMethod findJsonValueMethod();
@Deprecated
public AnnotatedMember findAnySetterField() {
AnnotatedMember m = findAnySetterAccessor();
if (m instanceof AnnotatedField) {
return m;
}
return null;
}

public abstract AnnotatedMethod findMethod(String name, Class<?>[] paramTypes);

/*
/**********************************************************
/* Basic API, class configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -455,19 +455,10 @@ protected void addBeanProps(DeserializationContext ctxt,
}

// Also, do we have a fallback "any" setter?
AnnotatedMethod anySetterMethod = beanDesc.findAnySetter();
AnnotatedMember anySetterField = null;
if (anySetterMethod != null) {
builder.setAnySetter(constructAnySetter(ctxt, beanDesc, anySetterMethod));
AnnotatedMember anySetter = beanDesc.findAnySetterAccessor();
if (anySetter != null) {
builder.setAnySetter(constructAnySetter(ctxt, beanDesc, anySetter));
} else {
anySetterField = beanDesc.findAnySetterField();
if (anySetterField != null) {
builder.setAnySetter(constructAnySetter(ctxt, beanDesc, anySetterField));
}
}
// NOTE: we do NOT add @JsonIgnore'd properties into blocked ones if there's any-setter
// Implicit ones via @JsonIgnore and equivalent?
if (anySetterMethod == null && anySetterField == null) {
Collection<String> ignored2 = beanDesc.getIgnoredPropertyNames();
if (ignored2 != null) {
for (String propName : ignored2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -720,6 +720,15 @@ public PropertyName findNameForDeserialization(Annotated a)
return n;
}

@Override
public Boolean hasAnySetter(Annotated a) {
Boolean b = _primary.hasAnySetter(a);
if (b == null) {
b = _secondary.hasAnySetter(a);
}
return b;
}

@Override
public JsonSetter.Value findSetterInfo(Annotated a) {
JsonSetter.Value v2 = _secondary.findSetterInfo(a);
Expand All @@ -728,11 +737,6 @@ public JsonSetter.Value findSetterInfo(Annotated a) {
? v1 : v2.withOverrides(v1);
}

@Override
public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
return _primary.hasAnySetterAnnotation(am) || _secondary.hasAnySetterAnnotation(am);
}

@Override
@Deprecated // since 2.9
public boolean hasCreatorAnnotation(Annotated a) {
Expand All @@ -755,6 +759,12 @@ public JsonCreator.Mode findCreatorAnnotation(MapperConfig<?> config, Annotated
return (mode == null) ? _secondary.findCreatorAnnotation(config, a) : mode;
}

@Override
@Deprecated // since 2.9
public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
return _primary.hasAnySetterAnnotation(am) || _secondary.hasAnySetterAnnotation(am);
}

protected boolean _isExplicitClassOrOb(Object maybeCls, Class<?> implicit) {
if (maybeCls instanceof Class<?>) {
Class<?> cls = (Class<?>) maybeCls;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -293,25 +293,39 @@ public AnnotatedConstructor findDefaultConstructor() {
}

@Override
public AnnotatedMethod findAnySetter() throws IllegalArgumentException
public AnnotatedMember findAnySetterAccessor() throws IllegalArgumentException
{
AnnotatedMethod anySetter = (_propCollector == null) ? null
: _propCollector.getAnySetterMethod();
if (anySetter != null) {
/* Also, let's be somewhat strict on how field name is to be
* passed; String, Object make sense, others not
* so much.
*/
/* !!! 18-May-2009, tatu: how about enums? Can add support if
* requested; easy enough for devs to add support within
* method.
*/
Class<?> type = anySetter.getRawParameterType(0);
if (type != String.class && type != Object.class) {
throw new IllegalArgumentException("Invalid 'any-setter' annotation on method "+anySetter.getName()+"(): first argument not of type String or Object, but "+type.getName());
if (_propCollector != null) {
AnnotatedMethod anyMethod = _propCollector.getAnySetterMethod();
if (anyMethod != null) {
// Also, let's be somewhat strict on how field name is to be
// passed; String, Object make sense, others not so much.

/* !!! 18-May-2009, tatu: how about enums? Can add support if
* requested; easy enough for devs to add support within method.
*/
Class<?> type = anyMethod.getRawParameterType(0);
if ((type != String.class) && (type != Object.class)) {
throw new IllegalArgumentException(String.format(
"Invalid 'any-setter' annotation on method '%s()': first argument not of type String or Object, but %s",
anyMethod.getName(), type.getName()));
}
return anyMethod;
}
AnnotatedMember anyField = _propCollector.getAnySetterField();
if (anyField != null) {
// For now let's require a Map; in future can add support for other
// types like perhaps Iterable<Map.Entry>?
Class<?> type = anyField.getRawType();
if (!Map.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(String.format(
"Invalid 'any-setter' annotation on field '%s': type is not instance of java.util.Map",
anyField.getName()));
}
return anyField;
}
}
return anySetter;
return null;
}

@Override
Expand Down Expand Up @@ -465,23 +479,6 @@ public AnnotatedMember findAnyGetter() throws IllegalArgumentException
return anyGetter;
}

@Override
public AnnotatedMember findAnySetterField() throws IllegalArgumentException {
AnnotatedMember anySetter = (_propCollector == null) ? null : _propCollector.getAnySetterField();
if (anySetter != null) {
/*
* For now let's require a Map; in future can add support for other
* types like perhaps Iterable<Map.Entry>?
*/
Class<?> type = anySetter.getRawType();
if (!Map.class.isAssignableFrom(type)) {
throw new IllegalArgumentException("Invalid 'any-setter' annotation on field " + anySetter.getName()
+ "(): type is not instance of java.util.Map");
}
}
return anySetter;
}

@Override
public Map<String,AnnotatedMember> findBackReferenceProperties()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -992,8 +992,7 @@ public Boolean hasAnyGetter(Annotated a) {

@Override
@Deprecated // since 2.9
public boolean hasAnyGetterAnnotation(AnnotatedMethod am)
{
public boolean hasAnyGetterAnnotation(AnnotatedMethod am) {
// No dedicated disabling; regular @JsonIgnore used if needs to be ignored (handled separately)
return _hasAnnotation(am, JsonAnyGetter.class);
}
Expand Down Expand Up @@ -1203,20 +1202,25 @@ public PropertyName findNameForDeserialization(Annotated a)
}

@Override
public boolean hasAnySetterAnnotation(AnnotatedMethod am)
{
/* No dedicated disabling; regular @JsonIgnore used
* if needs to be ignored (and if so, is handled prior
* to this method getting called)
*/
return _hasAnnotation(am, JsonAnySetter.class);
public Boolean hasAnySetter(Annotated a) {
JsonAnySetter ann = _findAnnotation(a, JsonAnySetter.class);
if (ann == null) {
return null;
}
return ann.enabled();
}

@Override
public JsonSetter.Value findSetterInfo(Annotated a) {
return JsonSetter.Value.from(_findAnnotation(a, JsonSetter.class));
}

@Override
@Deprecated // since 2.9
public boolean hasAnySetterAnnotation(AnnotatedMethod am) {
return _hasAnnotation(am, JsonAnySetter.class);
}

@Override
@Deprecated // since 2.9
public boolean hasCreatorAnnotation(Annotated a)
Expand Down
Loading

0 comments on commit 89662b1

Please sign in to comment.