001package net.gdface.thrift; 002 003import com.google.common.base.Function; 004import net.gdface.utils.BaseTypeTransformer; 005 006import static com.google.common.base.Preconditions.*; 007import static net.gdface.thrift.ThriftUtils.*; 008/** 009 * 类型转æ¢å·¥å…·ç±» 010 * @author guyadong 011 * 012 */ 013public class TypeTransformer extends BaseTypeTransformer{ 014 private static TypeTransformer instance = new TypeTransformer(); 015 public static TypeTransformer getInstance() { 016 return instance; 017 } 018 public static synchronized void setInstance(TypeTransformer instance) { 019 TypeTransformer.instance = checkNotNull(instance,"instance is null"); 020 } 021 protected TypeTransformer() { 022 } 023 @SuppressWarnings({ "unchecked", "rawtypes" }) 024 @Override 025 public <L,R>Function<L,R> getTransformer(Class<L>left,Class<R>right){ 026 Function<L, R> result = super.getTransformer(left,right); 027 if (null == result) { 028 if(isThriftStruct(left) && isThriftStruct(right)){ 029 // æ·»åŠ ThriftStuctå¯¹è±¡ä¹‹é—´çš„è½¬æ¢ 030 synchronized (this.transTable) { 031 // double checking 032 if (null == (result = (Function<L, R>) this.transTable.get(left, right))) { 033 if(isThriftException(left,right)){ 034 result = new ThriftExceptionTransformer(left,right); 035 }else{ 036 result = new ThriftStructTransformer(left,right); 037 } 038 setTransformer(left, right, result); 039 } 040 } 041 }else if(isThriftDecoratorPair(left,right) ){ 042 // æ·»åŠ thrift decoratorå¯¹è±¡å’Œè¢«è£…é¥°å¯¹è±¡ä¹‹é—´çš„è½¬æ¢ 043 updateThriftDecoatorTransformer(right,(Class<? extends ThriftDecorator>)left); 044 result = (Function<L, R>) this.transTable.get(left, right); 045 }else if(isThriftDecoratorPair(right,left) ){ 046 // æ·»åŠ thrift decoratorå¯¹è±¡å’Œè¢«è£…é¥°å¯¹è±¡ä¹‹é—´çš„è½¬æ¢ 047 updateThriftDecoatorTransformer(left,(Class<? extends ThriftDecorator>)right); 048 result = (Function<L, R>) this.transTable.get(left, right); 049 }else if(isThriftClientPair(left,right)){ 050 // æ·»åŠ åŽŸå§‹å¯¹è±¡å’Œthrift decoratorå¯¹è±¡ä¹‹é—´çš„è½¬æ¢ 051 updateThriftClientTypeTransformer(left,right); 052 result = (Function<L, R>) this.transTable.get(left, right); 053 }else if(isThriftClientPair(right,left)){ 054 // æ·»åŠ åŽŸå§‹å¯¹è±¡å’Œthrift decoratorå¯¹è±¡ä¹‹é—´çš„è½¬æ¢ 055 updateThriftClientTypeTransformer(right,left); 056 result = (Function<L, R>) this.transTable.get(left, right); 057 } 058 } 059 return result; 060 } 061 private <L,R extends ThriftDecorator<L>>void updateThriftDecoatorTransformer(Class<L>left,Class<R>right){ 062 synchronized (this.transTable) { 063 // double checking 064 if (null == this.transTable.get(left, right)) { 065 ThriftDecoratorTransformer<L,R> trans = new ThriftDecoratorTransformer<L,R>(left,right); 066 setTransformer(left, right, trans.toDecoratorFun); 067 setTransformer(right,left, trans.toDelegateFun); 068 } 069 } 070 } 071 private <L,M extends ThriftDecorator<L>,R>void updateThriftClientTypeTransformer(Class<L>left,Class<R>right){ 072 synchronized (this.transTable) { 073 // double checking 074 if (null == this.transTable.get(left, right)) { 075 ThriftClientTypeTransformer<L, M, R> trans = new ThriftClientTypeTransformer<L,M,R>(left,right); 076 setTransformer(left, right, trans.toThriftClientTypeFun); 077 setTransformer(right,left, trans.toOriginalTypeFun); 078 } 079 } 080 } 081 /** 082 * å°†{@code value}转æ¢ä¸º{@code right}指定的类型 083 * @param value 084 * @param left {@code value}的原类型 085 * @param right ç›®æ ‡ç±»åž‹ 086 * @return 087 */ 088 /** 089 * 原始类型和thrift client 类型之间的转æ¢å™¨,需è¦2将完æˆè½¬æ¢ï¼Œå¦‚æžœ{@code L->M->R} 090 * @author guyadong 091 * 092 * @param <L> 原始类型 093 * @param <M>ä¸é—´ç±»åž‹deorator 094 * @param <R> thrift client 类型 095 */ 096 public class ThriftClientTypeTransformer<L,M extends ThriftDecorator<L>,R> { 097 private final Function<L, M> left2Middle; 098 private final Function<M, R> middle2Right; 099 private final Function<M, L> middle2Left; 100 private final Function<R, M> right2Middle; 101 public ThriftClientTypeTransformer(Class<L> left, Class<R> right) { 102 checkArgument(null != left && null != right,"left,middle,right must not be null"); 103 Class<M> middClass = getMiddleClassChecked(left,right); 104 left2Middle = getTransformerChecked(left,middClass); 105 middle2Right = getTransformerChecked(middClass,right); 106 middle2Left = getTransformerChecked(middClass,left); 107 right2Middle = getTransformerChecked(right,middClass); 108 } 109 public final Function<L,R> toThriftClientTypeFun = new Function<L,R>(){ 110 @Override 111 public R apply(L input) { 112 M m = left2Middle.apply(input); 113 return middle2Right.apply(m); 114 }}; 115 public final Function<R,L> toOriginalTypeFun = new Function<R,L>(){ 116 @Override 117 public L apply(R input) { 118 M m = right2Middle.apply(input); 119 return middle2Left.apply(m); 120 }}; 121 } 122}