Skip to content

Commit

Permalink
Minor improvement wrt #614
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Nov 17, 2014
1 parent 607dfa7 commit a56270a
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 5 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ Project: jackson-databind
(contributed by Aurelien L)
#607: Allow (re)config of `JsonParser.Feature`s via `ObjectReader`
#608: Allow (re)config of `JsonGenerator.Feature`s via `ObjectWriter`
#614: Add a mechanism for using `@JsonCreator.mode` for resolving possible ambiguity between
delegating- and property-based creators
- Allow use of `Shape.ARRAY` for Enums, as an alias to 'use index'
- Start using `JsonGenerator.writeStartArray(int)` to help data formats
that benefit from knowing number of elements in arrays (and would otherwise
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
Expand Down Expand Up @@ -440,7 +441,18 @@ protected void _addDeserializerConstructors(DeserializationContext ctxt, BeanDes
boolean hasExplicitName = (propDef != null) && propDef.isExplicitlyNamed();
Object injectId = intr.findInjectableValueId(ctor.getParameter(0));

if (hasExplicitName || (injectId != null)) {
JsonCreator.Mode mode = intr.findCreatorBinding(ctor);

boolean withProps = (mode == JsonCreator.Mode.PROPERTIES);
if (!withProps && (mode != JsonCreator.Mode.DELEGATING)) {
if (hasExplicitName || (injectId != null)) {
withProps = true;
} else {
// TODO: one more thing -- if property has matching field
// or setter, also consider property-based
}
}
if (withProps) {
CreatorProperty[] properties = new CreatorProperty[1];
PropertyName name = (propDef == null) ? null : propDef.getFullName();
properties[0] = constructCreatorProperty(ctxt, beanDesc, name, 0, ctor.getParameter(0), injectId);
Expand All @@ -449,6 +461,11 @@ protected void _addDeserializerConstructors(DeserializationContext ctxt, BeanDes
/*boolean added = */ _handleSingleArgumentConstructor(ctxt, beanDesc, vchecker, intr, creators,
ctor, isCreator,
vchecker.isCreatorVisible(ctor));
// one more thing: sever link to creator property, to avoid possible later
// problems with "unresolved" constructor property
if (propDef != null) {
((POJOPropertyBuilder) propDef).removeConstructors();
}
}
// regardless, fully handled
continue;
Expand Down Expand Up @@ -590,7 +607,19 @@ protected void _addDeserializerFactoryMethods(DeserializationContext ctxt, BeanD
BeanPropertyDefinition propDef = (propDefs == null) ? null : propDefs[0];
boolean hasExplicitName = (propDef != null) && propDef.isExplicitlyNamed();
final Object injectId = intr.findInjectableValueId(factory.getParameter(0));
if ((injectId == null) && !hasExplicitName) { // not property based

JsonCreator.Mode mode = intr.findCreatorBinding(factory);

boolean withProps = (mode == JsonCreator.Mode.PROPERTIES);
if (!withProps && (mode != JsonCreator.Mode.DELEGATING)) {
if (hasExplicitName || (injectId != null)) {
withProps = true;
} else {
// TODO: one more thing -- if property has matching field
// or setter, also consider property-based
}
}
if (!withProps) { // not property based but delegating
/*boolean added=*/ _handleSingleArgumentFactory(config, beanDesc, vchecker, intr, creators,
factory, isCreator);
// otherwise just ignored
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,15 @@ public void removeNonVisible(boolean force)
}
}

/**
* Mutator that will simply drop any constructor parameters property may have.
*
* @since 2.5
*/
public void removeConstructors() {
_ctorParameters = null;
}

/**
* Method called to trim unnecessary entries, such as implicit
* getter if there is an explict one available. This is important
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@

public class SingleArgCreatorTest extends BaseMapTest
{
// [Issue#430]: single arg BUT named; should not delegate
// [databind#430]: single arg BUT named; should not delegate

static class SingleNamedStringBean {

final String _ss;

@JsonCreator
Expand All @@ -22,7 +21,19 @@ public SingleNamedStringBean(@JsonProperty("") String ss){
public String getSs() { return _ss; }
}

// [Databind#557]
// For [databind#614]
static class SingleNamedButStillDelegating {
protected final String value;

@JsonCreator(mode=JsonCreator.Mode.DELEGATING)
public SingleNamedButStillDelegating(@JsonProperty("foobar") String v){
value = v;
}

public String getFoobar() { return "x"; }
}

// [databind#557]

static class StringyBean
{
Expand Down Expand Up @@ -73,5 +84,13 @@ public void testSingleStringArgWithImplicitName() throws Exception
StringyBean bean = mapper.readValue(quote("foobar"), StringyBean.class);
assertEquals("foobar", bean.getValue());
}

// [databind#714]
public void testSingleExplicitlyNamedButDelegating() throws Exception
{
SingleNamedButStillDelegating bean = MAPPER.readValue(quote("xyz"),
SingleNamedButStillDelegating.class);
assertEquals("xyz", bean.value);
}
}

0 comments on commit a56270a

Please sign in to comment.