001package com.facebook.swift.codec.metadata; 002 003import static com.google.common.base.Preconditions.checkState; 004 005import java.lang.reflect.Type; 006import java.util.List; 007import java.util.logging.Logger; 008 009import javax.annotation.concurrent.Immutable; 010 011import com.facebook.swift.codec.ThriftField.Requiredness; 012import com.facebook.swift.codec.metadata.ThriftFieldMetadata; 013import com.facebook.swift.codec.metadata.ThriftInjection; 014import com.facebook.swift.codec.metadata.ThriftParameterInjection; 015import com.google.common.primitives.Primitives; 016 017/** 018 * {@link ThriftFieldMetadata}的代ç†ç±»ï¼Œ 019 * é‡è½½{@link #getRequiredness()}æ–¹æ³•ï¼Œæ ¹æ®å‚数类型对返回值进行修改 020 * @author guyadong 021 * 022 */ 023@Immutable 024public class DecoratorThriftFieldMetadata extends ThriftFieldMetadata { 025 private static final Logger logger = Logger.getLogger(DecoratorThriftFieldMetadata.class.getName()); 026 private static Boolean primitiveOptional = null; 027 private static Boolean objectOptional = null; 028 private final Type javaType; 029 public DecoratorThriftFieldMetadata(ThriftFieldMetadata input){ 030 super( 031 input.getId(), 032 input.getRequiredness(), 033 input.getThriftType(), 034 input.getName(), 035 input.getType(), 036 input.getInjections(), 037 input.getConstructorInjection(), 038 input.getMethodInjection(), 039 input.getExtraction(), 040 input.getCoercion()); 041 // 获å–field的类型 042 List<ThriftInjection> injections = getInjections(); 043 checkState(injections.size()>0,"invalid size of injections"); 044 ThriftInjection injection = injections.get(0); 045 if(injection instanceof ThriftParameterInjection){ 046 javaType = ((ThriftParameterInjection)injection).getJavaType(); 047 }else if(injection instanceof ThriftFieldInjection){ 048 javaType = ((ThriftFieldInjection)injection).getField().getType(); 049 }else{ 050 javaType = null; 051 // å¯¹äºŽä¸æ”¯æŒçš„æ•°æ®ç±»åž‹æ— 法获å–field类型,输出è¦å‘Š 052 logger.warning( 053 String.format("UNSUPPORED TYPE %s,can't get Java Type. " 054 + "(ä¸è¯†åˆ«çš„ThriftInjectionå®žä¾‹ç±»åž‹ï¼Œæ— æ³•å®žçŽ°requiredness转义)", 055 null == injection? null : injection.getClass().getName())); 056 } 057 } 058 /** é‡è½½æ–¹æ³•,实现 requiredness 转义 */ 059 @Override 060 public Requiredness getRequiredness() { 061 Requiredness requiredness = super.getRequiredness(); 062 checkState(Requiredness.UNSPECIFIED != requiredness); 063 // 当为primitive类型时,Requiredness 为REQUIRED 064 // 当为primitive类型的Objectå°è£…类型时(Long,Integer,Boolean),Requiredness为OPTIONAL 065 if(Boolean.TRUE.equals(objectOptional) && requiredness == Requiredness.NONE){ 066 if(javaType instanceof Class<?>) 067 { 068 Class<?> parameterClass = (Class<?>)javaType; 069 if(parameterClass.isPrimitive()){ 070 requiredness = Requiredness.REQUIRED; 071 }else { 072 requiredness = Requiredness.OPTIONAL; 073 } 074 }else{ 075 requiredness = Requiredness.OPTIONAL; 076 } 077 }else if( !Boolean.FALSE.equals(primitiveOptional) 078 && javaType instanceof Class<?> 079 && requiredness == Requiredness.NONE){ 080 Class<?> parameterClass = (Class<?>)javaType; 081 if(parameterClass.isPrimitive()){ 082 requiredness = Requiredness.REQUIRED; 083 // logger.info(String.format("%s %s", parameterClass.getSimpleName(),requiredness)); 084 }else if(Primitives.isWrapperType(parameterClass)){ 085 requiredness = Requiredness.OPTIONAL; 086 // logger.info(String.format("%s %s", parameterClass.getSimpleName(),requiredness)); 087 } 088 } 089 return requiredness; 090 } 091 /** 092 * 设置primitiveOptionalæ ‡è®°<br> 093 * 指定{@link #getRequiredness}方法调用时是å¦å¯¹primitive类型åŠå…¶å°è£…类型(Integer,Long)傿•°çš„返回值进行替æ¢<br> 094 * 默认值:{@code true}<br> 095 * 该方法åªèƒ½è¢«è°ƒç”¨ä¸€æ¬¡ 096 * @param optional 097 * @see #getRequiredness() 098 * @throws IllegalStateException 方法已ç»è¢«è°ƒç”¨ 099 */ 100 public static synchronized void setPrimitiveOptional(boolean optional) { 101 checkState(null == DecoratorThriftFieldMetadata.primitiveOptional,"primitiveOptional is initialized already."); 102 DecoratorThriftFieldMetadata.primitiveOptional = optional; 103 } 104 /** 105 * 设置ObjectOptionalæ ‡è®°<br> 106 * 指定{@link #getRequiredness}方法调用时是å¦å¯¹Objectç±»åž‹å‚æ•°çš„返回值进行替æ¢<br> 107 * 默认值:{@code true}<br> 108 * 该方法åªèƒ½è¢«è°ƒç”¨ä¸€æ¬¡ 109 * @param optional 110 * @see #getRequiredness() 111 * @throws IllegalStateException 方法已ç»è¢«è°ƒç”¨ 112 */ 113 public static synchronized void setObjectOptional(Boolean optional) { 114 checkState(null == DecoratorThriftFieldMetadata.objectOptional,"ObjectOptional is initialized already."); 115 DecoratorThriftFieldMetadata.objectOptional = optional; 116 } 117 118}