net.gdface.thrift.ThriftUtils Maven / Gradle / Ivy
package net.gdface.thrift;
import static com.facebook.swift.codec.metadata.FieldKind.THRIFT_FIELD;
import static com.google.common.base.Preconditions.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URL;
import java.nio.ByteBuffer;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
import org.apache.thrift.TApplicationException;
import org.apache.thrift.protocol.TProtocolException;
import com.facebook.swift.codec.ThriftField.Requiredness;
import com.facebook.swift.codec.metadata.ThriftConstructorInjection;
import com.facebook.swift.codec.metadata.ThriftFieldMetadata;
import com.facebook.swift.codec.metadata.ThriftParameterInjection;
import com.facebook.swift.codec.metadata.ThriftStructMetadata;
import com.facebook.swift.service.RuntimeTApplicationException;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
/**
* thrift工具
* @author guyadong
*
*/
public class ThriftUtils extends 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 ThriftUtils() {
}
/**
* 构造{@code metadata}指定类型的实例并填充字段
* 参见 com.facebook.swift.codec.internal.reflection.ReflectionThriftStructCodec#constructStruct(Map)
* @param data
* @param metadata
* @return T instance
* @throws Exception
*/
@SuppressWarnings("unchecked")
public static T constructStruct(Map data,ThriftStructMetadata metadata)
throws Exception{
T instance;
{
ThriftConstructorInjection constructor = metadata.getConstructorInjection().get();
Type[] dstTypes = constructor.getConstructor().getGenericParameterTypes();
Type[] srcTypes = new Type[constructor.getParameters().size()];
Object[] parametersValues = new Object[constructor.getParameters().size()];
checkState(dstTypes.length == parametersValues.length);
for (ThriftParameterInjection parameter : constructor.getParameters()) {
TypeValue value = data.get(parameter.getId());
parametersValues[parameter.getParameterIndex()] = value.value;
srcTypes[parameter.getParameterIndex()] = value.type;
}
for(int i =0;i
* 参见 com.facebook.swift.codec.internal.reflection.ReflectionThriftStructCodec#constructStruct(Map)
* @param data
* @param metadata
* @param instance
* @return always instance
* @throws Exception
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static T fillStructField(Map data,ThriftStructMetadata metadata,T instance)
throws Exception{
return (T) fillStructField((Map)data,metadata,instance,TypeTransformer.getInstance(),true);
}
/**
* 根据{@code metadata}类型数据获取{@code instance}实例所有的字段值
* 参见 com.facebook.swift.codec.internal.reflection.ReflectionThriftStructCodec#write(Object, org.apache.thrift.protocol.TProtocol)
* @param instance
* @param metadata
* @return 字段值映射表
*/
public static Map getFieldValues(Object instance, ThriftStructMetadata metadata) {
checkArgument(null != instance && null != metadata && metadata.getStructClass().isInstance(instance),
"instance,metadata must not be null");
Collection fields = metadata.getFields(THRIFT_FIELD);
Map data = new HashMap<>(fields.size());
for (ThriftFieldMetadata field : fields) {
try {
// is the field readable?
if (field.isWriteOnly()) {
continue;
}
TypeValue value = getFieldValue(instance, field);
if (value.value == null) {
if (field.getRequiredness() == Requiredness.REQUIRED) {
throw new TProtocolException("required field was not set");
} else {
continue;
}
}
data.put(field.getId(), value);
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
throw new RuntimeException(e);
}
}
return data;
}
/**
* @param instance
* @param metadata
* @return field values
* @deprecated name spell error, replaced by {@link #getFieldValues(Object, ThriftStructMetadata)}
*/
public static Map getFiledValues(Object instance, ThriftStructMetadata metadata) {
return getFieldValues(instance,metadata);
}
/** 避免{@code null}抛出异常 */
public static T returnNull(RuntimeTApplicationException e){
Throwable cause = e.getCause();
if (cause instanceof TApplicationException
&& ((TApplicationException) cause).getType() == TApplicationException.MISSING_RESULT){
return null;
}
throw e;
}
/** 避免{@code null}抛出异常
* @throws Throwable */
public static T returnNull(Throwable e) throws Throwable{
if(e instanceof RuntimeTApplicationException){
return returnNull((RuntimeTApplicationException)e);
}
throw e;
}
public static void addCallback(
final ListenableFuture future,
final FutureCallback super V> callback,Executor executor) {
checkArgument(null != callback,"callback is null");
checkArgument(null != executor,"executor is null");
Runnable callbackListener =
new Runnable() {
@Override
public void run() {
V value;
try {
value = Futures.getDone(future);
} catch (ExecutionException e) {
try{
// value is null
value = returnNull(e.getCause());
}catch(Throwable t){
callback.onFailure(t);
return;
}
} catch (Throwable e) {
callback.onFailure(e);
return;
}
callback.onSuccess(value);
}
};
future.addListener(callbackListener, executor);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy