Skip to content

Commit 4e94c0e

Browse files
committed
Fix #1392 for 2.7.9 / 2.8.4
1 parent 987a463 commit 4e94c0e

File tree

6 files changed

+48
-20
lines changed

6 files changed

+48
-20
lines changed

release-notes/VERSION

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ Project: jackson-databind
44
=== Releases ===
55
------------------------------------------------------------------------
66

7+
2.7.9 (not yet released)
8+
9+
#1392: Custom UnmodifiableSetMixin Fails in Jackson 2.7+ but works in Jackson 2.6
10+
(reported by Rob W)
11+
712
2.7.8 (26-Sep-2016)
813

914
#877: @JsonIgnoreProperties`: ignoring the "cause" property of `Throwable` on GAE

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerBase.java

+1
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ protected BeanDeserializerBase(BeanDeserializerBuilder builder,
228228
_objectIdReader = builder.getObjectIdReader();
229229
_nonStandardCreation = (_unwrappedPropertyHandler != null)
230230
|| _valueInstantiator.canCreateUsingDelegate()
231+
|| _valueInstantiator.canCreateUsingArrayDelegate() // new in 2.7
231232
|| _valueInstantiator.canCreateFromObjectWith()
232233
|| !_valueInstantiator.canCreateUsingDefault()
233234
;

src/main/java/com/fasterxml/jackson/databind/deser/ValueInstantiator.java

+7-3
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public boolean canInstantiate() {
5353
|| canCreateFromInt() || canCreateFromLong()
5454
|| canCreateFromDouble() || canCreateFromBoolean();
5555
}
56-
56+
5757
/**
5858
* Method that can be called to check whether a String-based creator
5959
* is available for this instantiator
@@ -83,7 +83,7 @@ public boolean canInstantiate() {
8383
* creator is available to use (to call {@link #createFromDouble}).
8484
*/
8585
public boolean canCreateFromBoolean() { return false; }
86-
86+
8787
/**
8888
* Method that can be called to check whether a default creator (constructor,
8989
* or no-arg static factory method)
@@ -102,6 +102,8 @@ public boolean canInstantiate() {
102102
* Method that can be called to check whether a array-delegate-based creator
103103
* (single-arg constructor or factory method)
104104
* is available for this instantiator
105+
*
106+
* @since 2.7
105107
*/
106108
public boolean canCreateUsingArrayDelegate() { return false; }
107109

@@ -141,9 +143,11 @@ public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig confi
141143
* non-null type is returned, deserializer will bind JSON into specified
142144
* type (using standard deserializer for that type), and pass that to
143145
* instantiator.
146+
*
147+
* @since 2.7
144148
*/
145149
public JavaType getArrayDelegateType(DeserializationConfig config) { return null; }
146-
150+
147151
/*
148152
/**********************************************************
149153
/* Instantiation methods for JSON Object

src/main/java/com/fasterxml/jackson/databind/deser/std/CollectionDeserializer.java

+21-11
Original file line numberDiff line numberDiff line change
@@ -172,14 +172,24 @@ public CollectionDeserializer createContextual(DeserializationContext ctxt,
172172
{
173173
// May need to resolve types for delegate-based creators:
174174
JsonDeserializer<Object> delegateDeser = null;
175-
if ((_valueInstantiator != null) && _valueInstantiator.canCreateUsingDelegate()) {
176-
JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
177-
if (delegateType == null) {
178-
throw new IllegalArgumentException("Invalid delegate-creator definition for "+_collectionType
179-
+": value instantiator ("+_valueInstantiator.getClass().getName()
180-
+") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'");
175+
if (_valueInstantiator != null) {
176+
if (_valueInstantiator.canCreateUsingDelegate()) {
177+
JavaType delegateType = _valueInstantiator.getDelegateType(ctxt.getConfig());
178+
if (delegateType == null) {
179+
throw new IllegalArgumentException("Invalid delegate-creator definition for "+_collectionType
180+
+": value instantiator ("+_valueInstantiator.getClass().getName()
181+
+") returned true for 'canCreateUsingDelegate()', but null for 'getDelegateType()'");
182+
}
183+
delegateDeser = findDeserializer(ctxt, delegateType, property);
184+
} else if (_valueInstantiator.canCreateUsingArrayDelegate()) {
185+
JavaType delegateType = _valueInstantiator.getArrayDelegateType(ctxt.getConfig());
186+
if (delegateType == null) {
187+
throw new IllegalArgumentException("Invalid array-delegate-creator definition for "+_collectionType
188+
+": value instantiator ("+_valueInstantiator.getClass().getName()
189+
+") returned true for 'canCreateUsingArrayDelegate()', but null for 'getArrayDelegateType()'");
190+
}
191+
delegateDeser = findDeserializer(ctxt, delegateType, property);
181192
}
182-
delegateDeser = findDeserializer(ctxt, delegateType, property);
183193
}
184194
// [databind#1043]: allow per-property allow-wrapping of single overrides:
185195
// 11-Dec-2015, tatu: Should we pass basic `Collection.class`, or more refined? Mostly
@@ -204,7 +214,7 @@ public CollectionDeserializer createContextual(DeserializationContext ctxt,
204214
}
205215
return withResolved(delegateDeser, valueDeser, valueTypeDeser, unwrapSingle);
206216
}
207-
217+
208218
/*
209219
/**********************************************************
210220
/* ContainerDeserializerBase API
@@ -236,9 +246,9 @@ public Collection<Object> deserialize(JsonParser p, DeserializationContext ctxt)
236246
return (Collection<Object>) _valueInstantiator.createUsingDelegate(ctxt,
237247
_delegateDeserializer.deserialize(p, ctxt));
238248
}
239-
/* [JACKSON-620]: empty String may be ok; bit tricky to check, however, since
240-
* there is also possibility of "auto-wrapping" of single-element arrays.
241-
* Hence we only accept empty String here.
249+
/* Empty String may be ok; bit tricky to check, however, since
250+
* there is also possibility of "auto-wrapping" of single-element arrays.
251+
* Hence we only accept empty String here.
242252
*/
243253
if (p.hasToken(JsonToken.VALUE_STRING)) {
244254
String str = p.getText();

src/main/java/com/fasterxml/jackson/databind/deser/std/StdValueInstantiator.java

+12-4
Original file line numberDiff line numberDiff line change
@@ -262,19 +262,27 @@ public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) t
262262
@Override
263263
public Object createUsingDelegate(DeserializationContext ctxt, Object delegate) throws IOException
264264
{
265+
// 04-Oct-2016, tatu: Need delegation to work around [databind#1392]...
266+
if (_delegateCreator == null) {
267+
if (_arrayDelegateCreator != null) {
268+
return _createUsingDelegate(_arrayDelegateCreator, _arrayDelegateArguments, ctxt, delegate);
269+
}
270+
}
265271
return _createUsingDelegate(_delegateCreator, _delegateArguments, ctxt, delegate);
266272
}
267273

268274
@Override
269275
public Object createUsingArrayDelegate(DeserializationContext ctxt, Object delegate) throws IOException
270276
{
271-
if (_arrayDelegateCreator == null) { // sanity-check; caller should check
272-
// fallback to the classic delegate creator
273-
return createUsingDelegate(ctxt, delegate);
277+
if (_arrayDelegateCreator == null) {
278+
if (_delegateCreator != null) { // sanity-check; caller should check
279+
// fallback to the classic delegate creator
280+
return createUsingDelegate(ctxt, delegate);
281+
}
274282
}
275283
return _createUsingDelegate(_arrayDelegateCreator, _arrayDelegateArguments, ctxt, delegate);
276284
}
277-
285+
278286
/*
279287
/**********************************************************
280288
/* Public API implementation; instantiation from JSON scalars

src/test/java/com/fasterxml/jackson/failing/UnmodifiableSetTyping1392Test.java renamed to src/test/java/com/fasterxml/jackson/databind/creators/ArrayDelegatorCreatorForCollectionTest.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.fasterxml.jackson.failing;
1+
package com.fasterxml.jackson.databind.creators;
22

33
import java.util.Collections;
44
import java.util.Set;
@@ -7,7 +7,7 @@
77

88
import com.fasterxml.jackson.databind.*;
99

10-
public class UnmodifiableSetTyping1392Test extends BaseMapTest
10+
public class ArrayDelegatorCreatorForCollectionTest extends BaseMapTest
1111
{
1212
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY)
1313
abstract static class UnmodifiableSetMixin {

0 commit comments

Comments
 (0)