1 package org.apache.velocity.util.introspection; 2 3 /* 4 * Licensed to the Apache Software Foundation (ASF) under one 5 * or more contributor license agreements. See the NOTICE file 6 * distributed with this work for additional information 7 * regarding copyright ownership. The ASF licenses this file 8 * to you under the Apache License, Version 2.0 (the 9 * "License"); you may not use this file except in compliance 10 * with the License. You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, 15 * software distributed under the License is distributed on an 16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 * KIND, either express or implied. See the License for the 18 * specific language governing permissions and limitations 19 * under the License. 20 */ 21 22 import org.apache.commons.lang3.LocaleUtils; 23 import org.apache.commons.lang3.reflect.TypeUtils; 24 import org.apache.commons.lang3.tuple.Pair; 25 26 import java.lang.reflect.Type; 27 import java.math.BigDecimal; 28 import java.math.BigInteger; 29 import java.util.HashMap; 30 import java.util.Locale; 31 import java.util.Map; 32 import java.util.Optional; 33 import java.util.concurrent.ConcurrentHashMap; 34 35 /** 36 * A conversion handler adds admissible conversions between Java types whenever Velocity introspection has to map 37 * VTL methods and property accessors to Java methods. This implementation is the default Conversion Handler 38 * for Velocity. 39 * 40 * @author <a href="mailto:claude.brisson@gmail.com">Claude Brisson</a> 41 * @version $Id: TypeConversionHandlerImpl.java $ 42 * @since 2.0 43 */ 44 45 public class TypeConversionHandlerImpl implements TypeConversionHandler 46 { 47 /** 48 * standard narrowing and string parsing conversions. 49 */ 50 static Map<Pair<String, String>, Converter<?>> standardConverterMap; 51 52 /** 53 * basic toString converter 54 */ 55 static Converter<?> toString; 56 57 /** 58 * cache miss converter 59 */ 60 static Converter<?> cacheMiss; 61 62 /** 63 * a converters cache map, initialized with the standard narrowing and string parsing conversions. 64 */ 65 Map<Pair<String, String>, Converter<?>> converterCacheMap; 66 67 static final String BOOLEAN_TYPE = "boolean"; 68 static final String BYTE_TYPE = "byte"; 69 static final String SHORT_TYPE = "short"; 70 static final String INTEGER_TYPE = "int"; 71 static final String LONG_TYPE = "long"; 72 static final String FLOAT_TYPE = "float"; 73 static final String DOUBLE_TYPE = "double"; 74 static final String CHARACTER_TYPE = "char"; 75 static final String BOOLEAN_CLASS = "java.lang.Boolean"; 76 static final String BYTE_CLASS = "java.lang.Byte"; 77 static final String SHORT_CLASS = "java.lang.Short"; 78 static final String INTEGER_CLASS = "java.lang.Integer"; 79 static final String LONG_CLASS = "java.lang.Long"; 80 static final String BIG_INTEGER_CLASS = "java.math.BigInteger"; 81 static final String FLOAT_CLASS = "java.lang.Float"; 82 static final String DOUBLE_CLASS = "java.lang.Double"; 83 static final String BIG_DECIMAL_CLASS = "java.math.BigDecimal"; 84 static final String NUMBER_CLASS = "java.lang.Number"; 85 static final String CHARACTER_CLASS = "java.lang.Character"; 86 static final String STRING_CLASS = "java.lang.String"; 87 static final String LOCALE_CLASS = "java.util.Locale"; 88 89 /* 90 * Bounds checking helper 91 */ 92 checkBounds(Number n, double min, double max)93 static boolean checkBounds(Number n, double min, double max) 94 { 95 double d = n.doubleValue(); 96 if (d < min || d > max) 97 { 98 throw new NumberFormatException("value out of range: " + n); 99 } 100 return true; 101 } 102 103 static 104 { 105 standardConverterMap = new HashMap<>(); 106 107 cacheMiss = o -> o; 108 109 /* 110 * Conversions towards boolean 111 */ 112 113 /* number -> boolean */ 114 115 Converter<Boolean> numberToBool = o -> Optional.ofNullable((Number)o).map(n -> Double.compare(n.doubleValue(), 0.0) != 0).orElse(null); 116 Converter<Boolean> bigIntegerToBool = o -> Optional.ofNullable((BigInteger)o).map(bi -> bi.signum() != 0).orElse(null); 117 Converter<Boolean> bigDecimalToBool = o -> Optional.ofNullable((BigDecimal)o).map(bi -> bi.signum() != 0).orElse(null); 118 Pair.of(BOOLEAN_CLASS, BYTE_CLASS)119 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, BYTE_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, SHORT_CLASS)120 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, SHORT_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, INTEGER_CLASS)121 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, INTEGER_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, LONG_CLASS)122 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, LONG_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, BIG_INTEGER_CLASS)123 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, BIG_INTEGER_CLASS), bigIntegerToBool); Pair.of(BOOLEAN_CLASS, FLOAT_CLASS)124 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, FLOAT_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, DOUBLE_CLASS)125 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, DOUBLE_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, BIG_DECIMAL_CLASS)126 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, BIG_DECIMAL_CLASS), bigDecimalToBool); Pair.of(BOOLEAN_CLASS, NUMBER_CLASS)127 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, NUMBER_CLASS), numberToBool); Pair.of(BOOLEAN_CLASS, BYTE_TYPE)128 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, BYTE_TYPE), numberToBool); Pair.of(BOOLEAN_CLASS, SHORT_TYPE)129 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, SHORT_TYPE), numberToBool); Pair.of(BOOLEAN_CLASS, INTEGER_TYPE)130 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, INTEGER_TYPE), numberToBool); Pair.of(BOOLEAN_CLASS, LONG_TYPE)131 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, LONG_TYPE), numberToBool); Pair.of(BOOLEAN_CLASS, FLOAT_TYPE)132 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, FLOAT_TYPE), numberToBool); Pair.of(BOOLEAN_CLASS, DOUBLE_TYPE)133 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, DOUBLE_TYPE), numberToBool); Pair.of(BOOLEAN_TYPE, BYTE_CLASS)134 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, BYTE_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, SHORT_CLASS)135 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, SHORT_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, INTEGER_CLASS)136 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, INTEGER_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, BIG_INTEGER_CLASS)137 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, BIG_INTEGER_CLASS), bigIntegerToBool); Pair.of(BOOLEAN_TYPE, LONG_CLASS)138 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, LONG_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, FLOAT_CLASS)139 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, FLOAT_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, DOUBLE_CLASS)140 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, DOUBLE_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, BIG_DECIMAL_CLASS)141 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, BIG_DECIMAL_CLASS), bigDecimalToBool); Pair.of(BOOLEAN_TYPE, NUMBER_CLASS)142 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, NUMBER_CLASS), numberToBool); Pair.of(BOOLEAN_TYPE, BYTE_TYPE)143 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, BYTE_TYPE), numberToBool); Pair.of(BOOLEAN_TYPE, SHORT_TYPE)144 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, SHORT_TYPE), numberToBool); Pair.of(BOOLEAN_TYPE, INTEGER_TYPE)145 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, INTEGER_TYPE), numberToBool); Pair.of(BOOLEAN_TYPE, LONG_TYPE)146 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, LONG_TYPE), numberToBool); Pair.of(BOOLEAN_TYPE, FLOAT_TYPE)147 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, FLOAT_TYPE), numberToBool); Pair.of(BOOLEAN_TYPE, DOUBLE_TYPE)148 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, DOUBLE_TYPE), numberToBool); 149 150 /* character -> boolean */ 151 152 Converter<Boolean> charToBoolean = o -> Optional.ofNullable((Character)o).map(c -> c != 0).orElse(null); 153 Pair.of(BOOLEAN_CLASS, CHARACTER_CLASS)154 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, CHARACTER_CLASS), charToBoolean); Pair.of(BOOLEAN_CLASS, CHARACTER_TYPE)155 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, CHARACTER_TYPE), charToBoolean); Pair.of(BOOLEAN_TYPE, CHARACTER_CLASS)156 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, CHARACTER_CLASS), charToBoolean); Pair.of(BOOLEAN_TYPE, CHARACTER_TYPE)157 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, CHARACTER_TYPE), charToBoolean); 158 159 /* string -> boolean */ 160 161 Converter<Boolean> stringToBoolean = o -> Boolean.valueOf(String.valueOf(o)); 162 Pair.of(BOOLEAN_CLASS, STRING_CLASS)163 standardConverterMap.put(Pair.of(BOOLEAN_CLASS, STRING_CLASS), stringToBoolean); Pair.of(BOOLEAN_TYPE, STRING_CLASS)164 standardConverterMap.put(Pair.of(BOOLEAN_TYPE, STRING_CLASS), stringToBoolean); 165 166 /* 167 * Conversions towards byte 168 */ 169 170 /* narrowing towards byte */ 171 172 Converter<Byte> narrowingToByte = o -> Optional.ofNullable((Number)o) 173 .filter(n -> checkBounds(n, Byte.MIN_VALUE, Byte.MAX_VALUE)) 174 .map(Number::byteValue) 175 .orElse(null); 176 177 Converter<Byte> narrowingBigIntegerToByte = o -> Optional.ofNullable((BigInteger)o) 178 .map(BigInteger::byteValueExact) 179 .orElse(null); 180 181 Converter<Byte> narrowingBigDecimalToByte = o -> Optional.ofNullable((BigDecimal)o) 182 .map(BigDecimal::byteValueExact) 183 .orElse(null); 184 Pair.of(BYTE_CLASS, SHORT_CLASS)185 standardConverterMap.put(Pair.of(BYTE_CLASS, SHORT_CLASS), narrowingToByte); Pair.of(BYTE_CLASS, INTEGER_CLASS)186 standardConverterMap.put(Pair.of(BYTE_CLASS, INTEGER_CLASS), narrowingToByte); Pair.of(BYTE_CLASS, LONG_CLASS)187 standardConverterMap.put(Pair.of(BYTE_CLASS, LONG_CLASS), narrowingToByte); Pair.of(BYTE_CLASS, BIG_INTEGER_CLASS)188 standardConverterMap.put(Pair.of(BYTE_CLASS, BIG_INTEGER_CLASS), narrowingBigIntegerToByte); Pair.of(BYTE_CLASS, FLOAT_CLASS)189 standardConverterMap.put(Pair.of(BYTE_CLASS, FLOAT_CLASS), narrowingToByte); Pair.of(BYTE_CLASS, DOUBLE_CLASS)190 standardConverterMap.put(Pair.of(BYTE_CLASS, DOUBLE_CLASS), narrowingToByte); Pair.of(BYTE_CLASS, BIG_DECIMAL_CLASS)191 standardConverterMap.put(Pair.of(BYTE_CLASS, BIG_DECIMAL_CLASS), narrowingBigDecimalToByte); Pair.of(BYTE_CLASS, NUMBER_CLASS)192 standardConverterMap.put(Pair.of(BYTE_CLASS, NUMBER_CLASS), narrowingToByte); Pair.of(BYTE_CLASS, SHORT_TYPE)193 standardConverterMap.put(Pair.of(BYTE_CLASS, SHORT_TYPE), narrowingToByte); Pair.of(BYTE_CLASS, INTEGER_TYPE)194 standardConverterMap.put(Pair.of(BYTE_CLASS, INTEGER_TYPE), narrowingToByte); Pair.of(BYTE_CLASS, LONG_TYPE)195 standardConverterMap.put(Pair.of(BYTE_CLASS, LONG_TYPE), narrowingToByte); Pair.of(BYTE_CLASS, FLOAT_TYPE)196 standardConverterMap.put(Pair.of(BYTE_CLASS, FLOAT_TYPE), narrowingToByte); Pair.of(BYTE_CLASS, DOUBLE_TYPE)197 standardConverterMap.put(Pair.of(BYTE_CLASS, DOUBLE_TYPE), narrowingToByte); Pair.of(BYTE_TYPE, SHORT_CLASS)198 standardConverterMap.put(Pair.of(BYTE_TYPE, SHORT_CLASS), narrowingToByte); Pair.of(BYTE_TYPE, INTEGER_CLASS)199 standardConverterMap.put(Pair.of(BYTE_TYPE, INTEGER_CLASS), narrowingToByte); Pair.of(BYTE_TYPE, LONG_CLASS)200 standardConverterMap.put(Pair.of(BYTE_TYPE, LONG_CLASS), narrowingToByte); Pair.of(BYTE_TYPE, BIG_INTEGER_CLASS)201 standardConverterMap.put(Pair.of(BYTE_TYPE, BIG_INTEGER_CLASS), narrowingBigIntegerToByte); Pair.of(BYTE_TYPE, FLOAT_CLASS)202 standardConverterMap.put(Pair.of(BYTE_TYPE, FLOAT_CLASS), narrowingToByte); Pair.of(BYTE_TYPE, DOUBLE_CLASS)203 standardConverterMap.put(Pair.of(BYTE_TYPE, DOUBLE_CLASS), narrowingToByte); Pair.of(BYTE_TYPE, BIG_DECIMAL_CLASS)204 standardConverterMap.put(Pair.of(BYTE_TYPE, BIG_DECIMAL_CLASS), narrowingBigDecimalToByte); Pair.of(BYTE_TYPE, NUMBER_CLASS)205 standardConverterMap.put(Pair.of(BYTE_TYPE, NUMBER_CLASS), narrowingToByte); Pair.of(BYTE_TYPE, SHORT_TYPE)206 standardConverterMap.put(Pair.of(BYTE_TYPE, SHORT_TYPE), narrowingToByte); Pair.of(BYTE_TYPE, INTEGER_TYPE)207 standardConverterMap.put(Pair.of(BYTE_TYPE, INTEGER_TYPE), narrowingToByte); Pair.of(BYTE_TYPE, LONG_TYPE)208 standardConverterMap.put(Pair.of(BYTE_TYPE, LONG_TYPE), narrowingToByte); Pair.of(BYTE_TYPE, FLOAT_TYPE)209 standardConverterMap.put(Pair.of(BYTE_TYPE, FLOAT_TYPE), narrowingToByte); Pair.of(BYTE_TYPE, DOUBLE_TYPE)210 standardConverterMap.put(Pair.of(BYTE_TYPE, DOUBLE_TYPE), narrowingToByte); 211 212 /* string to byte */ 213 214 Converter<Byte> stringToByte = o -> Byte.valueOf(String.valueOf(o)); 215 Pair.of(BYTE_CLASS, STRING_CLASS)216 standardConverterMap.put(Pair.of(BYTE_CLASS, STRING_CLASS), stringToByte); Pair.of(BYTE_TYPE, STRING_CLASS)217 standardConverterMap.put(Pair.of(BYTE_TYPE, STRING_CLASS), stringToByte); 218 219 /* 220 * Conversions towards short 221 */ 222 223 /* narrowing towards short */ 224 225 Converter<Short> narrowingToShort = o -> Optional.ofNullable((Number)o) 226 .filter(n -> checkBounds(n, Short.MIN_VALUE, Short.MAX_VALUE)) 227 .map(Number::shortValue) 228 .orElse(null); 229 230 Converter<Short> narrowingBigIntegerToShort = o -> Optional.ofNullable((BigInteger)o) 231 .map(BigInteger::shortValueExact) 232 .orElse(null); 233 234 Converter<Short> narrowingBigDecimalToShort = o -> Optional.ofNullable((BigDecimal)o) 235 .map(BigDecimal::shortValueExact) 236 .orElse(null); 237 Pair.of(SHORT_CLASS, INTEGER_CLASS)238 standardConverterMap.put(Pair.of(SHORT_CLASS, INTEGER_CLASS), narrowingToShort); Pair.of(SHORT_CLASS, LONG_CLASS)239 standardConverterMap.put(Pair.of(SHORT_CLASS, LONG_CLASS), narrowingToShort); Pair.of(SHORT_CLASS, BIG_INTEGER_CLASS)240 standardConverterMap.put(Pair.of(SHORT_CLASS, BIG_INTEGER_CLASS), narrowingBigIntegerToShort); Pair.of(SHORT_CLASS, FLOAT_CLASS)241 standardConverterMap.put(Pair.of(SHORT_CLASS, FLOAT_CLASS), narrowingToShort); Pair.of(SHORT_CLASS, DOUBLE_CLASS)242 standardConverterMap.put(Pair.of(SHORT_CLASS, DOUBLE_CLASS), narrowingToShort); Pair.of(SHORT_CLASS, BIG_DECIMAL_CLASS)243 standardConverterMap.put(Pair.of(SHORT_CLASS, BIG_DECIMAL_CLASS), narrowingBigDecimalToShort); Pair.of(SHORT_CLASS, NUMBER_CLASS)244 standardConverterMap.put(Pair.of(SHORT_CLASS, NUMBER_CLASS), narrowingToShort); Pair.of(SHORT_CLASS, INTEGER_TYPE)245 standardConverterMap.put(Pair.of(SHORT_CLASS, INTEGER_TYPE), narrowingToShort); Pair.of(SHORT_CLASS, LONG_TYPE)246 standardConverterMap.put(Pair.of(SHORT_CLASS, LONG_TYPE), narrowingToShort); Pair.of(SHORT_CLASS, FLOAT_TYPE)247 standardConverterMap.put(Pair.of(SHORT_CLASS, FLOAT_TYPE), narrowingToShort); Pair.of(SHORT_CLASS, DOUBLE_TYPE)248 standardConverterMap.put(Pair.of(SHORT_CLASS, DOUBLE_TYPE), narrowingToShort); Pair.of(SHORT_TYPE, INTEGER_CLASS)249 standardConverterMap.put(Pair.of(SHORT_TYPE, INTEGER_CLASS), narrowingToShort); Pair.of(SHORT_TYPE, LONG_CLASS)250 standardConverterMap.put(Pair.of(SHORT_TYPE, LONG_CLASS), narrowingToShort); Pair.of(SHORT_TYPE, BIG_INTEGER_CLASS)251 standardConverterMap.put(Pair.of(SHORT_TYPE, BIG_INTEGER_CLASS), narrowingBigIntegerToShort); Pair.of(SHORT_TYPE, FLOAT_CLASS)252 standardConverterMap.put(Pair.of(SHORT_TYPE, FLOAT_CLASS), narrowingToShort); Pair.of(SHORT_TYPE, DOUBLE_CLASS)253 standardConverterMap.put(Pair.of(SHORT_TYPE, DOUBLE_CLASS), narrowingToShort); Pair.of(SHORT_TYPE, BIG_DECIMAL_CLASS)254 standardConverterMap.put(Pair.of(SHORT_TYPE, BIG_DECIMAL_CLASS), narrowingBigDecimalToShort); Pair.of(SHORT_TYPE, NUMBER_CLASS)255 standardConverterMap.put(Pair.of(SHORT_TYPE, NUMBER_CLASS), narrowingToShort); Pair.of(SHORT_TYPE, INTEGER_TYPE)256 standardConverterMap.put(Pair.of(SHORT_TYPE, INTEGER_TYPE), narrowingToShort); Pair.of(SHORT_TYPE, LONG_TYPE)257 standardConverterMap.put(Pair.of(SHORT_TYPE, LONG_TYPE), narrowingToShort); Pair.of(SHORT_TYPE, FLOAT_TYPE)258 standardConverterMap.put(Pair.of(SHORT_TYPE, FLOAT_TYPE), narrowingToShort); Pair.of(SHORT_TYPE, DOUBLE_TYPE)259 standardConverterMap.put(Pair.of(SHORT_TYPE, DOUBLE_TYPE), narrowingToShort); 260 261 /* widening towards short */ 262 263 Converter<Short> wideningToShort = o -> Optional.ofNullable((Number)o) 264 .map(Number::shortValue) 265 .orElse(null); 266 Pair.of(SHORT_CLASS, BYTE_CLASS)267 standardConverterMap.put(Pair.of(SHORT_CLASS, BYTE_CLASS), wideningToShort); Pair.of(SHORT_CLASS, BYTE_TYPE)268 standardConverterMap.put(Pair.of(SHORT_CLASS, BYTE_TYPE), wideningToShort); 269 270 /* string to short */ 271 272 Converter<Short> stringToShort = o -> Short.valueOf(String.valueOf(o)); 273 Pair.of(SHORT_CLASS, STRING_CLASS)274 standardConverterMap.put(Pair.of(SHORT_CLASS, STRING_CLASS), stringToShort); Pair.of(SHORT_TYPE, STRING_CLASS)275 standardConverterMap.put(Pair.of(SHORT_TYPE, STRING_CLASS), stringToShort); 276 277 /* 278 * Conversions towards int 279 */ 280 281 /* narrowing towards int */ 282 283 Converter<Integer> narrowingToInteger = o -> Optional.ofNullable((Number)o) 284 .filter(n -> checkBounds(n, Integer.MIN_VALUE, Integer.MAX_VALUE)) 285 .map(Number::intValue) 286 .orElse(null); 287 288 Converter<Integer> narrowingBigIntegerToInteger = o -> Optional.ofNullable((BigInteger)o) 289 .map(BigInteger::intValueExact) 290 .orElse(null); 291 292 Converter<Integer> narrowingBigDecimalToInteger = o -> Optional.ofNullable((BigDecimal)o) 293 .map(BigDecimal::intValueExact) 294 .orElse(null); 295 Pair.of(INTEGER_CLASS, LONG_CLASS)296 standardConverterMap.put(Pair.of(INTEGER_CLASS, LONG_CLASS), narrowingToInteger); Pair.of(INTEGER_CLASS, BIG_INTEGER_CLASS)297 standardConverterMap.put(Pair.of(INTEGER_CLASS, BIG_INTEGER_CLASS), narrowingBigIntegerToInteger); Pair.of(INTEGER_CLASS, FLOAT_CLASS)298 standardConverterMap.put(Pair.of(INTEGER_CLASS, FLOAT_CLASS), narrowingToInteger); Pair.of(INTEGER_CLASS, DOUBLE_CLASS)299 standardConverterMap.put(Pair.of(INTEGER_CLASS, DOUBLE_CLASS), narrowingToInteger); Pair.of(INTEGER_CLASS, BIG_DECIMAL_CLASS)300 standardConverterMap.put(Pair.of(INTEGER_CLASS, BIG_DECIMAL_CLASS), narrowingBigDecimalToInteger); Pair.of(INTEGER_CLASS, NUMBER_CLASS)301 standardConverterMap.put(Pair.of(INTEGER_CLASS, NUMBER_CLASS), narrowingToInteger); Pair.of(INTEGER_CLASS, LONG_TYPE)302 standardConverterMap.put(Pair.of(INTEGER_CLASS, LONG_TYPE), narrowingToInteger); Pair.of(INTEGER_CLASS, FLOAT_TYPE)303 standardConverterMap.put(Pair.of(INTEGER_CLASS, FLOAT_TYPE), narrowingToInteger); Pair.of(INTEGER_CLASS, DOUBLE_TYPE)304 standardConverterMap.put(Pair.of(INTEGER_CLASS, DOUBLE_TYPE), narrowingToInteger); Pair.of(INTEGER_TYPE, LONG_CLASS)305 standardConverterMap.put(Pair.of(INTEGER_TYPE, LONG_CLASS), narrowingToInteger); Pair.of(INTEGER_TYPE, BIG_INTEGER_CLASS)306 standardConverterMap.put(Pair.of(INTEGER_TYPE, BIG_INTEGER_CLASS), narrowingBigIntegerToInteger); Pair.of(INTEGER_TYPE, FLOAT_CLASS)307 standardConverterMap.put(Pair.of(INTEGER_TYPE, FLOAT_CLASS), narrowingToInteger); Pair.of(INTEGER_TYPE, DOUBLE_CLASS)308 standardConverterMap.put(Pair.of(INTEGER_TYPE, DOUBLE_CLASS), narrowingToInteger); Pair.of(INTEGER_TYPE, BIG_DECIMAL_CLASS)309 standardConverterMap.put(Pair.of(INTEGER_TYPE, BIG_DECIMAL_CLASS), narrowingBigDecimalToInteger); Pair.of(INTEGER_TYPE, NUMBER_CLASS)310 standardConverterMap.put(Pair.of(INTEGER_TYPE, NUMBER_CLASS), narrowingToInteger); Pair.of(INTEGER_TYPE, LONG_TYPE)311 standardConverterMap.put(Pair.of(INTEGER_TYPE, LONG_TYPE), narrowingToInteger); Pair.of(INTEGER_TYPE, FLOAT_TYPE)312 standardConverterMap.put(Pair.of(INTEGER_TYPE, FLOAT_TYPE), narrowingToInteger); Pair.of(INTEGER_TYPE, DOUBLE_TYPE)313 standardConverterMap.put(Pair.of(INTEGER_TYPE, DOUBLE_TYPE), narrowingToInteger); 314 315 /* widening towards int */ 316 317 Converter<Integer> wideningToInteger = o -> Optional.ofNullable((Number)o) 318 .map(Number::intValue) 319 .orElse(null); 320 Pair.of(INTEGER_CLASS, BYTE_CLASS)321 standardConverterMap.put(Pair.of(INTEGER_CLASS, BYTE_CLASS), wideningToInteger); Pair.of(INTEGER_CLASS, SHORT_CLASS)322 standardConverterMap.put(Pair.of(INTEGER_CLASS, SHORT_CLASS), wideningToInteger); Pair.of(INTEGER_CLASS, BYTE_TYPE)323 standardConverterMap.put(Pair.of(INTEGER_CLASS, BYTE_TYPE), wideningToInteger); Pair.of(INTEGER_CLASS, SHORT_TYPE)324 standardConverterMap.put(Pair.of(INTEGER_CLASS, SHORT_TYPE), wideningToInteger); 325 326 /* string to int */ 327 328 Converter<Integer> stringToInteger = o -> Integer.valueOf(String.valueOf(o)); 329 Pair.of(INTEGER_CLASS, STRING_CLASS)330 standardConverterMap.put(Pair.of(INTEGER_CLASS, STRING_CLASS), stringToInteger); Pair.of(INTEGER_TYPE, STRING_CLASS)331 standardConverterMap.put(Pair.of(INTEGER_TYPE, STRING_CLASS), stringToInteger); 332 333 /* 334 * Conversions towards long 335 */ 336 337 /* narrowing towards long */ 338 339 Converter<Long> narrowingToLong = o -> Optional.ofNullable((Number)o) 340 .filter(n -> checkBounds(n, Long.MIN_VALUE, Long.MAX_VALUE)) 341 .map(Number::longValue) 342 .orElse(null); 343 344 Converter<Long> narrowingBigIntegerToLong = o -> Optional.ofNullable((BigInteger)o) 345 .map(BigInteger::longValueExact) 346 .orElse(null); 347 348 Converter<Long> narrowingBigDecimalToLong = o -> Optional.ofNullable((BigDecimal)o) 349 .map(BigDecimal::longValueExact) 350 .orElse(null); 351 Pair.of(LONG_CLASS, BIG_INTEGER_CLASS)352 standardConverterMap.put(Pair.of(LONG_CLASS, BIG_INTEGER_CLASS), narrowingBigIntegerToLong); Pair.of(LONG_CLASS, FLOAT_CLASS)353 standardConverterMap.put(Pair.of(LONG_CLASS, FLOAT_CLASS), narrowingToLong); Pair.of(LONG_CLASS, DOUBLE_CLASS)354 standardConverterMap.put(Pair.of(LONG_CLASS, DOUBLE_CLASS), narrowingToLong); Pair.of(LONG_CLASS, BIG_DECIMAL_CLASS)355 standardConverterMap.put(Pair.of(LONG_CLASS, BIG_DECIMAL_CLASS), narrowingBigDecimalToLong); Pair.of(LONG_CLASS, NUMBER_CLASS)356 standardConverterMap.put(Pair.of(LONG_CLASS, NUMBER_CLASS), narrowingToLong); Pair.of(LONG_CLASS, FLOAT_TYPE)357 standardConverterMap.put(Pair.of(LONG_CLASS, FLOAT_TYPE), narrowingToLong); Pair.of(LONG_CLASS, DOUBLE_TYPE)358 standardConverterMap.put(Pair.of(LONG_CLASS, DOUBLE_TYPE), narrowingToLong); Pair.of(LONG_TYPE, BIG_INTEGER_CLASS)359 standardConverterMap.put(Pair.of(LONG_TYPE, BIG_INTEGER_CLASS), narrowingBigIntegerToLong); Pair.of(LONG_TYPE, FLOAT_CLASS)360 standardConverterMap.put(Pair.of(LONG_TYPE, FLOAT_CLASS), narrowingToLong); Pair.of(LONG_TYPE, DOUBLE_CLASS)361 standardConverterMap.put(Pair.of(LONG_TYPE, DOUBLE_CLASS), narrowingToLong); Pair.of(LONG_TYPE, BIG_DECIMAL_CLASS)362 standardConverterMap.put(Pair.of(LONG_TYPE, BIG_DECIMAL_CLASS), narrowingBigDecimalToLong); Pair.of(LONG_TYPE, NUMBER_CLASS)363 standardConverterMap.put(Pair.of(LONG_TYPE, NUMBER_CLASS), narrowingToLong); Pair.of(LONG_TYPE, FLOAT_TYPE)364 standardConverterMap.put(Pair.of(LONG_TYPE, FLOAT_TYPE), narrowingToLong); Pair.of(LONG_TYPE, DOUBLE_TYPE)365 standardConverterMap.put(Pair.of(LONG_TYPE, DOUBLE_TYPE), narrowingToLong); 366 367 /* widening towards long */ 368 369 Converter<Long> wideningToLong = o -> Optional.ofNullable((Number)o) 370 .map(Number::longValue) 371 .orElse(null); 372 Pair.of(LONG_CLASS, BYTE_CLASS)373 standardConverterMap.put(Pair.of(LONG_CLASS, BYTE_CLASS), wideningToLong); Pair.of(LONG_CLASS, SHORT_CLASS)374 standardConverterMap.put(Pair.of(LONG_CLASS, SHORT_CLASS), wideningToLong); Pair.of(LONG_CLASS, INTEGER_CLASS)375 standardConverterMap.put(Pair.of(LONG_CLASS, INTEGER_CLASS), wideningToLong); Pair.of(LONG_CLASS, BYTE_TYPE)376 standardConverterMap.put(Pair.of(LONG_CLASS, BYTE_TYPE), wideningToLong); Pair.of(LONG_CLASS, SHORT_TYPE)377 standardConverterMap.put(Pair.of(LONG_CLASS, SHORT_TYPE), wideningToLong); Pair.of(LONG_CLASS, INTEGER_TYPE)378 standardConverterMap.put(Pair.of(LONG_CLASS, INTEGER_TYPE), wideningToLong); 379 380 /* string to long */ 381 382 Converter<Long> stringToLong = o -> Long.valueOf(String.valueOf(o)); 383 Pair.of(LONG_CLASS, STRING_CLASS)384 standardConverterMap.put(Pair.of(LONG_CLASS, STRING_CLASS), stringToLong); Pair.of(LONG_TYPE, STRING_CLASS)385 standardConverterMap.put(Pair.of(LONG_TYPE, STRING_CLASS), stringToLong); 386 387 /* 388 * Conversions towards BigInteger 389 */ 390 391 /* exact types towards BigInteger */ 392 393 Converter<BigInteger> toBigInteger = o -> Optional.ofNullable((Number)o) 394 .map(n -> BigInteger.valueOf(n.longValue())) 395 .orElse(null); 396 Pair.of(BIG_INTEGER_CLASS, BYTE_CLASS)397 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, BYTE_CLASS), toBigInteger); Pair.of(BIG_INTEGER_CLASS, SHORT_CLASS)398 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, SHORT_CLASS), toBigInteger); Pair.of(BIG_INTEGER_CLASS, INTEGER_CLASS)399 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, INTEGER_CLASS), toBigInteger); Pair.of(BIG_INTEGER_CLASS, LONG_CLASS)400 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, LONG_CLASS), toBigInteger); Pair.of(BIG_INTEGER_CLASS, BYTE_TYPE)401 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, BYTE_TYPE), toBigInteger); Pair.of(BIG_INTEGER_CLASS, SHORT_TYPE)402 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, SHORT_TYPE), toBigInteger); Pair.of(BIG_INTEGER_CLASS, INTEGER_TYPE)403 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, INTEGER_TYPE), toBigInteger); Pair.of(BIG_INTEGER_CLASS, LONG_TYPE)404 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, LONG_TYPE), toBigInteger); 405 406 /* approximate types towards BigInteger */ 407 408 /* It makes no sense trying to convert from float or double towards BigInteger 409 if we do care about precision loss.. 410 */ 411 412 Converter<BigInteger> bigDecimalToBigInteger = o -> Optional.ofNullable((BigDecimal)o) 413 .map(BigDecimal::toBigIntegerExact) 414 .orElse(null); 415 Pair.of(BIG_INTEGER_CLASS, BIG_DECIMAL_CLASS)416 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, BIG_DECIMAL_CLASS), bigDecimalToBigInteger); 417 418 /* string to BigInteger */ 419 420 Converter<BigInteger> stringToBigInteger = o -> Optional.ofNullable(o) 421 .map(s -> new BigInteger(String.valueOf(s))) 422 .orElse(null); 423 Pair.of(BIG_INTEGER_CLASS, STRING_CLASS)424 standardConverterMap.put(Pair.of(BIG_INTEGER_CLASS, STRING_CLASS), stringToBigInteger); 425 426 /* 427 * Conversions towards float 428 */ 429 430 Converter<Float> toFloat = o -> Optional.ofNullable((Number)o) 431 .map(Number::floatValue) 432 .orElse(null); 433 434 /* narrowing towards float */ 435 Pair.of(FLOAT_CLASS, BIG_INTEGER_CLASS)436 standardConverterMap.put(Pair.of(FLOAT_CLASS, BIG_INTEGER_CLASS), toFloat); Pair.of(FLOAT_CLASS, DOUBLE_CLASS)437 standardConverterMap.put(Pair.of(FLOAT_CLASS, DOUBLE_CLASS), toFloat); Pair.of(FLOAT_CLASS, BIG_DECIMAL_CLASS)438 standardConverterMap.put(Pair.of(FLOAT_CLASS, BIG_DECIMAL_CLASS), toFloat); Pair.of(FLOAT_CLASS, NUMBER_CLASS)439 standardConverterMap.put(Pair.of(FLOAT_CLASS, NUMBER_CLASS), toFloat); Pair.of(FLOAT_CLASS, DOUBLE_TYPE)440 standardConverterMap.put(Pair.of(FLOAT_CLASS, DOUBLE_TYPE), toFloat); Pair.of(FLOAT_TYPE, BIG_INTEGER_CLASS)441 standardConverterMap.put(Pair.of(FLOAT_TYPE, BIG_INTEGER_CLASS), toFloat); Pair.of(FLOAT_TYPE, DOUBLE_CLASS)442 standardConverterMap.put(Pair.of(FLOAT_TYPE, DOUBLE_CLASS), toFloat); Pair.of(FLOAT_TYPE, BIG_DECIMAL_CLASS)443 standardConverterMap.put(Pair.of(FLOAT_TYPE, BIG_DECIMAL_CLASS), toFloat); Pair.of(FLOAT_TYPE, NUMBER_CLASS)444 standardConverterMap.put(Pair.of(FLOAT_TYPE, NUMBER_CLASS), toFloat); Pair.of(FLOAT_TYPE, DOUBLE_TYPE)445 standardConverterMap.put(Pair.of(FLOAT_TYPE, DOUBLE_TYPE), toFloat); 446 447 /* exact types towards float */ 448 Pair.of(FLOAT_CLASS, BYTE_CLASS)449 standardConverterMap.put(Pair.of(FLOAT_CLASS, BYTE_CLASS), toFloat); Pair.of(FLOAT_CLASS, SHORT_CLASS)450 standardConverterMap.put(Pair.of(FLOAT_CLASS, SHORT_CLASS), toFloat); Pair.of(FLOAT_CLASS, INTEGER_CLASS)451 standardConverterMap.put(Pair.of(FLOAT_CLASS, INTEGER_CLASS), toFloat); Pair.of(FLOAT_CLASS, LONG_CLASS)452 standardConverterMap.put(Pair.of(FLOAT_CLASS, LONG_CLASS), toFloat); Pair.of(FLOAT_CLASS, BYTE_TYPE)453 standardConverterMap.put(Pair.of(FLOAT_CLASS, BYTE_TYPE), toFloat); Pair.of(FLOAT_CLASS, SHORT_TYPE)454 standardConverterMap.put(Pair.of(FLOAT_CLASS, SHORT_TYPE), toFloat); Pair.of(FLOAT_CLASS, INTEGER_TYPE)455 standardConverterMap.put(Pair.of(FLOAT_CLASS, INTEGER_TYPE), toFloat); Pair.of(FLOAT_CLASS, LONG_TYPE)456 standardConverterMap.put(Pair.of(FLOAT_CLASS, LONG_TYPE), toFloat); 457 458 /* string to float */ 459 460 Converter<Float> stringToFloat = o -> Float.valueOf(String.valueOf(o)); 461 Pair.of(FLOAT_CLASS, STRING_CLASS)462 standardConverterMap.put(Pair.of(FLOAT_CLASS, STRING_CLASS), stringToFloat); Pair.of(FLOAT_TYPE, STRING_CLASS)463 standardConverterMap.put(Pair.of(FLOAT_TYPE, STRING_CLASS), stringToFloat); 464 465 /* 466 * Conversions towards double 467 */ 468 469 Converter<Double> toDouble = o -> Optional.ofNullable((Number)o) 470 .map(Number::doubleValue) 471 .orElse(null); 472 473 /* narrowing towards double */ 474 Pair.of(DOUBLE_CLASS, BIG_INTEGER_CLASS)475 standardConverterMap.put(Pair.of(DOUBLE_CLASS, BIG_INTEGER_CLASS), toDouble); Pair.of(DOUBLE_CLASS, BIG_DECIMAL_CLASS)476 standardConverterMap.put(Pair.of(DOUBLE_CLASS, BIG_DECIMAL_CLASS), toDouble); Pair.of(DOUBLE_TYPE, BIG_INTEGER_CLASS)477 standardConverterMap.put(Pair.of(DOUBLE_TYPE, BIG_INTEGER_CLASS), toDouble); Pair.of(DOUBLE_TYPE, BIG_DECIMAL_CLASS)478 standardConverterMap.put(Pair.of(DOUBLE_TYPE, BIG_DECIMAL_CLASS), toDouble); 479 480 /* exact types or widening towards double */ 481 Pair.of(DOUBLE_CLASS, BYTE_CLASS)482 standardConverterMap.put(Pair.of(DOUBLE_CLASS, BYTE_CLASS), toDouble); Pair.of(DOUBLE_CLASS, SHORT_CLASS)483 standardConverterMap.put(Pair.of(DOUBLE_CLASS, SHORT_CLASS), toDouble); Pair.of(DOUBLE_CLASS, INTEGER_CLASS)484 standardConverterMap.put(Pair.of(DOUBLE_CLASS, INTEGER_CLASS), toDouble); Pair.of(DOUBLE_CLASS, LONG_CLASS)485 standardConverterMap.put(Pair.of(DOUBLE_CLASS, LONG_CLASS), toDouble); Pair.of(DOUBLE_CLASS, FLOAT_CLASS)486 standardConverterMap.put(Pair.of(DOUBLE_CLASS, FLOAT_CLASS), toDouble); Pair.of(DOUBLE_CLASS, NUMBER_CLASS)487 standardConverterMap.put(Pair.of(DOUBLE_CLASS, NUMBER_CLASS), toDouble); Pair.of(DOUBLE_CLASS, BYTE_TYPE)488 standardConverterMap.put(Pair.of(DOUBLE_CLASS, BYTE_TYPE), toDouble); Pair.of(DOUBLE_CLASS, SHORT_TYPE)489 standardConverterMap.put(Pair.of(DOUBLE_CLASS, SHORT_TYPE), toDouble); Pair.of(DOUBLE_CLASS, INTEGER_TYPE)490 standardConverterMap.put(Pair.of(DOUBLE_CLASS, INTEGER_TYPE), toDouble); Pair.of(DOUBLE_CLASS, LONG_TYPE)491 standardConverterMap.put(Pair.of(DOUBLE_CLASS, LONG_TYPE), toDouble); Pair.of(DOUBLE_CLASS, FLOAT_TYPE)492 standardConverterMap.put(Pair.of(DOUBLE_CLASS, FLOAT_TYPE), toDouble); Pair.of(DOUBLE_TYPE, NUMBER_CLASS)493 standardConverterMap.put(Pair.of(DOUBLE_TYPE, NUMBER_CLASS), toDouble); 494 495 /* string to double */ 496 497 Converter<Double> stringToDouble = o -> Double.valueOf(String.valueOf(o)); 498 Pair.of(DOUBLE_CLASS, STRING_CLASS)499 standardConverterMap.put(Pair.of(DOUBLE_CLASS, STRING_CLASS), stringToDouble); Pair.of(DOUBLE_TYPE, STRING_CLASS)500 standardConverterMap.put(Pair.of(DOUBLE_TYPE, STRING_CLASS), stringToDouble); 501 502 /* 503 * Conversions towards BigDecimal 504 */ 505 506 /* exact types towards BigDecimal */ 507 508 Converter<BigDecimal> exactToBigDecimal = o -> Optional.ofNullable((Number)o) 509 .map(n -> BigDecimal.valueOf(n.longValue())) 510 .orElse(null); 511 512 Converter<BigDecimal> bigIntegerToBigDecimal = o -> Optional.ofNullable((BigInteger)o) 513 .map(bi -> new BigDecimal(bi)) 514 .orElse(null); 515 Pair.of(BIG_DECIMAL_CLASS, BYTE_CLASS)516 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, BYTE_CLASS), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, SHORT_CLASS)517 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, SHORT_CLASS), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, INTEGER_CLASS)518 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, INTEGER_CLASS), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, LONG_CLASS)519 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, LONG_CLASS), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, BIG_INTEGER_CLASS)520 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, BIG_INTEGER_CLASS), bigIntegerToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, BYTE_TYPE)521 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, BYTE_TYPE), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, SHORT_TYPE)522 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, SHORT_TYPE), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, INTEGER_TYPE)523 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, INTEGER_TYPE), exactToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, LONG_TYPE)524 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, LONG_TYPE), exactToBigDecimal); 525 526 /* approximate types towards BigDecimal */ 527 528 Converter<BigDecimal> approxToBigDecimal = o -> Optional.ofNullable((Number)o) 529 .map(n -> BigDecimal.valueOf(n.doubleValue())) 530 .orElse(null); 531 Pair.of(BIG_DECIMAL_CLASS, FLOAT_CLASS)532 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, FLOAT_CLASS), approxToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, DOUBLE_CLASS)533 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, DOUBLE_CLASS), approxToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, FLOAT_TYPE)534 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, FLOAT_TYPE), approxToBigDecimal); Pair.of(BIG_DECIMAL_CLASS, DOUBLE_TYPE)535 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, DOUBLE_TYPE), approxToBigDecimal); 536 537 /* string to BigDecimal */ 538 539 Converter<BigDecimal> stringToBigDecimal = o -> Optional.ofNullable(o) 540 .map(s -> new BigDecimal(String.valueOf(s))) 541 .orElse(null); 542 Pair.of(BIG_DECIMAL_CLASS, STRING_CLASS)543 standardConverterMap.put(Pair.of(BIG_DECIMAL_CLASS, STRING_CLASS), stringToBigDecimal); 544 545 /* 546 * Conversions from boolean to numeric type 547 */ 548 549 /* boolean to byte */ 550 551 Converter<Byte> booleanToByte = o -> Optional.ofNullable((Boolean)o) 552 .map(b -> b ? (byte)1 : (byte)0) 553 .orElse(null); 554 Pair.of(BYTE_CLASS, BOOLEAN_CLASS)555 standardConverterMap.put(Pair.of(BYTE_CLASS, BOOLEAN_CLASS), booleanToByte); Pair.of(BYTE_CLASS, BOOLEAN_TYPE)556 standardConverterMap.put(Pair.of(BYTE_CLASS, BOOLEAN_TYPE), booleanToByte); Pair.of(BYTE_TYPE, BOOLEAN_CLASS)557 standardConverterMap.put(Pair.of(BYTE_TYPE, BOOLEAN_CLASS), booleanToByte); Pair.of(BYTE_TYPE, BOOLEAN_TYPE)558 standardConverterMap.put(Pair.of(BYTE_TYPE, BOOLEAN_TYPE), booleanToByte); 559 560 /* boolean to short */ 561 562 Converter<Short> booleanToShort = o -> Optional.ofNullable((Boolean)o) 563 .map(b -> b ? (short)1 : (short)0) 564 .orElse(null); 565 Pair.of(SHORT_CLASS, BOOLEAN_CLASS)566 standardConverterMap.put(Pair.of(SHORT_CLASS, BOOLEAN_CLASS), booleanToShort); Pair.of(SHORT_CLASS, BOOLEAN_TYPE)567 standardConverterMap.put(Pair.of(SHORT_CLASS, BOOLEAN_TYPE), booleanToShort); Pair.of(SHORT_TYPE, BOOLEAN_CLASS)568 standardConverterMap.put(Pair.of(SHORT_TYPE, BOOLEAN_CLASS), booleanToShort); Pair.of(SHORT_TYPE, BOOLEAN_TYPE)569 standardConverterMap.put(Pair.of(SHORT_TYPE, BOOLEAN_TYPE), booleanToShort); 570 571 /* boolean to integer */ 572 573 Converter<Integer> booleanToInteger = o -> Optional.ofNullable((Boolean)o) 574 .map(b -> b ? (int)1 : (int)0) 575 .orElse(null); 576 Pair.of(INTEGER_CLASS, BOOLEAN_CLASS)577 standardConverterMap.put(Pair.of(INTEGER_CLASS, BOOLEAN_CLASS), booleanToInteger); Pair.of(INTEGER_CLASS, BOOLEAN_TYPE)578 standardConverterMap.put(Pair.of(INTEGER_CLASS, BOOLEAN_TYPE), booleanToInteger); Pair.of(INTEGER_TYPE, BOOLEAN_CLASS)579 standardConverterMap.put(Pair.of(INTEGER_TYPE, BOOLEAN_CLASS), booleanToInteger); Pair.of(INTEGER_TYPE, BOOLEAN_TYPE)580 standardConverterMap.put(Pair.of(INTEGER_TYPE, BOOLEAN_TYPE), booleanToInteger); 581 582 /* boolean to long */ 583 584 Converter<Long> booleanToLong = o -> Optional.ofNullable((Boolean)o) 585 .map(b -> b ? 1l : 0l) 586 .orElse(null); 587 Pair.of(LONG_CLASS, BOOLEAN_CLASS)588 standardConverterMap.put(Pair.of(LONG_CLASS, BOOLEAN_CLASS), booleanToLong); Pair.of(LONG_CLASS, BOOLEAN_TYPE)589 standardConverterMap.put(Pair.of(LONG_CLASS, BOOLEAN_TYPE), booleanToLong); Pair.of(LONG_TYPE, BOOLEAN_CLASS)590 standardConverterMap.put(Pair.of(LONG_TYPE, BOOLEAN_CLASS), booleanToLong); Pair.of(LONG_TYPE, BOOLEAN_TYPE)591 standardConverterMap.put(Pair.of(LONG_TYPE, BOOLEAN_TYPE), booleanToLong); 592 593 /* to string */ 594 595 toString = o -> String.valueOf(o); 596 597 /* string to locale */ 598 Converter<Locale> stringToLocale = o -> Optional.ofNullable(o) 599 .map(l -> LocaleUtils.toLocale(String.valueOf(l))) 600 .orElse(null); 601 Pair.of(LOCALE_CLASS, STRING_CLASS)602 standardConverterMap.put(Pair.of(LOCALE_CLASS, STRING_CLASS), stringToLocale); 603 } 604 605 /** 606 * Constructor 607 */ TypeConversionHandlerImpl()608 public TypeConversionHandlerImpl() 609 { 610 converterCacheMap = new ConcurrentHashMap<>(); 611 } 612 613 /** 614 * Check to see if the conversion can be done using an explicit conversion 615 * @param actual found argument type 616 * @param formal expected formal type 617 * @return true if actual class can be explicitely converted to expected formal type 618 * @since 2.1 619 */ 620 @Override isExplicitlyConvertible(Type formal, Class<?> actual, boolean possibleVarArg)621 public boolean isExplicitlyConvertible(Type formal, Class<?> actual, boolean possibleVarArg) 622 { 623 /* 624 * for consistency, we also have to check standard implicit convertibility 625 * since it may not have been checked before by the calling code 626 */ 627 Class<?> formalClass = IntrospectionUtils.getTypeClass(formal); 628 if (formalClass != null && formalClass == actual || 629 IntrospectionUtils.isMethodInvocationConvertible(formal, actual, possibleVarArg) || 630 getNeededConverter(formal, actual) != null) 631 { 632 return true; 633 } 634 635 /* Check var arg */ 636 if (possibleVarArg && TypeUtils.isArrayType(formal)) 637 { 638 if (actual.isArray()) 639 { 640 actual = actual.getComponentType(); 641 } 642 return isExplicitlyConvertible(TypeUtils.getArrayComponentType(formal), actual, false); 643 } 644 return false; 645 } 646 647 648 /** 649 * Returns the appropriate Converter object needed for an explicit conversion 650 * Returns null if no conversion is needed. 651 * 652 * @param actual found argument type 653 * @param formal expected formal type 654 * @return null if no conversion is needed, or the appropriate Converter object 655 * @since 2.1 656 */ 657 @Override getNeededConverter(Type formal, Class<?> actual)658 public Converter<?> getNeededConverter(Type formal, Class<?> actual) 659 { 660 if (actual == null) 661 { 662 return null; 663 } 664 Pair<String, String> key = Pair.of(formal.getTypeName(), actual.getTypeName()); 665 666 /* first check for a standard conversion */ 667 Converter<?> converter = standardConverterMap.get(key); 668 if (converter == null) 669 { 670 /* then the converters cache map */ 671 converter = converterCacheMap.get(key); 672 if (converter == null) 673 { 674 Class<?> formalClass = IntrospectionUtils.getTypeClass(formal); 675 /* check for conversion towards string */ 676 if (formal == String.class) 677 { 678 converter = toString; 679 } 680 /* check for String -> Enum constant conversion */ 681 else if (formalClass != null && formalClass.isEnum() && actual == String.class) 682 { 683 final Class<Enum> enumClass = (Class<Enum>)formalClass; 684 converter = o -> Enum.valueOf(enumClass, (String)o); 685 } 686 687 converterCacheMap.put(key, converter == null ? cacheMiss : converter); 688 } 689 } 690 return converter == cacheMiss ? null : converter; 691 } 692 693 /** 694 * Add the given converter to the handler. 695 * 696 * @param formal expected formal type 697 * @param actual provided argument type 698 * @param converter converter 699 * @since 2.1 700 */ 701 @Override addConverter(Type formal, Class<?> actual, Converter<?> converter)702 public void addConverter(Type formal, Class<?> actual, Converter<?> converter) 703 { 704 Pair<String, String> key = Pair.of(formal.getTypeName(), actual.getTypeName()); 705 converterCacheMap.put(key, converter); 706 Class<?> formalClass = IntrospectionUtils.getTypeClass(formal); 707 if (formalClass != null) 708 { 709 if (formalClass.isPrimitive()) 710 { 711 key = Pair.of(IntrospectionUtils.getBoxedClass(formalClass).getTypeName(), actual.getTypeName()); 712 converterCacheMap.put(key, converter); 713 } 714 else 715 { 716 Class<?> unboxedFormal = IntrospectionUtils.getUnboxedClass(formalClass); 717 if (unboxedFormal != formalClass) 718 { 719 key = Pair.of(unboxedFormal.getTypeName(), actual.getTypeName()); 720 converterCacheMap.put(key, converter); 721 } 722 } 723 } 724 } 725 } 726