001package net.gdface.utils;
002
003import java.lang.reflect.Array;
004import java.lang.reflect.ParameterizedType;
005import java.lang.reflect.Type;
006import java.net.MalformedURLException;
007import java.net.URI;
008import java.net.URL;
009import java.nio.ByteBuffer;
010import java.util.Arrays;
011import java.util.Date;
012import java.util.List;
013import java.util.Map;
014import java.util.Map.Entry;
015import java.util.Set;
016
017import com.google.common.base.Function;
018import com.google.common.collect.HashBasedTable;
019import com.google.common.collect.ImmutableMap;
020import com.google.common.collect.Iterables;
021import com.google.common.collect.Lists;
022import com.google.common.collect.Maps;
023import com.google.common.collect.Maps.EntryTransformer;
024import com.google.common.collect.Sets;
025import com.google.common.collect.Table;
026import com.google.common.primitives.Booleans;
027import com.google.common.primitives.Doubles;
028import com.google.common.primitives.Floats;
029import com.google.common.primitives.Ints;
030import com.google.common.primitives.Longs;
031import com.google.common.primitives.Shorts;
032import com.google.common.reflect.TypeToken;
033
034import static com.google.common.base.Preconditions.*;
035/**
036 * 类型转换工具类
037 * @author guyadong
038 *
039 */
040public class BaseTypeTransformer {
041        /**
042         * 返回buffer中所有字节(position~limit),不改变buffer状态
043         * @param buffer
044         * @return buffer 为 null 时返回 null 
045         */
046        public static final byte[] getBytesInBuffer(ByteBuffer buffer){
047                if(null == buffer){
048                        return null;
049                }
050                int pos = buffer.position();
051                try{
052                        byte[] bytes = new byte[buffer.remaining()];
053                        buffer.get(bytes);
054                        return bytes;
055                }finally{
056                        buffer.position(pos);
057                }
058        }
059        @SuppressWarnings("rawtypes")
060        private final Function sameTypeFun = new Function(){
061                @Override
062                public Object apply(Object input) {
063                        return input;
064                }};
065        private final Function<Boolean,Boolean> booleanTypeFun = new Function<Boolean,Boolean>(){
066                @Override
067                public Boolean apply(Boolean input) {
068                        return checkNotNull(input,"input is null").booleanValue();
069                }};
070        private final Function<Character,Character> charTypeFun = new Function<Character,Character>(){
071                @Override
072                public Character apply(Character input) {
073                        return checkNotNull(input,"input is null").charValue();
074                }};             
075        private final Function<Byte,Byte> byteTypeFun = new Function<Byte,Byte>(){
076        @Override
077        public Byte apply(Byte input) {
078                return checkNotNull(input,"input is null").byteValue();
079        }};     
080        private final Function<Short,Short> shortTypeFun = new Function<Short,Short>(){
081                @Override
082                public Short apply(Short input) {
083                        return checkNotNull(input,"input is null").shortValue();
084                }};             
085        private final Function<Integer,Integer> intTypeFun = new Function<Integer,Integer>(){
086                @Override
087                public Integer apply(Integer input) {
088                        return checkNotNull(input,"input is null").intValue();
089                }};
090        private final Function<Long,Long> longTypeFun = new Function<Long,Long>(){
091                @Override
092                public Long apply(Long input) {
093                        return checkNotNull(input,"input is null").longValue();
094                }};
095        private final Function<Float,Float> floatTypeFun = new Function<Float,Float>(){
096                @Override
097                public Float apply(Float input) {
098                        return checkNotNull(input,"input is null").floatValue();
099                }};
100        private final Function<Double,Double> doubleTypeFun = new Function<Double,Double>(){
101                @Override
102                public Double apply(Double input) {
103                        Double.class.isPrimitive();
104                        return checkNotNull(input,"input is null").doubleValue();
105                }};
106        private final Function<Void,Void> voidTypeFun = new Function<Void,Void>(){
107                @Override
108                public Void apply(Void input) {
109                        return null;
110                }};
111        private final Function<byte[],ByteBuffer> byteArray2ByteBufferFun = new Function<byte[],ByteBuffer>(){
112                @Override
113                public ByteBuffer apply(byte[] input) {
114                        return null == input ? null :ByteBuffer.wrap(input);
115                }};
116        private final Function<ByteBuffer,byte[]> byteBuffer2ByteArrayFun = new Function<ByteBuffer,byte[]>(){
117                @Override
118                public byte[] apply(ByteBuffer input) {
119                        return getBytesInBuffer(input);
120                }};
121        private final Function<Float,Double> float2DoubleFun = new Function<Float,Double>(){
122                @Override
123                public Double apply(Float input) {
124                        return null == input ? null : input.doubleValue();
125                }};
126        private final Function<Double,Float> double2FloatFun = new Function<Double,Float>(){
127                @Override
128                public Float apply(Double input) {
129                        return null == input ? null : input.floatValue();
130                }};
131        private final Function<Date,Long> date2LongFunction = new Function<Date,Long>(){
132                @Override
133                public Long apply(Date input) {
134                        return null == input ? null : input.getTime();
135                }};
136        private final Function<Long,Date> long2DateFun = new Function<Long,Date>(){
137                @Override
138                public Date apply(Long input) {
139                        return null == input ? null : new Date(input);
140                }};
141        private final Function<Long,java.sql.Date> long2SqlDateFun = new Function<Long,java.sql.Date>(){
142                @Override
143                public java.sql.Date apply(Long input) {
144                        return null == input ? null : new java.sql.Date(input);
145                }};
146        private final Function<Long,java.sql.Time> long2SqlTimeFun = new Function<Long,java.sql.Time>(){
147                @Override
148                public java.sql.Time apply(Long input) {
149                        return null == input ? null : new java.sql.Time(input);
150                }};
151        private final Function<URL,String> url2StringFun = new Function<URL,String>(){
152                @Override
153                public String apply(URL input) {
154                        return null == input ? null : input.toString();
155                }};
156        private final Function<URI,String> uri2StringFun = new Function<URI,String>(){
157                @Override
158                public String apply(URI input) {
159                        return null == input ? null : input.toString();
160                }};
161        private final Function<String,URL> string2UrlFun = new Function<String,URL>(){
162                @Override
163                public URL apply(String input) {
164                        try {
165                                return null == input ? null : new URL(input);
166                        } catch (MalformedURLException e) {
167                                throw new RuntimeException(e);
168                        }
169                }};
170        private final Function<String,URI> string2UriFun = new Function<String,URI>(){
171                @Override
172                public URI apply(String input) {
173                        return null == input ? null : URI.create(input);
174                }};
175        private final Function<int[],List<Integer>> intArray2List = new Function<int[],List<Integer>>(){
176                @Override
177                public List<Integer> apply(int[] input) {
178                        return null == input ? null : Ints.asList(input);
179                }};
180        private final Function<long[],List<Long>> longArray2List = new Function<long[],List<Long>>(){
181                @Override
182                public List<Long> apply(long[] input) {
183                        return null == input ? null : Longs.asList(input);
184                }};
185        private final Function<double[],List<Double>> doubleArray2List = new Function<double[],List<Double>>(){
186                @Override
187                public List<Double> apply(double[] input) {
188                        return null == input ? null : Doubles.asList(input);
189                }};
190        private final Function<float[],List<Double>> floatArray2List = new Function<float[],List<Double>>(){
191                @Override
192                public List<Double> apply(float[] input) {                      
193                        return null == input 
194                                        ? null 
195                                        : Lists.transform(Floats.asList(input),(Function<Float,Double>)float2DoubleFun);
196                }};
197        private final Function<short[],List<Short>> shortArray2List = new Function<short[],List<Short>>(){
198                @Override
199                public List<Short> apply(short[] input) {
200                        return null == input ? null : Shorts.asList(input);
201                }};
202        private final Function<boolean[],List<Boolean>> booleanArray2List = new Function<boolean[],List<Boolean>>(){
203                @Override
204                public List<Boolean> apply(boolean[] input) {
205                        return null == input ? null : Booleans.asList(input);
206                }};
207        private final Function<List<Integer>,int[]> list2intArray = new Function<List<Integer>,int[]>(){
208                @Override
209                public int[] apply(List<Integer> input) {
210                        return null == input ? null : Ints.toArray(input);
211                }};
212        private final Function<List<Long>,long[]> list2longArray = new Function<List<Long>,long[]>(){
213                @Override
214                public long[] apply(List<Long> input) {
215                        return null == input ? null : Longs.toArray(input);
216                }};
217        private final Function<List<Double>,double[]> list2doubleArray = new Function<List<Double>,double[]>(){
218                @Override
219                public double[] apply(List<Double> input) {
220                        return null == input ? null : Doubles.toArray(input);
221                }};
222        private final Function<List<Double>,float[]> list2floatArray = new Function<List<Double>,float[]>(){
223                @Override
224                public float[] apply(List<Double> input) {
225                        return null == input ? null : Floats.toArray(input);
226                }};
227        private final Function<List<Short>,short[]> list2shortArray = new Function<List<Short>,short[]>(){
228                @Override
229                public short[] apply(List<Short> input) {
230                        return null == input ? null : Shorts.toArray(input);
231                }};
232        private final Function<List<Boolean>,boolean[]> list2booleanArray = new Function<List<Boolean>,boolean[]>(){
233                @Override
234                public boolean[] apply(List<Boolean> input) {
235                        return null == input ? null : Booleans.toArray(input);
236                }};
237        protected final Table<Class<?>,Class<?>,Function<?,?>> transTable = HashBasedTable.create();
238        public BaseTypeTransformer() {
239                transTable.put(byte[].class,ByteBuffer.class,byteArray2ByteBufferFun);
240                transTable.put(ByteBuffer.class,byte[].class,byteBuffer2ByteArrayFun);
241                transTable.put(Float.class,Double.class,float2DoubleFun);
242                transTable.put(Double.class,Float.class,double2FloatFun);
243                transTable.put(float.class,double.class,float2DoubleFun);
244                transTable.put(float.class,Double.class,float2DoubleFun);
245                transTable.put(double.class,float.class,double2FloatFun);
246                transTable.put(double.class,Float.class,double2FloatFun);
247                transTable.put(Date.class, Long.class, date2LongFunction);
248                transTable.put(java.sql.Date.class, Long.class, date2LongFunction);
249                transTable.put(java.sql.Time.class,Long.class,date2LongFunction);
250                transTable.put(Long.class,Date.class,long2DateFun);
251                transTable.put(Long.class,java.sql.Date.class,long2SqlDateFun);
252                transTable.put(Long.class,java.sql.Time.class,long2SqlTimeFun);
253                transTable.put(URL.class,String.class,url2StringFun);
254                transTable.put(URI.class,String.class,uri2StringFun);
255                transTable.put(String.class,URL.class,string2UrlFun);
256                transTable.put(String.class,URI.class,string2UriFun);
257                transTable.put(int[].class,List.class,intArray2List);
258                transTable.put(long[].class,List.class,longArray2List);
259                transTable.put(double[].class,List.class,doubleArray2List);
260                transTable.put(float[].class,List.class,floatArray2List);
261                transTable.put(short[].class,List.class,shortArray2List);
262                transTable.put(boolean[].class,List.class,booleanArray2List);
263                transTable.put(List.class,int[].class,list2intArray);
264                transTable.put(List.class,long[].class,list2longArray);
265                transTable.put(List.class,double[].class,list2doubleArray);
266                transTable.put(List.class,float[].class,list2floatArray);
267                transTable.put(List.class,short[].class,list2shortArray);
268                transTable.put(List.class,boolean[].class,list2booleanArray);
269                transTable.put(Boolean.class, boolean.class, booleanTypeFun);
270                transTable.put(Character.class, Character.class, charTypeFun);
271                transTable.put(Byte.class, byte.class, byteTypeFun);
272                transTable.put(Short.class, short.class, shortTypeFun);
273                transTable.put(Integer.class, int.class, intTypeFun);
274                transTable.put(Long.class, long.class, longTypeFun);
275                transTable.put(Float.class, float.class, floatTypeFun);
276                transTable.put(Double.class, double.class, doubleTypeFun);
277                transTable.put(Void.class, void.class, voidTypeFun);
278        }
279        /**
280         * 设置{@code left -> right}的转换器,参数不可为{@code null}
281         * @param left
282         * @param right
283         * @param trans 转换器对象
284         * @return
285         */
286        public <L,R>BaseTypeTransformer setTransformer(Class<L> left, Class<R> right, Function<L, R> trans){
287                checkArgument(null != left && null != right && null != trans,"left, right, trans must not be null");
288                synchronized (this.transTable) {
289                        transTable.put(left,right,trans);
290                        return this;
291                }
292        }
293        /**
294         * 返回{@code left TO right}指定的转换器,参数不可为{@code null}
295         * @param left
296         * @param right
297         * @return
298         */
299        @SuppressWarnings({ "unchecked", "rawtypes" })
300        public <L,R>Function<L,R> getTransformer(Class<L>left,Class<R>right){
301                checkArgument(null != left && null != right,"left, right must not be null");
302                if(right.isAssignableFrom(left)){
303                        // 相同类型转换
304                        return (Function<L,R>)this.sameTypeFun;
305                }
306                Function<L, R> result = (Function<L, R>) this.transTable.get(left, right);
307                if (null == result) {
308                        if (Enum.class.isAssignableFrom(left) && Enum.class.isAssignableFrom(left)) {
309                                // 添加枚举类型转换
310                                synchronized (this.transTable) {
311                                        // double checking
312                                        if (null == (result = (Function<L, R>) this.transTable.get(left, right))) {
313                                                result = new EnumTransformer((Class<? extends Enum<?>>) left,
314                                                                (Class<? extends Enum<?>>) right);
315                                                setTransformer(left, right, (Function<L,R>)result);
316                                        }
317                                }
318                        }
319                }
320                return result;
321        }
322        public <L,R>Function<L,R> getTransformerChecked(Class<L>left,Class<R>right){
323                return checkNotNull(getTransformer(left,right),"not found transformer for %s to %s",left,right);
324        }
325
326        /**
327         * 将{@code value}转换为{@code right}指定的类型
328         * @param value
329         * @param left {@code value}的原类型
330         * @param right 目标类型
331         * @return
332         */
333        @SuppressWarnings("unchecked")
334        public <L,R> R to (L value,Class<L>left,Class<R> right){
335                if(null == value){
336                        return null;
337                }
338                checkArgument(null != right,"right is null");
339                if(right.isInstance(value)){
340                        return (R) value;
341                }
342                return this.getTransformerChecked(left, right).apply(value);
343        }
344        /**
345         * 将 List 中的元素转换为{@code right}指定的类型
346         * @param input
347         * @param left 列表元素原类型
348         * @param right 列表元素目标类型
349         * @return
350         */
351        public <L,R>List<R> to(List<L> input,Class<L> left, Class<R> right){
352                return null == input 
353                                ? null 
354                                : Lists.transform(input, this.getTransformerChecked(left, right));
355        }
356        /**
357         * 将 Set 中的元素转换为{@code right}指定的类型
358         * @param input
359         * @param left 集合元素原类型
360         * @param right 集合元素目标类型
361         * @return
362         */
363        public <L,R> Set<R> to(Set<L> input,Class<L> left, Class<R> right){
364                return null == input 
365                                ? null 
366                                : Sets.newHashSet(Iterables.transform(input, this.getTransformerChecked(left, right)));
367        }
368        /**
369         * 将 数组 中的元素转换为{@code right}指定的类型
370         * @param input
371         * @param left 数组元素原类型
372         * @param right 数组元素目标类型
373         * @return
374         */
375        public <L,R> List<R> to(L[] input,Class<L> left,Class<R> right){
376                if(null == input){
377                        return null;
378                }
379                return to(Arrays.asList(input),left,right);
380        }
381        /**
382         * 将 int[] 转换为列表
383         * @param input
384         * @param left 
385         * @param right 
386         * @return
387         */
388        public List<Integer> to(int[] input,Class<Integer>left,Class<Integer> right){
389                return intArray2List.apply(input);
390        }
391        /**
392         * 将 long[] 转换为列表
393         * @param input
394         * @param left 
395         * @param right 
396         * @return
397         */
398        public List<Long> to(long[] input,Class<Long>left,Class<Long> right){
399                return longArray2List.apply(input);
400        }
401        /**
402         * 将 double[] 转换为列表
403         * @param input
404         * @param left 
405         * @param right 
406         * @return
407         */
408        public List<Double> to(double[] input,Class<Double>left,Class<Double> right){
409                return doubleArray2List.apply(input);
410        }
411        /**
412         * 将 float[] 转换为Double列表
413         * @param input
414         * @param left 
415         * @param right 
416         * @return
417         */
418        public List<Double> to(float[] input,Class<Float>left,Class<Double> right){
419                return floatArray2List.apply(input);
420        }
421        /**
422         * 将 short[] 转换为列表
423         * @param input
424         * @param left 
425         * @param right 
426         * @return
427         */
428        public List<Short> to(short[] input,Class<Short>left,Class<Short> right){
429                return shortArray2List.apply(input);
430        }
431        /**
432         * 将 boolean[] 转换为列表
433         * @param input
434         * @param left 
435         * @param right 
436         * @return
437         */
438        public List<Boolean> to(boolean[] input,Class<Boolean>left,Class<Boolean> right){
439                return booleanArray2List.apply(input);
440        }
441        /**
442         * 将 列表 转换为数组
443         * @param input
444         * @param left 列表元素类型
445         * @param right 数组元素类型
446         * @return
447         */
448        @SuppressWarnings("unchecked")
449        public <L,R> R[] toArray(List<L> input,Class<L> left,Class<R> right){
450                if(null == input){
451                        return null;
452                }
453                List<R> r = to(input,left,right);
454                return r.toArray((R[]) Array.newInstance(right, r.size()));
455        }
456        /**
457         * 将 Integer 列表 转换为数组
458         * @param input
459         * @param left 
460         * @param right 
461         * @return
462         */
463        public  int[] tointArray(List<Integer> input,Class<Integer> left,Class<Integer> right){
464                return list2intArray.apply(input);
465        }
466        /**
467         * 将 Long 列表 转换为数组
468         * @param input
469         * @param left 
470         * @param right 
471         * @return
472         */
473        public  long[] tolongArray(List<Long> input,Class<Long> left,Class<Long> right){
474                return list2longArray.apply(input);
475        }
476        /**
477         * 将 Double 列表 转换为数组
478         * @param input
479         * @param left 
480         * @param right 
481         * @return
482         */
483        public double[] todoubleArray(List<Double>input,Class<Double> left,Class<Double> right){
484                return list2doubleArray.apply(input);   
485        }
486        /**
487         * 将 Double 列表 转换为float数组
488         * @param input
489         * @param left 
490         * @param right 
491         * @return
492         */
493        public float[] tofloatArray(List<Double>input,Class<Double> left,Class<Float> right){
494                return list2floatArray.apply(input);
495        }
496        /**
497         * 将 Short 列表 转换为数组
498         * @param input
499         * @param left 
500         * @param right 
501         * @return
502         */
503        public short[] toshortArray(List<Short>input,Class<Short> left,Class<Short> right){
504                return list2shortArray.apply(input);    
505        }
506        /**
507         * 将 Boolean 列表 转换为数组
508         * @param input
509         * @param left 
510         * @param right 
511         * @return
512         */
513        public boolean[] tobooleanArray(List<Boolean>input,Class<Boolean> left,Class<Boolean> right){
514                return list2booleanArray.apply(input);
515        }
516        /**
517         * 将{@code Map<K1,V1>}转换为{@code Map<K2,V2>}
518         * @param input
519         * @param k1
520         * @param v1
521         * @param k2
522         * @param v2
523         * @return
524         */
525        @SuppressWarnings("unchecked")
526        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){
527                checkArgument(null != k1 && null != v1 && null != k2 && null != v2,"k1,v1,k2,v2 must not be null");
528                if(k1 == k2){
529                        if(v1 == v2){
530                                return (Map<K2, V2>) input;
531                        }
532                        return (Map<K2, V2>) Maps.transformValues(input, this.getTransformerChecked(v1, v2));
533                }else{
534                        Map<K2, V1> k2v1 = transform(input,this.getTransformerChecked(k1, k2));
535                        if(v1 == v2){
536                                return (Map<K2, V2>) k2v1;
537                        }else{
538                                return Maps.transformValues(k2v1, this.getTransformerChecked(v1, v2));
539                        }
540                }               
541        }
542        /**
543         * 将{@code value}转换为{@code right}指定的类型
544         * @param value
545         * @param left {@code value}的原类型
546         * @param right 目标类型
547         * @return
548         */
549        @SuppressWarnings({ "unchecked", "rawtypes" })
550        public <L, R> R cast(Object value, Type left, Type right) {
551                TypeToken<?> leftToken = TypeToken.of(checkNotNull(left));
552                TypeToken<?> rightToken = TypeToken.of(checkNotNull(right));
553                if(null == value){
554                        // right为primitive类型时 value不可为null,否则抛出异常
555                        checkArgument(! ((right instanceof Class<?>) && ((Class<?>)right).isPrimitive()),"cant cast null to primitive type %s",right);
556                        return null;
557                }
558                // object to object
559                if( left instanceof Class<?> && right instanceof Class<?>){
560                        return to((L)value,(Class<L>)left, (Class<R>)right);
561                }
562                // list to array
563                if(List.class.isAssignableFrom(leftToken.getRawType()) && null != rightToken.getComponentType()){
564                        Class<?> componentType = rightToken.getComponentType().getRawType();
565                        if(componentType == int.class){
566                                return (R) tointArray((List<Integer>)value, Integer.class, int.class);
567                        }
568                        if(componentType == long.class){
569                                return (R) tolongArray((List<Long>)value, Long.class, long.class);
570                        }
571                        if(componentType == double.class){
572                                return (R) todoubleArray((List<Double>)value, Double.class, double.class);
573                        }
574                        if(componentType == float.class){
575                                return (R) tofloatArray((List<Double>)value, Double.class, float.class);
576                        }
577                        if(componentType == short.class){
578                                return (R) toshortArray((List<Short>)value, Short.class, short.class);
579                        }
580                        if(componentType == boolean.class){
581                                return (R) tobooleanArray((List<Boolean>)value, Boolean.class, boolean.class);
582                        }
583                        Type elementType = ((ParameterizedType)left).getActualTypeArguments()[0];
584                        if(elementType instanceof Class<?>){
585                                return (R) toArray((List<L>)value,(Class<L>)elementType,(Class<R>)componentType);
586                        }
587                        throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right));
588                }
589                // list to list
590                if(List.class.isAssignableFrom(leftToken.getRawType()) && List.class == rightToken.getRawType()){
591                        checkArgument(value instanceof List);
592                        Type leftElementType = ((ParameterizedType)left).getActualTypeArguments()[0];
593                        Type rightElementType = ((ParameterizedType)right).getActualTypeArguments()[0];
594                        if(leftElementType instanceof Class<?>&& rightElementType instanceof Class<?>){
595                                return (R) to((List<L>)value,(Class<L>)leftElementType,(Class<R>)rightElementType);
596                        }
597                        throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right));
598                }
599                // set to set
600                if(Set.class.isAssignableFrom(leftToken.getRawType()) && Set.class == rightToken.getRawType()){
601                        checkArgument(value instanceof Set);
602                        Type leftElementType = ((ParameterizedType)left).getActualTypeArguments()[0];
603                        Type rightElementType = ((ParameterizedType)right).getActualTypeArguments()[0];
604                        if(leftElementType instanceof Class<?>&& rightElementType instanceof Class<?>){
605                                return (R) to((Set<L>)value,(Class<L>)leftElementType,(Class<R>)rightElementType);
606                        }
607                        throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right));
608                }
609                // map to map
610                if(Map.class.isAssignableFrom(leftToken.getRawType()) && Map.class == rightToken.getRawType()){
611                        Type k1Type = ((ParameterizedType)left).getActualTypeArguments()[0];
612                        Type v1Type = ((ParameterizedType)left).getActualTypeArguments()[1];
613                        Type k2Type = ((ParameterizedType)right).getActualTypeArguments()[0];
614                        Type v2Type = ((ParameterizedType)right).getActualTypeArguments()[1];
615                        if(k1Type instanceof Class<?> 
616                                && v1Type instanceof Class<?> 
617                                && k2Type instanceof Class<?> 
618                                && v2Type instanceof Class<?>){
619                                to((Map)value,(Class<?>)k1Type,(Class<?>)v1Type,(Class<?>)k2Type,(Class<?>)v2Type);
620                        }
621                        throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right));
622                }
623                // array to list
624                if(leftToken.isArray() && List.class == rightToken.getRawType()){
625                        checkArgument(value.getClass().isArray());
626                        Type componentType = leftToken.getComponentType().getType();
627                        if(componentType == int.class){
628                                return (R) to((int[])value, int.class, Integer.class);
629                        }
630                        if(componentType == long.class){
631                                return (R) to((long[])value, long.class, Long.class);
632                        }
633                        if(componentType == double.class){
634                                return (R) to((double[])value, double.class, Double.class);
635                        }
636                        if(componentType == float.class){
637                                return (R) to((float[])value, float.class, Double.class);
638                        }
639                        if(componentType == short.class){
640                                return (R) to((short[])value, short.class, Short.class);
641                        }
642                        if(componentType == boolean.class){
643                                return (R) to((boolean[])value, boolean.class, Boolean.class);
644                        }
645                        Type rightElementType = ((ParameterizedType)right).getActualTypeArguments()[0];
646                        if((leftToken.getComponentType().getType()) instanceof Class<?> 
647                                && rightElementType instanceof Class<?>){
648                                return (R) to((L[])value,(Class<L>)componentType,(Class<R>)rightElementType);
649                        }
650                        throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right));
651                }
652                throw new UnsupportedOperationException(String.format("unsupported cast %s to %s",left,right));
653        }
654        /** 
655     * convert {@code Map<K1,V>} to {@code Map<K2,V>}   
656     * @return {@linkplain ImmutableMap}
657     */
658    private static final <K1,K2,V>Map<K2,V> transform(Map<K1,V>fromMap,final Function<K1,K2>transformer){
659        checkNotNull(fromMap,"fromMap is null");
660        checkNotNull(transformer,"transformer is null");
661        // 新的Map对象Key类型已经是K2了,只是Value类型成了Entry
662        ImmutableMap<K2, Entry<K1, V>> k2Entry = Maps.uniqueIndex(fromMap.entrySet(), new Function<Entry<K1, V>,K2>(){
663            @Override
664            public K2 apply(Entry<K1, V> input) {               
665                return transformer.apply(input.getKey());
666            }});
667        // 再做一次转换将Entry<K1, V>转换成V,这个过程并没有创建新的Map,只是创建了k2Entry的代理对象
668        Map<K2, V> k2V = Maps.transformEntries(k2Entry, new EntryTransformer<K2,Entry<K1,V>,V>(){
669            @Override
670            public V transformEntry(K2 key, Entry<K1, V> value) {
671                return value.getValue();
672            }});
673        return k2V;
674    }
675}