1
1
package com .fasterxml .jackson .databind .deser .impl ;
2
2
3
3
import java .io .IOException ;
4
+ import java .lang .reflect .AnnotatedElement ;
4
5
import java .lang .reflect .Member ;
6
+ import java .lang .reflect .Type ;
5
7
import java .util .*;
6
8
7
9
import com .fasterxml .jackson .databind .*;
@@ -77,7 +79,7 @@ public class CreatorCollector
77
79
/* Life-cycle
78
80
/**********************************************************
79
81
*/
80
-
82
+
81
83
public CreatorCollector (BeanDescription beanDesc , MapperConfig <?> config )
82
84
{
83
85
_beanDesc = beanDesc ;
@@ -91,26 +93,12 @@ public ValueInstantiator constructValueInstantiator(DeserializationConfig config
91
93
final JavaType arrayDelegateType = _computeDelegateType (_creators [C_ARRAY_DELEGATE ], _arrayDelegateArgs );
92
94
final JavaType type = _beanDesc .getType ();
93
95
94
- // Any non-standard creator will prevent; with one exception: int-valued constructor
95
- // that standard containers have can be ignored
96
- if (!_hasNonDefaultCreator ) {
97
- /* 10-May-2014, tatu: If we have nothing special, and we are dealing with one
98
- * of "well-known" types, can create a non-reflection-based instantiator.
99
- */
100
- final Class <?> rawType = type .getRawClass ();
101
- if (rawType == Collection .class || rawType == List .class || rawType == ArrayList .class ) {
102
- return new Vanilla (Vanilla .TYPE_COLLECTION );
103
- }
104
- if (rawType == Map .class || rawType == LinkedHashMap .class ) {
105
- return new Vanilla (Vanilla .TYPE_MAP );
106
- }
107
- if (rawType == HashMap .class ) {
108
- return new Vanilla (Vanilla .TYPE_HASH_MAP );
109
- }
110
- }
111
-
96
+ // 11-Jul-2016, tatu: Earlier optimization by replacing the whole instantiator did not
97
+ // work well, so let's replace by lower-level check:
98
+ AnnotatedWithParams defaultCtor = StdTypeConstructor .tryToOptimize (_creators [C_DEFAULT ]);
99
+
112
100
StdValueInstantiator inst = new StdValueInstantiator (config , type );
113
- inst .configureFromObjectSettings (_creators [ C_DEFAULT ] ,
101
+ inst .configureFromObjectSettings (defaultCtor ,
114
102
_creators [C_DELEGATE ], delegateType , _delegateArgs ,
115
103
_creators [C_PROPS ], _propertyBasedArgs );
116
104
inst .configureFromArraySettings (_creators [C_ARRAY_DELEGATE ], arrayDelegateType , _arrayDelegateArgs );
@@ -122,13 +110,13 @@ public ValueInstantiator constructValueInstantiator(DeserializationConfig config
122
110
inst .configureIncompleteParameter (_incompleteParameter );
123
111
return inst ;
124
112
}
125
-
113
+
126
114
/*
127
115
/**********************************************************
128
116
/* Setters
129
117
/**********************************************************
130
118
*/
131
-
119
+
132
120
/**
133
121
* Method called to indicate the default creator: no-arguments
134
122
* constructor or factory method that is called to instantiate
@@ -179,15 +167,16 @@ public void addPropertyCreator(AnnotatedWithParams creator, boolean explicit,
179
167
HashMap <String ,Integer > names = new HashMap <String ,Integer >();
180
168
for (int i = 0 , len = properties .length ; i < len ; ++i ) {
181
169
String name = properties [i ].getName ();
182
- /* [Issue-13]: Need to consider Injectables, which may not have
183
- * a name at all, and need to be skipped
184
- */
170
+ // Need to consider Injectables, which may not have
171
+ // a name at all, and need to be skipped
185
172
if (name .length () == 0 && properties [i ].getInjectableValueId () != null ) {
186
173
continue ;
187
174
}
188
175
Integer old = names .put (name , Integer .valueOf (i ));
189
176
if (old != null ) {
190
- throw new IllegalArgumentException ("Duplicate creator property \" " +name +"\" (index " +old +" vs " +i +")" );
177
+ throw new IllegalArgumentException (String .format (
178
+ "Duplicate creator property \" %s\" (index %s vs %d)" ,
179
+ name , old , i ));
191
180
}
192
181
}
193
182
}
@@ -344,46 +333,164 @@ protected void verifyNonDup(AnnotatedWithParams newOne, int typeIndex, boolean e
344
333
/**********************************************************
345
334
*/
346
335
347
- protected final static class Vanilla
348
- extends ValueInstantiator .Base
336
+ /**
337
+ * Replacement for default constructor to use for a small set of
338
+ * "well-known" types.
339
+ *<p>
340
+ * Note: replaces earlier <code>Vanilla</code> <code>ValueInstantiator</code>
341
+ * implementation
342
+ *
343
+ * @since 2.8.1 (replacing earlier <code>Vanilla</code> instantiator
344
+ */
345
+ protected final static class StdTypeConstructor
346
+ extends AnnotatedWithParams
349
347
implements java .io .Serializable
350
348
{
351
349
private static final long serialVersionUID = 1L ;
352
350
353
- public final static int TYPE_COLLECTION = 1 ;
354
- public final static int TYPE_MAP = 2 ;
355
- public final static int TYPE_HASH_MAP = 3 ;
351
+ public final static int TYPE_ARRAY_LIST = 1 ;
352
+ public final static int TYPE_HASH_MAP = 2 ;
353
+ public final static int TYPE_LINKED_HASH_MAP = 3 ;
354
+
355
+ private final AnnotatedWithParams _base ;
356
356
357
357
private final int _type ;
358
358
359
- public Vanilla (int t ) {
360
- super (_type (t ));
359
+ public StdTypeConstructor (AnnotatedWithParams base , int t )
360
+ {
361
+ super (base , null );
362
+ _base = base ;
361
363
_type = t ;
362
364
}
363
365
364
- private static Class <?> _type (int t ) {
365
- switch (t ) {
366
- case TYPE_COLLECTION : return ArrayList .class ;
367
- case TYPE_MAP : return LinkedHashMap .class ;
368
- case TYPE_HASH_MAP : return HashMap .class ;
366
+ public static AnnotatedWithParams tryToOptimize (AnnotatedWithParams src )
367
+ {
368
+ if (src != null ) {
369
+ final Class <?> rawType = src .getDeclaringClass ();
370
+ if (rawType == List .class || rawType == ArrayList .class ) {
371
+ return new StdTypeConstructor (src , TYPE_ARRAY_LIST );
372
+ }
373
+ if (rawType == LinkedHashMap .class ) {
374
+ return new StdTypeConstructor (src , TYPE_LINKED_HASH_MAP );
375
+ }
376
+ if (rawType == HashMap .class ) {
377
+ return new StdTypeConstructor (src , TYPE_HASH_MAP );
378
+ }
379
+ }
380
+ return src ;
381
+ }
382
+
383
+ protected final Object _construct () {
384
+ switch (_type ) {
385
+ case TYPE_ARRAY_LIST :
386
+ return new ArrayList <Object >();
387
+ case TYPE_LINKED_HASH_MAP :
388
+ return new LinkedHashMap <String ,Object >();
389
+ case TYPE_HASH_MAP :
390
+ return new HashMap <String ,Object >();
369
391
}
370
- return Object . class ;
392
+ throw new IllegalStateException ( "Unknown type " + _type ) ;
371
393
}
372
394
373
395
@ Override
374
- public boolean canInstantiate () { return true ; }
396
+ public int getParameterCount () {
397
+ return _base .getParameterCount ();
398
+ }
375
399
376
400
@ Override
377
- public boolean canCreateUsingDefault () { return true ; }
401
+ public Class <?> getRawParameterType (int index ) {
402
+ return _base .getRawParameterType (index );
403
+ }
378
404
379
405
@ Override
380
- public Object createUsingDefault (DeserializationContext ctxt ) throws IOException {
381
- switch (_type ) {
382
- case TYPE_COLLECTION : return new ArrayList <Object >();
383
- case TYPE_MAP : return new LinkedHashMap <String ,Object >();
384
- case TYPE_HASH_MAP : return new HashMap <String ,Object >();
385
- }
386
- throw new IllegalStateException ("Unknown type " +_type );
406
+ public JavaType getParameterType (int index ) {
407
+ return _base .getParameterType (index );
408
+ }
409
+
410
+ @ SuppressWarnings ("deprecation" )
411
+ @ Override
412
+ public Type getGenericParameterType (int index ) {
413
+ return _base .getGenericParameterType (index );
414
+ }
415
+
416
+ @ Override
417
+ public Object call () throws Exception {
418
+ return _construct ();
419
+ }
420
+
421
+ @ Override
422
+ public Object call (Object [] args ) throws Exception {
423
+ return _construct ();
424
+ }
425
+
426
+ @ Override
427
+ public Object call1 (Object arg ) throws Exception {
428
+ return _construct ();
429
+ }
430
+
431
+ @ Override
432
+ public Class <?> getDeclaringClass () {
433
+ return _base .getDeclaringClass ();
434
+ }
435
+
436
+ @ Override
437
+ public Member getMember () {
438
+ return _base .getMember ();
439
+ }
440
+
441
+ @ Override
442
+ public void setValue (Object pojo , Object value ) throws UnsupportedOperationException , IllegalArgumentException {
443
+ throw new UnsupportedOperationException ();
444
+ }
445
+
446
+ @ Override
447
+ public Object getValue (Object pojo ) throws UnsupportedOperationException , IllegalArgumentException {
448
+ throw new UnsupportedOperationException ();
449
+ }
450
+
451
+ @ Override
452
+ public Annotated withAnnotations (AnnotationMap fallback ) {
453
+ throw new UnsupportedOperationException ();
454
+ }
455
+
456
+ @ Override
457
+ public AnnotatedElement getAnnotated () {
458
+ return _base .getAnnotated ();
459
+ }
460
+
461
+ @ Override
462
+ protected int getModifiers () {
463
+ return _base .getMember ().getModifiers ();
464
+ }
465
+
466
+ @ Override
467
+ public String getName () {
468
+ return _base .getName ();
469
+ }
470
+
471
+ @ Override
472
+ public JavaType getType () {
473
+ return _base .getType ();
474
+ }
475
+
476
+ @ Override
477
+ public Class <?> getRawType () {
478
+ return _base .getRawType ();
479
+ }
480
+
481
+ @ Override
482
+ public boolean equals (Object o ) {
483
+ return (o == this );
484
+ }
485
+
486
+ @ Override
487
+ public int hashCode () {
488
+ return _base .hashCode ();
489
+ }
490
+
491
+ @ Override
492
+ public String toString () {
493
+ return _base .toString ();
387
494
}
388
495
}
389
496
}
0 commit comments