001/* 002 * Copyright 2002-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.beans; 018 019import java.beans.PropertyChangeEvent; 020 021import org.springframework.util.ClassUtils; 022 023/** 024 * Exception thrown on a type mismatch when trying to set a bean property. 025 * 026 * @author Rod Johnson 027 * @author Juergen Hoeller 028 */ 029@SuppressWarnings("serial") 030public class TypeMismatchException extends PropertyAccessException { 031 032 /** 033 * Error code that a type mismatch error will be registered with. 034 */ 035 public static final String ERROR_CODE = "typeMismatch"; 036 037 038 private transient Object value; 039 040 private Class<?> requiredType; 041 042 043 /** 044 * Create a new {@code TypeMismatchException}. 045 * @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem 046 * @param requiredType the required target type 047 */ 048 public TypeMismatchException(PropertyChangeEvent propertyChangeEvent, Class<?> requiredType) { 049 this(propertyChangeEvent, requiredType, null); 050 } 051 052 /** 053 * Create a new {@code TypeMismatchException}. 054 * @param propertyChangeEvent the PropertyChangeEvent that resulted in the problem 055 * @param requiredType the required target type (or {@code null} if not known) 056 * @param cause the root cause (may be {@code null}) 057 */ 058 public TypeMismatchException(PropertyChangeEvent propertyChangeEvent, Class<?> requiredType, Throwable cause) { 059 super(propertyChangeEvent, 060 "Failed to convert property value of type '" + 061 ClassUtils.getDescriptiveType(propertyChangeEvent.getNewValue()) + "'" + 062 (requiredType != null ? 063 " to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" : "") + 064 (propertyChangeEvent.getPropertyName() != null ? 065 " for property '" + propertyChangeEvent.getPropertyName() + "'" : ""), 066 cause); 067 this.value = propertyChangeEvent.getNewValue(); 068 this.requiredType = requiredType; 069 } 070 071 /** 072 * Create a new {@code TypeMismatchException} without a {@code PropertyChangeEvent}. 073 * @param value the offending value that couldn't be converted (may be {@code null}) 074 * @param requiredType the required target type (or {@code null} if not known) 075 */ 076 public TypeMismatchException(Object value, Class<?> requiredType) { 077 this(value, requiredType, null); 078 } 079 080 /** 081 * Create a new {@code TypeMismatchException} without a {@code PropertyChangeEvent}. 082 * @param value the offending value that couldn't be converted (may be {@code null}) 083 * @param requiredType the required target type (or {@code null} if not known) 084 * @param cause the root cause (may be {@code null}) 085 */ 086 public TypeMismatchException(Object value, Class<?> requiredType, Throwable cause) { 087 super("Failed to convert value of type '" + ClassUtils.getDescriptiveType(value) + "'" + 088 (requiredType != null ? " to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" : ""), 089 cause); 090 this.value = value; 091 this.requiredType = requiredType; 092 } 093 094 095 /** 096 * Return the offending value (may be {@code null}). 097 */ 098 @Override 099 public Object getValue() { 100 return this.value; 101 } 102 103 /** 104 * Return the required target type, if any. 105 */ 106 public Class<?> getRequiredType() { 107 return this.requiredType; 108 } 109 110 @Override 111 public String getErrorCode() { 112 return ERROR_CODE; 113 } 114 115}