001package net.gdface.codegen.thrift;
002
003import org.apache.commons.configuration2.Configuration;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007import com.google.common.base.Function;
008import com.google.common.base.Predicate;
009import com.google.common.collect.ImmutableMap;
010import com.google.common.collect.Maps;
011import com.google.common.collect.Sets;
012
013import net.gdface.annotation.DeriveMethod;
014
015import static com.google.common.base.Preconditions.*;
016import static net.gdface.utils.FaceUtilits.*;
017
018import java.lang.reflect.Method;
019import java.util.Arrays;
020import java.util.Map;
021import java.util.Set;
022
023/**
024 * 根据配置文件提供的过滤参数对接口中的方法进行过滤
025 * @author guyadong
026 *
027 */
028public class MethodFilter implements Predicate<Method>{
029        private static final Logger logger = LoggerFactory.getLogger(MethodFilter.class);
030        private static final String SUFFIX_INCLUDE =".include";
031        private static final String SUFFIX_EXCLUDE =".exclude";
032
033        private final Configuration configuration = ThriftServiceDecoratorConfiguration.INSTANCE.getConfig();
034        private Set<Method> includeMethods;
035        private Set<Method> excludeMethods;
036        public MethodFilter(Class<?> interfaceClass) {
037                checkArgument(interfaceClass != null,"interfaceClass is null");
038                ImmutableMap<String, Method> methods = Maps.uniqueIndex(Arrays.asList(interfaceClass.getDeclaredMethods()), new Function<Method, String>() {
039
040                        @Override
041                        public String apply(Method input) {
042                                StringBuffer buffer = new StringBuffer(input.getName());
043                                DeriveMethod dm = input.getAnnotation(DeriveMethod.class);
044                                if(dm != null && dm.methodSuffix().length > 0){
045                                        buffer.append('.').append(dm.methodSuffix()[0]);
046                                }
047                                return buffer.toString();
048                        }
049                });
050                String includeKey = interfaceClass.getName() + SUFFIX_INCLUDE;
051                String excludeKey = interfaceClass.getName() + SUFFIX_EXCLUDE;
052                includeMethods = getMethodList(includeKey,interfaceClass,methods);
053                excludeMethods = getMethodList(excludeKey,interfaceClass,methods);
054                if(!includeMethods.isEmpty() && !excludeMethods.isEmpty()){
055                        logger.warn("{} and {} all defined, this first used preferentially",includeKey,excludeKey);
056                }
057        }
058
059        private Set<Method> getMethodList(String key,Class<?> interfaceClass,Map<String, Method> methods){
060                Set<Method> sets = Sets.newHashSet();
061                if(configuration.containsKey(key)){
062                        for(String port:elementsOf(configuration.getString(key))){
063                                if(!methods.containsKey(port)){
064                                        logger.warn("NOT FOUND Method named '{}' in {}",port,interfaceClass.getName());                         
065                                        continue;
066                                }                       
067                                sets.add(methods.get(port));
068                        }
069                }
070                return sets;
071        }
072
073        @Override
074        public boolean apply(Method input) {
075                if(!includeMethods.isEmpty()){
076                        return includeMethods.contains(input);
077                }
078                if(!excludeMethods.isEmpty()){
079                        return !excludeMethods.contains(input);
080                }
081                return true;
082        }
083        
084        
085}