001package net.gdface.utils; 002 003import java.lang.reflect.Array; 004import java.net.MalformedURLException; 005import java.net.URI; 006import java.net.URL; 007import java.nio.ByteBuffer; 008import java.util.Arrays; 009import java.util.Date; 010import java.util.List; 011import java.util.Map; 012import java.util.Map.Entry; 013import java.util.Set; 014 015import com.google.common.base.Function; 016import com.google.common.collect.HashBasedTable; 017import com.google.common.collect.ImmutableMap; 018import com.google.common.collect.Iterables; 019import com.google.common.collect.Lists; 020import com.google.common.collect.Maps; 021import com.google.common.collect.Maps.EntryTransformer; 022import com.google.common.collect.Sets; 023import com.google.common.collect.Table; 024import com.google.common.primitives.Booleans; 025import com.google.common.primitives.Doubles; 026import com.google.common.primitives.Floats; 027import com.google.common.primitives.Ints; 028import com.google.common.primitives.Longs; 029import com.google.common.primitives.Shorts; 030 031import static com.google.common.base.Preconditions.*; 032/** 033 * 类型转æ¢å·¥å…·ç±» 034 * @author guyadong 035 * @deprecated be replaced by {@link BaseTypeTransformer} 036 * 037 */ 038public class TypeTransformer { 039 /** 040 * 返回buffer䏿‰€æœ‰å—节(position~limit),䏿”¹å˜bufferçŠ¶æ€ 041 * @param buffer 042 * @return buffer 为 null 时返回 null 043 */ 044 public static final byte[] getBytesInBuffer(ByteBuffer buffer){ 045 if(null == buffer){ 046 return null; 047 } 048 int pos = buffer.position(); 049 try{ 050 byte[] bytes = new byte[buffer.remaining()]; 051 buffer.get(bytes); 052 return bytes; 053 }finally{ 054 buffer.position(pos); 055 } 056 } 057 @SuppressWarnings("rawtypes") 058 private final Function sameTypeFun = new Function(){ 059 @Override 060 public Object apply(Object input) { 061 return input; 062 }}; 063 private final Function<byte[],ByteBuffer> byteArray2ByteBufferFun = new Function<byte[],ByteBuffer>(){ 064 @Override 065 public ByteBuffer apply(byte[] input) { 066 return null == input ? null :ByteBuffer.wrap(input); 067 }}; 068 private final Function<ByteBuffer,byte[]> byteBuffer2ByteArrayFun = new Function<ByteBuffer,byte[]>(){ 069 @Override 070 public byte[] apply(ByteBuffer input) { 071 return getBytesInBuffer(input); 072 }}; 073 private final Function<Float,Double> float2DoubleFun = new Function<Float,Double>(){ 074 @Override 075 public Double apply(Float input) { 076 return null == input ? null : input.doubleValue(); 077 }}; 078 private final Function<Double,Float> double2FloatFun = new Function<Double,Float>(){ 079 @Override 080 public Float apply(Double input) { 081 return null == input ? null : input.floatValue(); 082 }}; 083 private final Function<Date,Long> date2LongFunction = new Function<Date,Long>(){ 084 @Override 085 public Long apply(Date input) { 086 return null == input ? null : input.getTime(); 087 }}; 088 private final Function<Long,Date> long2DateFun = new Function<Long,Date>(){ 089 @Override 090 public Date apply(Long input) { 091 return null == input ? null : new Date(input); 092 }}; 093 private final Function<Long,java.sql.Date> long2SqlDateFun = new Function<Long,java.sql.Date>(){ 094 @Override 095 public java.sql.Date apply(Long input) { 096 return null == input ? null : new java.sql.Date(input); 097 }}; 098 private final Function<Long,java.sql.Time> long2SqlTimeFun = new Function<Long,java.sql.Time>(){ 099 @Override 100 public java.sql.Time apply(Long input) { 101 return null == input ? null : new java.sql.Time(input); 102 }}; 103 private final Function<URL,String> url2StringFun = new Function<URL,String>(){ 104 @Override 105 public String apply(URL input) { 106 return null == input ? null : input.toString(); 107 }}; 108 private final Function<URI,String> uri2StringFun = new Function<URI,String>(){ 109 @Override 110 public String apply(URI input) { 111 return null == input ? null : input.toString(); 112 }}; 113 private final Function<String,URL> string2UrlFun = new Function<String,URL>(){ 114 @Override 115 public URL apply(String input) { 116 try { 117 return null == input ? null : new URL(input); 118 } catch (MalformedURLException e) { 119 throw new RuntimeException(e); 120 } 121 }}; 122 private final Function<String,URI> string2UriFun = new Function<String,URI>(){ 123 @Override 124 public URI apply(String input) { 125 return null == input ? null : URI.create(input); 126 }}; 127 private final Function<int[],List<Integer>> intArray2List = new Function<int[],List<Integer>>(){ 128 @Override 129 public List<Integer> apply(int[] input) { 130 return null == input ? null : Ints.asList(input); 131 }}; 132 private final Function<long[],List<Long>> longArray2List = new Function<long[],List<Long>>(){ 133 @Override 134 public List<Long> apply(long[] input) { 135 return null == input ? null : Longs.asList(input); 136 }}; 137 private final Function<double[],List<Double>> doubleArray2List = new Function<double[],List<Double>>(){ 138 @Override 139 public List<Double> apply(double[] input) { 140 return null == input ? null : Doubles.asList(input); 141 }}; 142 private final Function<float[],List<Double>> floatArray2List = new Function<float[],List<Double>>(){ 143 @Override 144 public List<Double> apply(float[] input) { 145 return null == input 146 ? null 147 : Lists.transform(Floats.asList(input),(Function<Float,Double>)float2DoubleFun); 148 }}; 149 private final Function<short[],List<Short>> shortArray2List = new Function<short[],List<Short>>(){ 150 @Override 151 public List<Short> apply(short[] input) { 152 return null == input ? null : Shorts.asList(input); 153 }}; 154 private final Function<boolean[],List<Boolean>> booleanArray2List = new Function<boolean[],List<Boolean>>(){ 155 @Override 156 public List<Boolean> apply(boolean[] input) { 157 return null == input ? null : Booleans.asList(input); 158 }}; 159 private final Function<List<Integer>,int[]> list2intArray = new Function<List<Integer>,int[]>(){ 160 @Override 161 public int[] apply(List<Integer> input) { 162 return null == input ? null : Ints.toArray(input); 163 }}; 164 private final Function<List<Long>,long[]> list2longArray = new Function<List<Long>,long[]>(){ 165 @Override 166 public long[] apply(List<Long> input) { 167 return null == input ? null : Longs.toArray(input); 168 }}; 169 private final Function<List<Double>,double[]> list2doubleArray = new Function<List<Double>,double[]>(){ 170 @Override 171 public double[] apply(List<Double> input) { 172 return null == input ? null : Doubles.toArray(input); 173 }}; 174 private final Function<List<Double>,float[]> list2floatArray = new Function<List<Double>,float[]>(){ 175 @Override 176 public float[] apply(List<Double> input) { 177 return null == input ? null : Floats.toArray(input); 178 }}; 179 private final Function<List<Short>,short[]> list2shortArray = new Function<List<Short>,short[]>(){ 180 @Override 181 public short[] apply(List<Short> input) { 182 return null == input ? null : Shorts.toArray(input); 183 }}; 184 private final Function<List<Boolean>,boolean[]> list2booleanArray = new Function<List<Boolean>,boolean[]>(){ 185 @Override 186 public boolean[] apply(List<Boolean> input) { 187 return null == input ? null : Booleans.toArray(input); 188 }}; 189 protected final Table<Class<?>,Class<?>,Function<?,?>> transTable = HashBasedTable.create(); 190 public TypeTransformer() { 191 transTable.put(byte[].class,ByteBuffer.class,byteArray2ByteBufferFun); 192 transTable.put(ByteBuffer.class,byte[].class,byteBuffer2ByteArrayFun); 193 transTable.put(Float.class,Double.class,float2DoubleFun); 194 transTable.put(Double.class,Float.class,double2FloatFun); 195 transTable.put(float.class,double.class,float2DoubleFun); 196 transTable.put(double.class,float.class,double2FloatFun); 197 transTable.put(Date.class, Long.class, date2LongFunction); 198 transTable.put(java.sql.Date.class, Long.class, date2LongFunction); 199 transTable.put(java.sql.Time.class,Long.class,date2LongFunction); 200 transTable.put(Long.class,Date.class,long2DateFun); 201 transTable.put(Long.class,java.sql.Date.class,long2SqlDateFun); 202 transTable.put(Long.class,java.sql.Time.class,long2SqlTimeFun); 203 transTable.put(URL.class,String.class,url2StringFun); 204 transTable.put(URI.class,String.class,uri2StringFun); 205 transTable.put(String.class,URL.class,string2UrlFun); 206 transTable.put(String.class,URI.class,string2UriFun); 207 transTable.put(int[].class,List.class,intArray2List); 208 transTable.put(long[].class,List.class,longArray2List); 209 transTable.put(double[].class,List.class,doubleArray2List); 210 transTable.put(float[].class,List.class,floatArray2List); 211 transTable.put(short[].class,List.class,shortArray2List); 212 transTable.put(boolean[].class,List.class,booleanArray2List); 213 transTable.put(List.class,int[].class,list2intArray); 214 transTable.put(List.class,long[].class,list2longArray); 215 transTable.put(List.class,double[].class,list2doubleArray); 216 transTable.put(List.class,float[].class,list2floatArray); 217 transTable.put(List.class,short[].class,list2shortArray); 218 transTable.put(List.class,boolean[].class,list2booleanArray); 219 } 220 /** 221 * 设置{@code left -> right}的转æ¢å™¨ï¼Œå‚æ•°ä¸å¯ä¸º{@code null} 222 * @param left 223 * @param right 224 * @param trans 转æ¢å™¨å¯¹è±¡ 225 * @return 226 */ 227 public <L,R>TypeTransformer setTransformer(Class<L> left, Class<R> right, Function<L, R> trans){ 228 checkArgument(null != left && null != right && null != trans,"left, right, trans must not be null"); 229 synchronized (this.transTable) { 230 transTable.put(left,right,trans); 231 return this; 232 } 233 } 234 /** 235 * 返回{@code left & right}指定的转æ¢å™¨ï¼Œå‚æ•°ä¸å¯ä¸º{@code null} 236 * @param left 237 * @param right 238 * @return 239 */ 240 @SuppressWarnings({ "unchecked" }) 241 public <L,R>Function<L,R> getTransformer(Class<L>left,Class<R>right){ 242 checkArgument(null != left && null != right,"left, right must not be null"); 243 if(right.isAssignableFrom(left)){ 244 // 相åŒç±»åž‹è½¬æ¢ 245 return (Function<L,R>)this.sameTypeFun; 246 } 247 Function<L, R> result = (Function<L, R>) this.transTable.get(left, right); 248 return result; 249 } 250 public <L,R>Function<L,R> getTransformerChecked(Class<L>left,Class<R>right){ 251 return checkNotNull(getTransformer(left,right),"not found transformer for %s to %s",left,right); 252 } 253 254 /** 255 * å°†{@code value}转æ¢ä¸º{@code right}指定的类型 256 * @param value 257 * @param left {@code value}的原类型 258 * @param right ç›®æ ‡ç±»åž‹ 259 * @return 260 */ 261 @SuppressWarnings("unchecked") 262 public <L,R> R to (L value,Class<L>left,Class<R> right){ 263 if(null == value){ 264 return null; 265 } 266 checkArgument(null != right,"right is null"); 267 if(right.isInstance(value)){ 268 return (R) value; 269 } 270 return this.getTransformerChecked(left, right).apply(value); 271 } 272 /** 273 * å°† List ä¸çš„å…ƒç´ è½¬æ¢ä¸º{@code right}指定的类型 274 * @param input 275 * @param left åˆ—è¡¨å…ƒç´ åŽŸç±»åž‹ 276 * @param right åˆ—è¡¨å…ƒç´ ç›®æ ‡ç±»åž‹ 277 * @return 278 */ 279 public <L,R>List<R> to(List<L> input,Class<L> left, Class<R> right){ 280 return null == input 281 ? null 282 : Lists.transform(input, this.getTransformerChecked(left, right)); 283 } 284 /** 285 * å°† Set ä¸çš„å…ƒç´ è½¬æ¢ä¸º{@code right}指定的类型 286 * @param input 287 * @param left 集åˆå…ƒç´ 原类型 288 * @param right 集åˆå…ƒç´ ç›®æ ‡ç±»åž‹ 289 * @return 290 */ 291 public <L,R> Set<R> to(Set<L> input,Class<L> left, Class<R> right){ 292 return null == input 293 ? null 294 : Sets.newHashSet(Iterables.transform(input, this.getTransformerChecked(left, right))); 295 } 296 /** 297 * å°† 数组 ä¸çš„å…ƒç´ è½¬æ¢ä¸º{@code right}指定的类型 298 * @param input 299 * @param left æ•°ç»„å…ƒç´ åŽŸç±»åž‹ 300 * @param right æ•°ç»„å…ƒç´ ç›®æ ‡ç±»åž‹ 301 * @return 302 */ 303 public <L,R> List<R> to(L[] input,Class<L> left,Class<R> right){ 304 if(null == input){ 305 return null; 306 } 307 return to(Arrays.asList(input),left,right); 308 } 309 /** 310 * å°† int[] 转æ¢ä¸ºåˆ—表 311 * @param input 312 * @param left 313 * @param right 314 * @return 315 */ 316 public List<Integer> to(int[] input,Class<Integer>left,Class<Integer> right){ 317 return intArray2List.apply(input); 318 } 319 /** 320 * å°† long[] 转æ¢ä¸ºåˆ—表 321 * @param input 322 * @param left 323 * @param right 324 * @return 325 */ 326 public List<Long> to(long[] input,Class<Long>left,Class<Long> right){ 327 return longArray2List.apply(input); 328 } 329 /** 330 * å°† double[] 转æ¢ä¸ºåˆ—表 331 * @param input 332 * @param left 333 * @param right 334 * @return 335 */ 336 public List<Double> to(double[] input,Class<Double>left,Class<Double> right){ 337 return doubleArray2List.apply(input); 338 } 339 /** 340 * å°† float[] 转æ¢ä¸ºDouble列表 341 * @param input 342 * @param left 343 * @param right 344 * @return 345 */ 346 public List<Double> to(float[] input,Class<Float>left,Class<Double> right){ 347 return floatArray2List.apply(input); 348 } 349 /** 350 * å°† short[] 转æ¢ä¸ºåˆ—表 351 * @param input 352 * @param left 353 * @param right 354 * @return 355 */ 356 public List<Short> to(short[] input,Class<Short>left,Class<Short> right){ 357 return shortArray2List.apply(input); 358 } 359 /** 360 * å°† boolean[] 转æ¢ä¸ºåˆ—表 361 * @param input 362 * @param left 363 * @param right 364 * @return 365 */ 366 public List<Boolean> to(boolean[] input,Class<Boolean>left,Class<Boolean> right){ 367 return booleanArray2List.apply(input); 368 } 369 /** 370 * å°† 列表 转æ¢ä¸ºæ•°ç»„ 371 * @param input 372 * @param left åˆ—è¡¨å…ƒç´ ç±»åž‹ 373 * @param right æ•°ç»„å…ƒç´ ç±»åž‹ 374 * @return 375 */ 376 @SuppressWarnings("unchecked") 377 public <L,R> R[] toArray(List<L> input,Class<L> left,Class<R> right){ 378 if(null == input){ 379 return null; 380 } 381 List<R> r = to(input,left,right); 382 return r.toArray((R[]) Array.newInstance(right, r.size())); 383 } 384 /** 385 * å°† Integer 列表 转æ¢ä¸ºæ•°ç»„ 386 * @param input 387 * @param left 388 * @param right 389 * @return 390 */ 391 public int[] tointArray(List<Integer> input,Class<Integer> left,Class<Integer> right){ 392 return list2intArray.apply(input); 393 } 394 /** 395 * å°† Long 列表 转æ¢ä¸ºæ•°ç»„ 396 * @param input 397 * @param left 398 * @param right 399 * @return 400 */ 401 public long[] tolongArray(List<Long> input,Class<Long> left,Class<Long> right){ 402 return list2longArray.apply(input); 403 } 404 /** 405 * å°† Double 列表 转æ¢ä¸ºæ•°ç»„ 406 * @param input 407 * @param left 408 * @param right 409 * @return 410 */ 411 public double[] todoubleArray(List<Double>input,Class<Double> left,Class<Double> right){ 412 return list2doubleArray.apply(input); 413 } 414 /** 415 * å°† Double 列表 转æ¢ä¸ºfloat数组 416 * @param input 417 * @param left 418 * @param right 419 * @return 420 */ 421 public float[] tofloatArray(List<Double>input,Class<Double> left,Class<Float> right){ 422 return list2floatArray.apply(input); 423 } 424 /** 425 * å°† Short 列表 转æ¢ä¸ºæ•°ç»„ 426 * @param input 427 * @param left 428 * @param right 429 * @return 430 */ 431 public short[] toshortArray(List<Short>input,Class<Short> left,Class<Short> right){ 432 return list2shortArray.apply(input); 433 } 434 /** 435 * å°† Boolean 列表 转æ¢ä¸ºæ•°ç»„ 436 * @param input 437 * @param left 438 * @param right 439 * @return 440 */ 441 public boolean[] tobooleanArray(List<Boolean>input,Class<Boolean> left,Class<Boolean> right){ 442 return list2booleanArray.apply(input); 443 } 444 /** 445 * å°†{@code Map<K1,V1>}转æ¢ä¸º{@code Map<K2,V2>} 446 * @param input 447 * @param k1 448 * @param v1 449 * @param k2 450 * @param v2 451 * @return 452 */ 453 @SuppressWarnings("unchecked") 454 public <K1,V1,K2,V2> Map<K2,V2> to(Map<K1,V1>input,Class<K1>k1,Class<V1>v1,Class<K2> k2,Class<V2> v2){ 455 checkArgument(null != k1 && null != v1 && null != k2 && null != v2,"k1,v1,k2,v2 must not be null"); 456 if(k1 == k2){ 457 if(v1 == v2){ 458 return (Map<K2, V2>) input; 459 } 460 return (Map<K2, V2>) Maps.transformValues(input, this.getTransformerChecked(v1, v2)); 461 }else{ 462 Map<K2, V1> k2v1 = transform(input,this.getTransformerChecked(k1, k2)); 463 if(v1 == v2){ 464 return (Map<K2, V2>) k2v1; 465 }else{ 466 return Maps.transformValues(k2v1, this.getTransformerChecked(v1, v2)); 467 } 468 } 469 } 470 /** 471 * convert {@code Map<K1,V>} to {@code Map<K2,V>} 472 * @return {@linkplain ImmutableMap} 473 */ 474 private static final <K1,K2,V>Map<K2,V> transform(Map<K1,V>fromMap,final Function<K1,K2>transformer){ 475 checkNotNull(fromMap,"fromMap is null"); 476 checkNotNull(transformer,"transformer is null"); 477 // æ–°çš„Map对象Keyç±»åž‹å·²ç»æ˜¯K2äº†ï¼Œåªæ˜¯Value类型æˆäº†Entry 478 ImmutableMap<K2, Entry<K1, V>> k2Entry = Maps.uniqueIndex(fromMap.entrySet(), new Function<Entry<K1, V>,K2>(){ 479 @Override 480 public K2 apply(Entry<K1, V> input) { 481 return transformer.apply(input.getKey()); 482 }}); 483 // å†åšä¸€æ¬¡è½¬æ¢å°†Entry<K1, V>è½¬æ¢æˆV,这个过程并没有创建新的Map,åªæ˜¯åˆ›å»ºäº†k2Entry的代ç†å¯¹è±¡ 484 Map<K2, V> k2V = Maps.transformEntries(k2Entry, new EntryTransformer<K2,Entry<K1,V>,V>(){ 485 @Override 486 public V transformEntry(K2 key, Entry<K1, V> value) { 487 return value.getValue(); 488 }}); 489 return k2V; 490 } 491}