net.gdface.thrift.BaseThriftUtils Maven / Gradle / Ivy
The newest version!
package net.gdface.thrift;
import static com.facebook.swift.codec.metadata.FieldKind.THRIFT_FIELD;
import static com.google.common.base.Preconditions.*;
import static java.lang.String.format;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.lang.reflect.WildcardType;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.facebook.swift.codec.ThriftStruct;
import com.facebook.swift.codec.metadata.ThriftExtraction;
import com.facebook.swift.codec.metadata.ThriftFieldExtractor;
import com.facebook.swift.codec.metadata.ThriftFieldInjection;
import com.facebook.swift.codec.metadata.ThriftFieldMetadata;
import com.facebook.swift.codec.metadata.ThriftInjection;
import com.facebook.swift.codec.metadata.ThriftMethodExtractor;
import com.facebook.swift.codec.metadata.ThriftMethodInjection;
import com.facebook.swift.codec.metadata.ThriftParameterInjection;
import com.facebook.swift.codec.metadata.ThriftStructMetadata;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.reflect.TypeParameter;
import com.google.common.reflect.TypeToken;
import net.gdface.utils.BaseTypeTransformer;
/**
* thrift工具
* @author guyadong
*
*/
public class BaseThriftUtils {
public static final Set> THRIFT_BUILTIN_KNOWNTYPES =
ImmutableSet.of(
boolean.class,
byte.class,
double.class,
short.class,
int.class,
long.class,
String.class,
ByteBuffer.class,
void.class,
Boolean.class,
Byte.class,
Short.class,
Integer.class,
Long.class,
Double.class);
public static final Map,Class>> CAST_TYPES =
ImmutableMap.,Class>>builder()
.put(byte[].class,ByteBuffer.class)
.put(Date.class,Long.class)
.put(java.sql.Date.class,Long.class)
.put(java.sql.Time.class,Long.class)
.put(float.class,double.class)
.put(Float.class,Double.class)
.put(URI.class,String.class)
.put(URL.class,String.class)
.build();
public static final String DECORATOR_PKG_SUFFIX="decorator";
public static final String CLIENT_SUFFIX="client";
public static final String DECORATOR_CLIENT_PKG_SUFFIX= DECORATOR_PKG_SUFFIX + "." + CLIENT_SUFFIX;
public static final String FIELD_INITIALIZED = "initialized";
public static final String FIELD_MODIFIED = "modified";
/**
* gu.sql2java.BaseBean 的内置字段名
*/
public static final ImmutableSet BASEBEAN_BUILTIN_FIELDS=ImmutableSet.of(FIELD_INITIALIZED,FIELD_MODIFIED);
private static Class> baseBeanClass;
static{
try {
baseBeanClass = Class.forName("gu.sql2java.BaseBean",false,BaseThriftUtils.class.getClassLoader());
} catch (ClassNotFoundException e) {
}
}
public BaseThriftUtils() {
}
public static Class> getBaseBeanClass() {
return baseBeanClass;
}
public static void setBaseBeanClass(Class> baseBeanClass) {
BaseThriftUtils.baseBeanClass = baseBeanClass;
}
/**
* 获取{@code field}指定的字段值
* 参见 com.facebook.swift.codec.internal.reflection.AbstractReflectionThriftCodec#getFieldValue(Object, ThriftFieldMetadata)
*
* @param instance
* @param field
* @return 字段值
* @throws Exception
*/
public static TypeValue getFieldValue(Object instance, ThriftFieldMetadata field) throws Exception {
try {
if (field.getExtraction().isPresent()) {
ThriftExtraction extraction = field.getExtraction().get();
if (extraction instanceof ThriftFieldExtractor) {
ThriftFieldExtractor thriftFieldExtractor = (ThriftFieldExtractor) extraction;
Field f = thriftFieldExtractor.getField();
return new TypeValue(f.getGenericType(),f.get(instance));
} else if (extraction instanceof ThriftMethodExtractor) {
ThriftMethodExtractor thriftMethodExtractor = (ThriftMethodExtractor) extraction;
Method method = thriftMethodExtractor.getMethod();
return new TypeValue(method.getGenericReturnType(),method.invoke(instance));
}
throw new IllegalAccessException("Unsupported field extractor type " + extraction.getClass().getName());
}
throw new IllegalAccessException("No extraction present for " + field);
} catch (InvocationTargetException e) {
if (e.getTargetException() != null) {
Throwables.throwIfInstanceOf(e.getTargetException(), Exception.class);
}
throw e;
}
}
public static boolean isThriftStruct(Type type){
return type instanceof Class>
? ((Class>)type).isAnnotationPresent(ThriftStruct.class)
: false;
}
public static boolean isThriftDecorator(Type type){
return type instanceof Class>
? ThriftDecorator.class.isAssignableFrom((Class>)type)
: false;
}
/**
* 如果{@code clazz}实现了{@link ThriftDecorator}接口,
* 则返回该类型代理的类型,否则返回{@code null}
* @param clazz
* @since 1.2.3
*/
public static Class> delegateClassOf(Class> clazz){
if(clazz != null && ThriftDecorator.class.isAssignableFrom(clazz)) {
for(Type type:clazz.getGenericInterfaces()) {
if(type instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType)type;
if(ThriftDecorator.class.equals(parameterizedType.getRawType())) {
return (Class>) parameterizedType.getActualTypeArguments()[0];
}
}
}
}
return null;
}
/**
* 如果输入类型是是装饰类({@link ThriftDecorator}),则返回代理类型,否则返回原样类型
* @param clazz
* @since 1.2.6
*/
public static Class> delegateClassOrSelf(Class> clazz){
Class> delegateClass = delegateClassOf(clazz);
return null == delegateClass ? clazz : delegateClass;
}
public static boolean isPrimitiveArray(Type type){
if(type instanceof Class>){
Class> clazz = (Class>)type;
return clazz.isArray() && clazz.getComponentType().isPrimitive();
}
return false;
}
public static boolean isThriftBuildinType(Type type){
return THRIFT_BUILTIN_KNOWNTYPES.contains(type);
}
public static boolean isPrimitivefloat(Type type){
return type == float.class;
}
public static boolean isfloat(Type type){
return type == float.class || type == Float.class;
}
public static boolean isCastType(Type type){
return CAST_TYPES.containsKey(type);
}
public static boolean isException(Type type){
return null == type
? false
: Exception.class.isAssignableFrom(TypeToken.of(type).getRawType());
}
public static Constructor getConstructor(Class clazz,Class>...parameterTypes){
try {
return clazz.getConstructor(parameterTypes);
} catch (NoSuchMethodException e) {
return null;
}
}
public static boolean hasConstructor(Class clazz,Class>...parameterTypes){
return getConstructor(clazz,parameterTypes) != null;
}
public static boolean isThriftException(Type type){
return isException(type) && isThriftStruct(type);
}
public static boolean isThriftException(Type left, Type right){
return isThriftException(left) && isThriftException(right);
}
public static boolean needTransformer(Type type){
return ! isThriftBuildinType(type) && ! isfloat(type);
}
public static interface Action{
void doClass(Class> type);
}
public static void traverseTypes(Type type,Action action){
checkArgument(null !=action,"action is null");
if(type instanceof Class>){
action.doClass((Class>) type);
}else if( type instanceof ParameterizedType){
ParameterizedType paramType = (ParameterizedType)type;
Type rawType = paramType.getRawType();
Type[] typeArgs = paramType.getActualTypeArguments();
traverseTypes(rawType,action);
for(Type arg:typeArgs){
traverseTypes(arg,action);
}
}else if (type instanceof GenericArrayType) {
traverseTypes(((GenericArrayType) type).getGenericComponentType(),action);
} else if (type instanceof TypeVariable) {
for (Type t : ((TypeVariable>) type).getBounds()) {
traverseTypes(t,action);
}
} else if (type instanceof WildcardType) {
for (Type t : ((WildcardType) type).getLowerBounds()) {
traverseTypes(t,action);
}
for (Type t : ((WildcardType) type).getUpperBounds()) {
traverseTypes(t,action);
}
} else{
throw new IllegalArgumentException(String.format("not allow type %s", type.toString()));
}
}
@SuppressWarnings("serial")
public static TypeToken