001package net.gdface.thrift; 002 003import static com.google.common.base.Preconditions.*; 004import static net.gdface.thrift.ThriftUtils.*; 005 006import java.lang.reflect.Constructor; 007import java.util.Map; 008 009import com.facebook.swift.codec.metadata.ThriftStructMetadata; 010import com.google.common.base.Function; 011import com.google.common.base.Strings; 012import com.google.common.base.Throwables; 013 014/** 015 * 有{@link com.facebook.swift.codec.ThriftStruct}æ³¨é‡Šçš„å¼‚å¸¸ç±»åž‹ä¹‹é—´çš„è½¬æ¢ 016 * @author guyadong 017 * 018 * @param <L> thrift 生æˆçš„client异常类型 019 * @param <R> 实现 {@link ThriftDecorator}的装饰类异常类型 020 */ 021public class ThriftExceptionTransformer<L extends Exception,R extends ThriftDecorator<? extends Exception>> 022 implements Function<L,R>{ 023 private final ThriftStructMetadata leftMetadata; 024 private final ThriftStructMetadata rightMetadata; 025 public ThriftExceptionTransformer(Class<L> left, Class<R> right) { 026 checkArgument(isThriftException(left,right),"left and right must not be Exception with @ThriftStruct annotation" ); 027 this.leftMetadata= CATALOG.getThriftStructMetadata(left); 028 this.rightMetadata= CATALOG.getThriftStructMetadata(right); 029 } 030 @Override 031 public R apply(L input) { 032 if(null == input){ 033 return null; 034 } 035 try { 036 Map<Short, TypeValue> data = ThriftUtils.getFiledValues(input,leftMetadata); 037 String message = input.getMessage(); 038 Constructor<R> constructor = getStringConstructor(); 039 if(null == constructor || Strings.isNullOrEmpty(message)){ 040 // é»˜è®¤æž„é€ æ–¹æ³•åˆ›å»ºå®žä¾‹ 041 return constructStruct(data,rightMetadata); 042 }else{ 043 // 调用String傿•°çš„æž„é€ æ–¹æ³•åˆ›å»ºå®žä¾‹ 044 R instance = constructor.newInstance(message); 045 return fillStructField(data,rightMetadata,instance); 046 } 047 } catch (Exception e) { 048 Throwables.throwIfUnchecked(e); 049 throw new RuntimeException(e); 050 } 051 } 052 /** 053 * 获å–String傿•°çš„æž„é€ æ–¹æ³•,没有则返回{@code null} 054 * @return 055 */ 056 @SuppressWarnings("unchecked") 057 private Constructor<R> getStringConstructor(){ 058 return ThriftUtils.getConstructor((Class<R>)rightMetadata.getStructClass(),String.class); 059 } 060 @Override 061 public String toString() { 062 StringBuilder builder = new StringBuilder() 063 .append("ThriftExceptionTransformer [leftClass=") 064 .append(leftMetadata.getStructType()) 065 .append(", rightClass=") 066 .append(rightMetadata.getStructType()) 067 .append("]"); 068 return builder.toString(); 069 } 070}