001/** 002 * Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com). 003 * <p> 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 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 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 */ 016package com.mybatisflex.core.util; 017 018import java.math.BigDecimal; 019import java.math.BigInteger; 020import java.time.LocalDate; 021import java.time.LocalDateTime; 022import java.time.LocalTime; 023import java.time.temporal.Temporal; 024import java.util.Date; 025 026public class ConvertUtil { 027 028 029 public static Object convert(Object value, Class<?> targetClass) { 030 if (value == null && targetClass.isPrimitive()) { 031 return getPrimitiveDefaultValue(targetClass); 032 } 033 if (value == null || (targetClass != String.class && value.getClass() == String.class 034 && StringUtil.isBlank((String) value))) { 035 return null; 036 } 037 if (value.getClass().isAssignableFrom(targetClass)) { 038 return value; 039 } 040 if (targetClass == String.class) { 041 return value.toString(); 042 } else if (targetClass == Integer.class || targetClass == int.class) { 043 if (value instanceof Number) { 044 return ((Number) value).intValue(); 045 } 046 return Integer.parseInt(value.toString()); 047 } else if (targetClass == Long.class || targetClass == long.class) { 048 if (value instanceof Number) { 049 return ((Number) value).longValue(); 050 } 051 return Long.parseLong(value.toString()); 052 } else if (targetClass == Double.class || targetClass == double.class) { 053 if (value instanceof Number) { 054 return ((Number) value).doubleValue(); 055 } 056 return Double.parseDouble(value.toString()); 057 } else if (targetClass == Float.class || targetClass == float.class) { 058 if (value instanceof Number) { 059 return ((Number) value).floatValue(); 060 } 061 return Float.parseFloat(value.toString()); 062 } else if (targetClass == Boolean.class || targetClass == boolean.class) { 063 String v = value.toString().toLowerCase(); 064 if ("1".equals(v) || "true".equalsIgnoreCase(v)) { 065 return Boolean.TRUE; 066 } else if ("0".equals(v) || "false".equalsIgnoreCase(v)) { 067 return Boolean.FALSE; 068 } else { 069 throw new RuntimeException("Can not parse to boolean type of value: \"" + value + "\""); 070 } 071 } else if (targetClass == java.math.BigDecimal.class) { 072 return new java.math.BigDecimal(value.toString()); 073 } else if (targetClass == java.math.BigInteger.class) { 074 return new java.math.BigInteger(value.toString()); 075 } else if (targetClass == byte[].class) { 076 return value.toString().getBytes(); 077 } else if (targetClass == Date.class) { 078 return DateUtil.parseDate(value); 079 } else if (targetClass == LocalDateTime.class) { 080 return toLocalDateTime(value); 081 } else if (targetClass == LocalDate.class) { 082 return DateUtil.toLocalDate(DateUtil.parseDate(value)); 083 } else if (targetClass == LocalTime.class) { 084 return DateUtil.toLocalTime(DateUtil.parseDate(value)); 085 } else if (targetClass == Short.class || targetClass == short.class) { 086 if (value instanceof Number) { 087 return ((Number) value).shortValue(); 088 } 089 return Short.parseShort(value.toString()); 090 } 091 092 throw new IllegalArgumentException("\"" + targetClass.getName() + "\" can not be parsed."); 093 } 094 095 096 //Boolean.TYPE, Character.TYPE, Byte.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE 097 public static Object getPrimitiveDefaultValue(Class<?> paraClass) { 098 if (paraClass == int.class || paraClass == long.class || paraClass == float.class || paraClass == double.class) { 099 return 0; 100 } else if (paraClass == boolean.class) { 101 return Boolean.FALSE; 102 } else if (paraClass == short.class) { 103 return (short) 0; 104 } else if (paraClass == byte.class) { 105 return (byte) 0; 106 } else if (paraClass == char.class) { 107 return '\u0000'; 108 } else { 109 throw new IllegalArgumentException("Can not get primitive default value for type: " + paraClass); 110 } 111 } 112 113 114 public static Integer toInt(Object i) { 115 if (i instanceof Integer) { 116 return (Integer) i; 117 } else if (i instanceof Number) { 118 return ((Number) i).intValue(); 119 } 120 return i != null ? Integer.parseInt(i.toString()) : null; 121 } 122 123 public static Long toLong(Object l) { 124 if (l instanceof Long) { 125 return (Long) l; 126 } else if (l instanceof Number) { 127 return ((Number) l).longValue(); 128 } 129 return l != null ? Long.parseLong(l.toString()) : null; 130 } 131 132 public static Double toDouble(Object d) { 133 if (d instanceof Double) { 134 return (Double) d; 135 } else if (d instanceof Number) { 136 return ((Number) d).doubleValue(); 137 } 138 139 return d != null ? Double.parseDouble(d.toString()) : null; 140 } 141 142 public static BigDecimal toBigDecimal(Object b) { 143 if (b instanceof BigDecimal) { 144 return (BigDecimal) b; 145 } else if (b != null) { 146 return new BigDecimal(b.toString()); 147 } else { 148 return null; 149 } 150 } 151 152 public static BigInteger toBigInteger(Object b) { 153 if (b instanceof BigInteger) { 154 return (BigInteger)b; 155 } 156 // 数据类型 id(19 number)在 Oracle Jdbc 下对应的是 BigDecimal, 157 // 但是在 MySql 下对应的是 BigInteger,这会导致在 MySql 下生成的代码无法在 Oracle 数据库中使用 158 if (b instanceof BigDecimal) { 159 return ((BigDecimal)b).toBigInteger(); 160 } else if (b instanceof Number) { 161 return BigInteger.valueOf(((Number)b).longValue()); 162 } else if (b instanceof String) { 163 return new BigInteger((String)b); 164 } 165 166 return (BigInteger)b; 167 } 168 169 public static Float toFloat(Object f) { 170 if (f instanceof Float) { 171 return (Float) f; 172 } else if (f instanceof Number) { 173 return ((Number) f).floatValue(); 174 } 175 return f != null ? Float.parseFloat(f.toString()) : null; 176 } 177 178 179 public static Short toShort(Object s) { 180 if (s instanceof Short) { 181 return (Short) s; 182 } else if (s instanceof Number) { 183 return ((Number) s).shortValue(); 184 } 185 return s != null ? Short.parseShort(s.toString()) : null; 186 } 187 188 189 public static Byte toByte(Object b) { 190 if (b instanceof Byte) { 191 return (Byte) b; 192 } else if (b instanceof Number) { 193 return ((Number) b).byteValue(); 194 } 195 return b != null ? Byte.parseByte(b.toString()) : null; 196 } 197 198 public static Boolean toBoolean(Object b) { 199 if (b instanceof Boolean) { 200 return (Boolean) b; 201 } else if (b == null) { 202 return null; 203 } 204 205 // 支持 Number 之下的整数类型 206 if (b instanceof Number) { 207 int n = ((Number) b).intValue(); 208 if (n == 1) { 209 return Boolean.TRUE; 210 } else if (n == 0) { 211 return Boolean.FALSE; 212 } 213 throw new IllegalArgumentException("Can not support convert: \"" + b + "\" to boolean."); 214 } 215 216 // 支持 String 217 if (b instanceof String) { 218 String s = b.toString(); 219 if ("true".equalsIgnoreCase(s) || "1".equals(s)) { 220 return Boolean.TRUE; 221 } else if ("false".equalsIgnoreCase(s) || "0".equals(s)) { 222 return Boolean.FALSE; 223 } 224 } 225 226 return (Boolean) b; 227 } 228 229 public static Number toNumber(Object o) { 230 if (o instanceof Number) { 231 return (Number) o; 232 } else if (o == null) { 233 return null; 234 } 235 String s = o.toString(); 236 return s.indexOf('.') != -1 ? Double.parseDouble(s) : Long.parseLong(s); 237 } 238 239 240 public static Date toDate(Object o) { 241 if (o instanceof Date) { 242 return (Date) o; 243 } 244 245 if (o instanceof Temporal) { 246 if (o instanceof LocalDateTime) { 247 return DateUtil.toDate((LocalDateTime) o); 248 } 249 if (o instanceof LocalDate) { 250 return DateUtil.toDate((LocalDate) o); 251 } 252 if (o instanceof LocalTime) { 253 return DateUtil.toDate((LocalTime) o); 254 } 255 } 256 257 if (o instanceof String) { 258 String s = (String) o; 259 return DateUtil.parseDate(s); 260 } 261 262 return (java.util.Date) o; 263 } 264 265 266 public static LocalDateTime toLocalDateTime(Object o) { 267 if (o instanceof LocalDateTime) { 268 return (LocalDateTime) o; 269 } 270 if (o instanceof java.util.Date) { 271 return DateUtil.toLocalDateTime((java.util.Date) o); 272 } 273 if (o instanceof LocalDate) { 274 return ((LocalDate) o).atStartOfDay(); 275 } 276 if (o instanceof LocalTime) { 277 return LocalDateTime.of(LocalDate.now(), (LocalTime) o); 278 } 279 280 if (o instanceof String) { 281 String s = (String) o; 282 return DateUtil.parseLocalDateTime(s); 283 } 284 285 return (LocalDateTime) o; 286 } 287}