All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.gdface.thrift.EnumThriftCodec Maven / Gradle / Ivy

The newest version!
package net.gdface.thrift;
import com.facebook.swift.codec.ThriftCodec;
import com.facebook.swift.codec.ThriftProtocolType;
import com.facebook.swift.codec.internal.UnknownEnumValueException;
import com.facebook.swift.codec.metadata.ThriftCatalogWithTransformer;
import com.facebook.swift.codec.metadata.ThriftEnumMetadata;
import com.facebook.swift.codec.metadata.ThriftType;
import com.gitee.l0km.aocache.annotations.AoCacheable;
import com.gitee.l0km.aocache.annotations.AoWeakCacheable;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;

import org.apache.thrift.protocol.TJSONProtocolXthrift;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.protocol.TProtocolSupport;

import javax.annotation.concurrent.Immutable;

/**
 * 支持负值的枚举类型编解码器
* 在默认枚举类型编解码器{@link com.facebook.swift.codec.internal.EnumThriftCodec}基础上删除非负值判断
* 当为{@link TJSONProtocolXthrift}时支持自动判断字段类型(STRING/I32)反序列化。并支持序列化为STRING
*/ @Immutable public class EnumThriftCodec> implements ThriftCodec { private final ThriftType type; private final ThriftEnumMetadata enumMetadata; @SuppressWarnings("unchecked") public EnumThriftCodec(ThriftType type) { this.type = type; enumMetadata = (ThriftEnumMetadata) type.getEnumMetadata(); } @Override public ThriftType getType() { return type; } @Override public T read(TProtocol protocol) throws Exception { Object enumValue; TJSONProtocolXthrift jsonsProtocol = TProtocolSupport.fetchJSONXthrift(protocol); if (null != jsonsProtocol) { enumValue = jsonsProtocol.readJSONStringOrInteger(); }else { enumValue = protocol.readI32(); } return read(enumValue); } @Override public void write(T enumConstant, TProtocol protocol) throws Exception { boolean enumValueAsString = false; TJSONProtocolXthrift jsonsProtocol = TProtocolSupport.fetchJSONXthrift(protocol); if(null != jsonsProtocol) { enumValueAsString = jsonsProtocol.enumValueAsString(); } write(enumConstant,protocol,enumValueAsString); } private void write(T enumConstant, TProtocol protocol,boolean enumValueAsString) throws Exception { Preconditions.checkNotNull(enumConstant, "enumConstant is null"); if(enumValueAsString) { protocol.writeString(enumConstant.name()); }else { int enumValue; if (enumMetadata.hasExplicitThriftValue()) { enumValue = enumMetadata.getByEnumConstant().get(enumConstant); } else { enumValue = enumConstant.ordinal(); } protocol.writeI32(enumValue); } } private T read(int enumValue) throws Exception { if (enumMetadata.hasExplicitThriftValue()) { T enumConstant = enumMetadata.getByEnumValue().get(enumValue); if (enumConstant != null) { return enumConstant; } } else { T[] enumConstants = enumMetadata.getEnumClass().getEnumConstants(); if (enumValue < enumConstants.length) { return enumConstants[enumValue]; } } // unknown, throw unknown value exception throw new UnknownEnumValueException( String.format( "Enum %s does not have a value for %s", enumMetadata.getEnumClass(), enumValue ) ); } private T read(String enumName) throws Exception { T value = enumNamesMapOf(enumMetadata.getEnumClass()).get(enumName); if (value != null) { return value; } // unknown, throw unknown value exception throw new UnknownEnumValueException( String.format( "Enum %s does not have a value for %s", enumMetadata.getEnumClass(), enumName ) ); } private T read(Object value) throws Exception { if(value instanceof Integer) { return read((int)value); }else { return read((String)value); } } @AoWeakCacheable protected static > ImmutableMap enumNamesMapOf(Class enumClass) { ImmutableMap.Builder builder= ImmutableMap.builder(); for(T e:enumClass.getEnumConstants()) { builder.put(e.name(), e); } return builder.build(); } /** * 生成指定枚举类型的编解码器 * @param type * @return EnumThriftCodec 实例 */ public static > EnumThriftCodec getCodec(Class type){ ThriftType thriftType = ThriftCatalogWithTransformer.CATALOG.getThriftType(type); return getCodec(thriftType); } /** * 生成指定枚举类型的编解码器 * @param type * @return EnumThriftCodec 实例 * @since 1.5.0 */ @AoCacheable public static > EnumThriftCodec getCodec(ThriftType thriftType){ return new EnumThriftCodec(thriftType); } /** * 如果是枚举类型编解码器则替换为自定义的{@link EnumThriftCodec}实例以支持不带类型的标准JSON格式数据协议 * @param * @param codec * @since 1.5.0 */ @SuppressWarnings("unchecked") public static ThriftCodec usingIfEnum(ThriftCodec codec) { if (ThriftProtocolType.ENUM.equals(codec.getType().getProtocolType()) && !(codec instanceof EnumThriftCodec)) { return (ThriftCodec) EnumThriftCodec.getCodec(codec.getType()); } return codec; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy