1 package com.fasterxml.jackson.databind.deser.std; 2 3 import java.io.IOException; 4 import java.lang.reflect.InvocationTargetException; 5 6 import com.fasterxml.jackson.databind.*; 7 import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; 8 import com.fasterxml.jackson.databind.deser.*; 9 import com.fasterxml.jackson.databind.introspect.AnnotatedWithParams; 10 import com.fasterxml.jackson.databind.util.ClassUtil; 11 import java.math.BigDecimal; 12 import java.math.BigInteger; 13 14 /** 15 * Default {@link ValueInstantiator} implementation, which supports 16 * Creator methods that can be indicated by standard Jackson 17 * annotations. 18 */ 19 @JacksonStdImpl 20 public class StdValueInstantiator 21 extends ValueInstantiator 22 implements java.io.Serializable 23 { 24 private static final long serialVersionUID = 1L; 25 26 /** 27 * Type of values that are instantiated; used 28 * for error reporting purposes. 29 */ 30 protected final String _valueTypeDesc; 31 32 /** 33 * @since 2.8 34 */ 35 protected final Class<?> _valueClass; 36 37 // // // Default (no-args) construction 38 39 /** 40 * Default (no-argument) constructor to use for instantiation 41 * (with {@link #createUsingDefault}) 42 */ 43 protected AnnotatedWithParams _defaultCreator; 44 45 // // // With-args (property-based) construction 46 47 protected AnnotatedWithParams _withArgsCreator; 48 protected SettableBeanProperty[] _constructorArguments; 49 50 // // // Delegate construction 51 52 protected JavaType _delegateType; 53 protected AnnotatedWithParams _delegateCreator; 54 protected SettableBeanProperty[] _delegateArguments; 55 56 // // // Array delegate construction 57 58 protected JavaType _arrayDelegateType; 59 protected AnnotatedWithParams _arrayDelegateCreator; 60 protected SettableBeanProperty[] _arrayDelegateArguments; 61 62 // // // Scalar construction 63 64 protected AnnotatedWithParams _fromStringCreator; 65 protected AnnotatedWithParams _fromIntCreator; 66 protected AnnotatedWithParams _fromLongCreator; 67 protected AnnotatedWithParams _fromBigIntegerCreator; 68 protected AnnotatedWithParams _fromDoubleCreator; 69 protected AnnotatedWithParams _fromBigDecimalCreator; 70 protected AnnotatedWithParams _fromBooleanCreator; 71 72 /* 73 /********************************************************** 74 /* Life-cycle 75 /********************************************************** 76 */ 77 78 /** 79 * @deprecated Since 2.7 use constructor that takes {@link JavaType} instead 80 */ 81 @Deprecated StdValueInstantiator(DeserializationConfig config, Class<?> valueType)82 public StdValueInstantiator(DeserializationConfig config, Class<?> valueType) { 83 _valueTypeDesc = ClassUtil.nameOf(valueType); 84 _valueClass = (valueType == null) ? Object.class : valueType; 85 } 86 StdValueInstantiator(DeserializationConfig config, JavaType valueType)87 public StdValueInstantiator(DeserializationConfig config, JavaType valueType) { 88 _valueTypeDesc = (valueType == null) ? "UNKNOWN TYPE" : valueType.toString(); 89 _valueClass = (valueType == null) ? Object.class : valueType.getRawClass(); 90 } 91 92 /** 93 * Copy-constructor that sub-classes can use when creating new instances 94 * by fluent-style construction 95 */ StdValueInstantiator(StdValueInstantiator src)96 protected StdValueInstantiator(StdValueInstantiator src) 97 { 98 _valueTypeDesc = src._valueTypeDesc; 99 _valueClass = src._valueClass; 100 101 _defaultCreator = src._defaultCreator; 102 103 _constructorArguments = src._constructorArguments; 104 _withArgsCreator = src._withArgsCreator; 105 106 _delegateType = src._delegateType; 107 _delegateCreator = src._delegateCreator; 108 _delegateArguments = src._delegateArguments; 109 110 _arrayDelegateType = src._arrayDelegateType; 111 _arrayDelegateCreator = src._arrayDelegateCreator; 112 _arrayDelegateArguments = src._arrayDelegateArguments; 113 114 _fromStringCreator = src._fromStringCreator; 115 _fromIntCreator = src._fromIntCreator; 116 _fromLongCreator = src._fromLongCreator; 117 _fromBigIntegerCreator = src._fromBigIntegerCreator; 118 _fromDoubleCreator = src._fromDoubleCreator; 119 _fromBigDecimalCreator = src._fromBigDecimalCreator; 120 _fromBooleanCreator = src._fromBooleanCreator; 121 } 122 123 /** 124 * Method for setting properties related to instantiating values 125 * from JSON Object. We will choose basically only one approach (out of possible 126 * three), and clear other properties 127 */ configureFromObjectSettings(AnnotatedWithParams defaultCreator, AnnotatedWithParams delegateCreator, JavaType delegateType, SettableBeanProperty[] delegateArgs, AnnotatedWithParams withArgsCreator, SettableBeanProperty[] constructorArgs)128 public void configureFromObjectSettings(AnnotatedWithParams defaultCreator, 129 AnnotatedWithParams delegateCreator, JavaType delegateType, SettableBeanProperty[] delegateArgs, 130 AnnotatedWithParams withArgsCreator, SettableBeanProperty[] constructorArgs) 131 { 132 _defaultCreator = defaultCreator; 133 _delegateCreator = delegateCreator; 134 _delegateType = delegateType; 135 _delegateArguments = delegateArgs; 136 _withArgsCreator = withArgsCreator; 137 _constructorArguments = constructorArgs; 138 } 139 configureFromArraySettings( AnnotatedWithParams arrayDelegateCreator, JavaType arrayDelegateType, SettableBeanProperty[] arrayDelegateArgs)140 public void configureFromArraySettings( 141 AnnotatedWithParams arrayDelegateCreator, 142 JavaType arrayDelegateType, 143 SettableBeanProperty[] arrayDelegateArgs) 144 { 145 _arrayDelegateCreator = arrayDelegateCreator; 146 _arrayDelegateType = arrayDelegateType; 147 _arrayDelegateArguments = arrayDelegateArgs; 148 } 149 configureFromStringCreator(AnnotatedWithParams creator)150 public void configureFromStringCreator(AnnotatedWithParams creator) { 151 _fromStringCreator = creator; 152 } 153 configureFromIntCreator(AnnotatedWithParams creator)154 public void configureFromIntCreator(AnnotatedWithParams creator) { 155 _fromIntCreator = creator; 156 } 157 configureFromLongCreator(AnnotatedWithParams creator)158 public void configureFromLongCreator(AnnotatedWithParams creator) { 159 _fromLongCreator = creator; 160 } 161 configureFromBigIntegerCreator(AnnotatedWithParams creator)162 public void configureFromBigIntegerCreator(AnnotatedWithParams creator) { _fromBigIntegerCreator = creator; } 163 configureFromDoubleCreator(AnnotatedWithParams creator)164 public void configureFromDoubleCreator(AnnotatedWithParams creator) { 165 _fromDoubleCreator = creator; 166 } 167 configureFromBigDecimalCreator(AnnotatedWithParams creator)168 public void configureFromBigDecimalCreator(AnnotatedWithParams creator) { _fromBigDecimalCreator = creator; } 169 configureFromBooleanCreator(AnnotatedWithParams creator)170 public void configureFromBooleanCreator(AnnotatedWithParams creator) { 171 _fromBooleanCreator = creator; 172 } 173 174 /* 175 /********************************************************** 176 /* Public API implementation; metadata 177 /********************************************************** 178 */ 179 180 @Override getValueTypeDesc()181 public String getValueTypeDesc() { 182 return _valueTypeDesc; 183 } 184 185 @Override getValueClass()186 public Class<?> getValueClass() { 187 return _valueClass; 188 } 189 190 @Override canCreateFromString()191 public boolean canCreateFromString() { 192 return (_fromStringCreator != null); 193 } 194 195 @Override canCreateFromInt()196 public boolean canCreateFromInt() { 197 return (_fromIntCreator != null); 198 } 199 200 @Override canCreateFromLong()201 public boolean canCreateFromLong() { 202 return (_fromLongCreator != null); 203 } 204 205 @Override canCreateFromBigInteger()206 public boolean canCreateFromBigInteger() { return _fromBigIntegerCreator != null; } 207 208 @Override canCreateFromDouble()209 public boolean canCreateFromDouble() { 210 return (_fromDoubleCreator != null); 211 } 212 213 @Override canCreateFromBigDecimal()214 public boolean canCreateFromBigDecimal() { return _fromBigDecimalCreator != null; } 215 216 @Override canCreateFromBoolean()217 public boolean canCreateFromBoolean() { 218 return (_fromBooleanCreator != null); 219 } 220 221 @Override canCreateUsingDefault()222 public boolean canCreateUsingDefault() { 223 return (_defaultCreator != null); 224 } 225 226 @Override canCreateUsingDelegate()227 public boolean canCreateUsingDelegate() { 228 return (_delegateType != null); 229 } 230 231 @Override canCreateUsingArrayDelegate()232 public boolean canCreateUsingArrayDelegate() { 233 return (_arrayDelegateType != null); 234 } 235 236 @Override canCreateFromObjectWith()237 public boolean canCreateFromObjectWith() { 238 return (_withArgsCreator != null); 239 } 240 241 @Override canInstantiate()242 public boolean canInstantiate() { 243 return canCreateUsingDefault() 244 || canCreateUsingDelegate() || canCreateUsingArrayDelegate() 245 || canCreateFromObjectWith() || canCreateFromString() 246 || canCreateFromInt() || canCreateFromLong() 247 || canCreateFromDouble() || canCreateFromBoolean(); 248 } 249 250 @Override getDelegateType(DeserializationConfig config)251 public JavaType getDelegateType(DeserializationConfig config) { 252 return _delegateType; 253 } 254 255 @Override getArrayDelegateType(DeserializationConfig config)256 public JavaType getArrayDelegateType(DeserializationConfig config) { 257 return _arrayDelegateType; 258 } 259 260 @Override getFromObjectArguments(DeserializationConfig config)261 public SettableBeanProperty[] getFromObjectArguments(DeserializationConfig config) { 262 return _constructorArguments; 263 } 264 265 /* 266 /********************************************************** 267 /* Public API implementation; instantiation from JSON Object 268 /********************************************************** 269 */ 270 271 @Override createUsingDefault(DeserializationContext ctxt)272 public Object createUsingDefault(DeserializationContext ctxt) throws IOException 273 { 274 if (_defaultCreator == null) { // sanity-check; caller should check 275 return super.createUsingDefault(ctxt); 276 } 277 try { 278 return _defaultCreator.call(); 279 } catch (Exception e) { // 19-Apr-2017, tatu: Let's not catch Errors, just Exceptions 280 return ctxt.handleInstantiationProblem(_valueClass, null, rewrapCtorProblem(ctxt, e)); 281 } 282 } 283 284 @Override createFromObjectWith(DeserializationContext ctxt, Object[] args)285 public Object createFromObjectWith(DeserializationContext ctxt, Object[] args) throws IOException 286 { 287 if (_withArgsCreator == null) { // sanity-check; caller should check 288 return super.createFromObjectWith(ctxt, args); 289 } 290 try { 291 return _withArgsCreator.call(args); 292 } catch (Exception e) { // 19-Apr-2017, tatu: Let's not catch Errors, just Exceptions 293 return ctxt.handleInstantiationProblem(_valueClass, args, rewrapCtorProblem(ctxt, e)); 294 } 295 } 296 297 @Override createUsingDelegate(DeserializationContext ctxt, Object delegate)298 public Object createUsingDelegate(DeserializationContext ctxt, Object delegate) throws IOException 299 { 300 // 04-Oct-2016, tatu: Need delegation to work around [databind#1392]... 301 if (_delegateCreator == null) { 302 if (_arrayDelegateCreator != null) { 303 return _createUsingDelegate(_arrayDelegateCreator, _arrayDelegateArguments, ctxt, delegate); 304 } 305 } 306 return _createUsingDelegate(_delegateCreator, _delegateArguments, ctxt, delegate); 307 } 308 309 @Override createUsingArrayDelegate(DeserializationContext ctxt, Object delegate)310 public Object createUsingArrayDelegate(DeserializationContext ctxt, Object delegate) throws IOException 311 { 312 if (_arrayDelegateCreator == null) { 313 if (_delegateCreator != null) { // sanity-check; caller should check 314 // fallback to the classic delegate creator 315 return createUsingDelegate(ctxt, delegate); 316 } 317 } 318 return _createUsingDelegate(_arrayDelegateCreator, _arrayDelegateArguments, ctxt, delegate); 319 } 320 321 /* 322 /********************************************************** 323 /* Public API implementation; instantiation from JSON scalars 324 /********************************************************** 325 */ 326 327 @Override createFromString(DeserializationContext ctxt, String value)328 public Object createFromString(DeserializationContext ctxt, String value) throws IOException 329 { 330 if (_fromStringCreator != null) { 331 try { 332 return _fromStringCreator.call1(value); 333 } catch (Throwable t) { 334 return ctxt.handleInstantiationProblem(_fromStringCreator.getDeclaringClass(), 335 value, rewrapCtorProblem(ctxt, t)); 336 } 337 } 338 return super.createFromString(ctxt, value); 339 } 340 341 @Override createFromInt(DeserializationContext ctxt, int value)342 public Object createFromInt(DeserializationContext ctxt, int value) throws IOException 343 { 344 // First: "native" int methods work best: 345 if (_fromIntCreator != null) { 346 Object arg = Integer.valueOf(value); 347 try { 348 return _fromIntCreator.call1(arg); 349 } catch (Throwable t0) { 350 return ctxt.handleInstantiationProblem(_fromIntCreator.getDeclaringClass(), 351 arg, rewrapCtorProblem(ctxt, t0)); 352 } 353 } 354 // but if not, can do widening conversion 355 if (_fromLongCreator != null) { 356 Object arg = Long.valueOf(value); 357 try { 358 return _fromLongCreator.call1(arg); 359 } catch (Throwable t0) { 360 return ctxt.handleInstantiationProblem(_fromLongCreator.getDeclaringClass(), 361 arg, rewrapCtorProblem(ctxt, t0)); 362 } 363 } 364 365 if (_fromBigIntegerCreator != null) { 366 Object arg = BigInteger.valueOf(value); 367 try { 368 return _fromBigIntegerCreator.call1(arg); 369 } catch (Throwable t0) { 370 return ctxt.handleInstantiationProblem(_fromBigIntegerCreator.getDeclaringClass(), 371 arg, rewrapCtorProblem(ctxt, t0) 372 ); 373 } 374 } 375 376 return super.createFromInt(ctxt, value); 377 } 378 379 @Override createFromLong(DeserializationContext ctxt, long value)380 public Object createFromLong(DeserializationContext ctxt, long value) throws IOException 381 { 382 if (_fromLongCreator != null) { 383 Object arg = Long.valueOf(value); 384 try { 385 return _fromLongCreator.call1(arg); 386 } catch (Throwable t0) { 387 return ctxt.handleInstantiationProblem(_fromLongCreator.getDeclaringClass(), 388 arg, 389 rewrapCtorProblem(ctxt, t0) 390 ); 391 } 392 } 393 394 if (_fromBigIntegerCreator != null) { 395 Object arg = BigInteger.valueOf(value); 396 try { 397 return _fromBigIntegerCreator.call1(arg); 398 } catch (Throwable t0) { 399 return ctxt.handleInstantiationProblem(_fromBigIntegerCreator.getDeclaringClass(), 400 arg, rewrapCtorProblem(ctxt, t0) 401 ); 402 } 403 } 404 405 return super.createFromLong(ctxt, value); 406 } 407 408 @Override createFromBigInteger(DeserializationContext ctxt, BigInteger value)409 public Object createFromBigInteger(DeserializationContext ctxt, BigInteger value) throws IOException 410 { 411 if (_fromBigDecimalCreator != null) { 412 try { 413 return _fromBigIntegerCreator.call1(value); 414 } catch (Throwable t) { 415 return ctxt.handleInstantiationProblem(_fromBigIntegerCreator.getDeclaringClass(), 416 value, rewrapCtorProblem(ctxt, t) 417 ); 418 } 419 } 420 421 return super.createFromBigInteger(ctxt, value); 422 } 423 424 @Override createFromDouble(DeserializationContext ctxt, double value)425 public Object createFromDouble(DeserializationContext ctxt, double value) throws IOException 426 { 427 if(_fromDoubleCreator != null) { 428 Object arg = Double.valueOf(value); 429 try { 430 return _fromDoubleCreator.call1(arg); 431 } catch (Throwable t0) { 432 return ctxt.handleInstantiationProblem(_fromDoubleCreator.getDeclaringClass(), 433 arg, rewrapCtorProblem(ctxt, t0)); 434 } 435 } 436 437 if (_fromBigDecimalCreator != null) { 438 Object arg = BigDecimal.valueOf(value); 439 try { 440 return _fromBigDecimalCreator.call1(arg); 441 } catch (Throwable t0) { 442 return ctxt.handleInstantiationProblem(_fromBigDecimalCreator.getDeclaringClass(), 443 arg, rewrapCtorProblem(ctxt, t0)); 444 } 445 } 446 447 return super.createFromDouble(ctxt, value); 448 } 449 450 @Override createFromBigDecimal(DeserializationContext ctxt, BigDecimal value)451 public Object createFromBigDecimal(DeserializationContext ctxt, BigDecimal value) throws IOException 452 { 453 if (_fromBigDecimalCreator != null) { 454 try { 455 return _fromBigDecimalCreator.call1(value); 456 } catch (Throwable t) { 457 return ctxt.handleInstantiationProblem(_fromBigDecimalCreator.getDeclaringClass(), 458 value, rewrapCtorProblem(ctxt, t) 459 ); 460 } 461 } 462 463 return super.createFromBigDecimal(ctxt, value); 464 } 465 466 @Override createFromBoolean(DeserializationContext ctxt, boolean value)467 public Object createFromBoolean(DeserializationContext ctxt, boolean value) throws IOException 468 { 469 if (_fromBooleanCreator == null) { 470 return super.createFromBoolean(ctxt, value); 471 } 472 final Boolean arg = Boolean.valueOf(value); 473 try { 474 return _fromBooleanCreator.call1(arg); 475 } catch (Throwable t0) { 476 return ctxt.handleInstantiationProblem(_fromBooleanCreator.getDeclaringClass(), 477 arg, rewrapCtorProblem(ctxt, t0)); 478 } 479 } 480 481 /* 482 /********************************************************** 483 /* Extended API: configuration mutators, accessors 484 /********************************************************** 485 */ 486 487 @Override getDelegateCreator()488 public AnnotatedWithParams getDelegateCreator() { 489 return _delegateCreator; 490 } 491 492 @Override getArrayDelegateCreator()493 public AnnotatedWithParams getArrayDelegateCreator() { 494 return _arrayDelegateCreator; 495 } 496 497 @Override getDefaultCreator()498 public AnnotatedWithParams getDefaultCreator() { 499 return _defaultCreator; 500 } 501 502 @Override getWithArgsCreator()503 public AnnotatedWithParams getWithArgsCreator() { 504 return _withArgsCreator; 505 } 506 507 /* 508 /********************************************************** 509 /* Internal methods 510 /********************************************************** 511 */ 512 513 /** 514 * @deprecated Since 2.7 call either {@link #rewrapCtorProblem} or 515 * {@link #wrapAsJsonMappingException} 516 */ 517 @Deprecated // since 2.7 wrapException(Throwable t)518 protected JsonMappingException wrapException(Throwable t) 519 { 520 // 05-Nov-2015, tatu: This used to always unwrap the whole exception, but now only 521 // does so if and until `JsonMappingException` is found. 522 for (Throwable curr = t; curr != null; curr = curr.getCause()) { 523 if (curr instanceof JsonMappingException) { 524 return (JsonMappingException) curr; 525 } 526 } 527 return new JsonMappingException(null, 528 "Instantiation of "+getValueTypeDesc()+" value failed: "+ClassUtil.exceptionMessage(t), t); 529 } 530 531 /** 532 * @deprecated Since 2.7 call either {@link #rewrapCtorProblem} or 533 * {@link #wrapAsJsonMappingException} 534 */ 535 @Deprecated // since 2.10 unwrapAndWrapException(DeserializationContext ctxt, Throwable t)536 protected JsonMappingException unwrapAndWrapException(DeserializationContext ctxt, Throwable t) 537 { 538 // 05-Nov-2015, tatu: This used to always unwrap the whole exception, but now only 539 // does so if and until `JsonMappingException` is found. 540 for (Throwable curr = t; curr != null; curr = curr.getCause()) { 541 if (curr instanceof JsonMappingException) { 542 return (JsonMappingException) curr; 543 } 544 } 545 return ctxt.instantiationException(getValueClass(), t); 546 } 547 548 /** 549 * Helper method that will return given {@link Throwable} case as 550 * a {@link JsonMappingException} (if it is of that type), or call 551 * {@link DeserializationContext#instantiationException(Class, Throwable)} to 552 * produce and return suitable {@link JsonMappingException}. 553 * 554 * @since 2.7 555 */ wrapAsJsonMappingException(DeserializationContext ctxt, Throwable t)556 protected JsonMappingException wrapAsJsonMappingException(DeserializationContext ctxt, 557 Throwable t) 558 { 559 // 05-Nov-2015, tatu: Only avoid wrapping if already a JsonMappingException 560 if (t instanceof JsonMappingException) { 561 return (JsonMappingException) t; 562 } 563 return ctxt.instantiationException(getValueClass(), t); 564 } 565 566 /** 567 * Method that subclasses may call for standard handling of an exception thrown when 568 * calling constructor or factory method. Will unwrap {@link ExceptionInInitializerError} 569 * and {@link InvocationTargetException}s, then call {@link #wrapAsJsonMappingException}. 570 * 571 * @since 2.7 572 */ rewrapCtorProblem(DeserializationContext ctxt, Throwable t)573 protected JsonMappingException rewrapCtorProblem(DeserializationContext ctxt, 574 Throwable t) 575 { 576 // 05-Nov-2015, tatu: Seems like there are really only 2 useless wrapper errors/exceptions, 577 // so just peel those, and nothing else 578 if ((t instanceof ExceptionInInitializerError) // from static initialization block 579 || (t instanceof InvocationTargetException) // from constructor/method 580 ) { 581 Throwable cause = t.getCause(); 582 if (cause != null) { 583 t = cause; 584 } 585 } 586 return wrapAsJsonMappingException(ctxt, t); 587 } 588 589 /* 590 /********************************************************** 591 /* Helper methods 592 /********************************************************** 593 */ 594 _createUsingDelegate(AnnotatedWithParams delegateCreator, SettableBeanProperty[] delegateArguments, DeserializationContext ctxt, Object delegate)595 private Object _createUsingDelegate(AnnotatedWithParams delegateCreator, 596 SettableBeanProperty[] delegateArguments, 597 DeserializationContext ctxt, 598 Object delegate) 599 throws IOException 600 { 601 if (delegateCreator == null) { // sanity-check; caller should check 602 throw new IllegalStateException("No delegate constructor for "+getValueTypeDesc()); 603 } 604 try { 605 // First simple case: just delegate, no injectables 606 if (delegateArguments == null) { 607 return delegateCreator.call1(delegate); 608 } 609 // And then the case with at least one injectable... 610 final int len = delegateArguments.length; 611 Object[] args = new Object[len]; 612 for (int i = 0; i < len; ++i) { 613 SettableBeanProperty prop = delegateArguments[i]; 614 if (prop == null) { // delegate 615 args[i] = delegate; 616 } else { // nope, injectable: 617 args[i] = ctxt.findInjectableValue(prop.getInjectableValueId(), prop, null); 618 } 619 } 620 // and then try calling with full set of arguments 621 return delegateCreator.call(args); 622 } catch (Throwable t) { 623 throw rewrapCtorProblem(ctxt, t); 624 } 625 } 626 } 627