001package com.facebook.swift.codec.metadata;
002
003import java.util.Collection;
004
005import javax.annotation.Nullable;
006import javax.annotation.concurrent.Immutable;
007
008import com.google.common.base.Function;
009import com.google.common.cache.CacheBuilder;
010import com.google.common.cache.CacheLoader;
011import com.google.common.cache.LoadingCache;
012import com.google.common.collect.Collections2;
013import com.google.common.collect.ImmutableList;
014
015/**
016 * {@link ThriftStructMetadata}的代理类<br>
017 * 重载所有{@link ThriftFieldMetadata}相关方法
018 * @author guyadong
019 *
020 */
021@Immutable
022public class DecoratorThriftStructMetadata extends ThriftStructMetadata {
023    /** {@link DecoratorThriftStructMetadata}缓存对象,
024     * 保存每个{@link ThriftStructMetadata}对应的{@link DecoratorThriftStructMetadata}实例 
025     */
026    private static final LoadingCache<ThriftStructMetadata,DecoratorThriftStructMetadata> 
027        STRUCTS_CACHE = 
028                CacheBuilder.newBuilder().build(
029                                new CacheLoader<ThriftStructMetadata,DecoratorThriftStructMetadata>(){
030                                                @Override
031                                                public DecoratorThriftStructMetadata load(ThriftStructMetadata key) throws Exception {
032                                                        return new DecoratorThriftStructMetadata(key);
033                                                }});
034    /**  将{@link ThriftStructMetadata}转换为 {@link DecoratorThriftStructMetadata}对象 */
035    public static final Function<ThriftStructMetadata,ThriftStructMetadata> 
036        STRUCT_TRANSFORMER = new Function<ThriftStructMetadata,ThriftStructMetadata>(){
037                @Nullable
038                        @Override
039                        public ThriftStructMetadata apply(@Nullable ThriftStructMetadata input) {
040                                return null == input || input instanceof DecoratorThriftStructMetadata
041                                                ? input
042                                                : STRUCTS_CACHE.getUnchecked(input);
043                        }};
044            /** 
045             * {@link DecoratorThriftFieldMetadata}缓存对象,
046             * 保存每个{@link ThriftFieldMetadata}对应的{@link DecoratorThriftFieldMetadata}实例 
047             */
048            private final LoadingCache<ThriftFieldMetadata,DecoratorThriftFieldMetadata> 
049                FIELDS_CACHE = 
050                        CacheBuilder.newBuilder().build(
051                                        new CacheLoader<ThriftFieldMetadata,DecoratorThriftFieldMetadata>(){
052                                                        @Override
053                                                        public DecoratorThriftFieldMetadata load(ThriftFieldMetadata key) throws Exception {
054                                                                return new DecoratorThriftFieldMetadata(key);
055                                                        }});
056            /**  将{@link ThriftFieldMetadata}转换为 {@link DecoratorThriftFieldMetadata}对象 */
057                private  final Function<ThriftFieldMetadata,ThriftFieldMetadata> 
058                        FIELD_TRANSFORMER = 
059                                new Function<ThriftFieldMetadata,ThriftFieldMetadata>(){
060                                        @Nullable
061                                        @Override
062                                        public ThriftFieldMetadata apply(@Nullable ThriftFieldMetadata input) {
063                                            return null == input || input instanceof DecoratorThriftFieldMetadata  
064                                                        ? input 
065                                                        : FIELDS_CACHE.getUnchecked(input);
066                                        }};
067        private DecoratorThriftStructMetadata(ThriftStructMetadata input){
068                super(input.getStructName(), 
069                                input.getStructType(), 
070                                input.getBuilderType(), 
071                                input.getMetadataType(), 
072                                input.getBuilderMethod(), 
073                                input.getDocumentation(), 
074                                ImmutableList.copyOf(input.getFields()),
075                                input.getConstructorInjection(), 
076                                input.getMethodInjections());
077        }
078        @Override
079        public ThriftFieldMetadata getField(int id) {
080                return FIELD_TRANSFORMER.apply(super.getField(id));
081        }
082
083        @Override
084        public Collection<ThriftFieldMetadata> getFields() {
085                return Collections2.transform(super.getFields(), FIELD_TRANSFORMER);
086        }
087
088        @Override
089        public Collection<ThriftFieldMetadata> getFields(FieldKind type) {
090                return Collections2.transform(super.getFields(type), FIELD_TRANSFORMER);
091        }
092
093}