package ws.antonov.config.api.consumer; import com.google.protobuf.Message; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.util.Assert; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; /** * Copyright 2011 Alex Antonov * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @author aantonov * @since 0.1 */ public class ConfigClientInvocationHandler implements InvocationHandler { private ConfigClient configClient; private ParameterNameDiscoverer parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer(); public ConfigClientInvocationHandler(ConfigClient configClient) { this.configClient = configClient; } public Object invoke(Object o, Method method, Object[] objects) throws Throwable { ConfigParamsBuilder.ConfigParamsMap configParams = generateConfigParams(method, objects); Assert.isAssignable(Message.class, method.getReturnType()); return configClient.getConfig((Class<Message>) method.getReturnType(), configParams); } private ConfigParamsBuilder.ConfigParamsMap generateConfigParams(Method method, Object[] args) { ConfigParam[] configParamAnnotations = retrieveRequestParams(method); String[] parameterNames = parameterNameDiscoverer.getParameterNames(method); ConfigParamsBuilder configParamsBuilder = new ConfigParamsBuilder(); for (int i = 0; i < args.length; i++) { Object arg = args[i]; ConfigParam configParam = configParamAnnotations[i]; String paramName; if (parameterNames != null && (configParam == null || configParam.value() == "")) { paramName = parameterNames[i]; configParamsBuilder.addParam(paramName, arg); } else if (configParam != null && configParam.value().length() > 0) { paramName = configParam.value(); configParamsBuilder.addParam(paramName, arg); } } return configParamsBuilder.build(); } public static ConfigParam[] retrieveRequestParams(Method method) { Annotation[][] annotations = method.getParameterAnnotations(); ConfigParam[] paramNames = new ConfigParam[annotations.length]; for (int i = 0; i < annotations.length; i++) { Annotation[] anns = annotations[i]; paramNames[i] = null; for (Annotation ann : anns) { if (ConfigParam.class.isInstance(ann)) { paramNames[i] = (ConfigParam) ann; break; } } } return paramNames; } }