Java tutorial
/* * Copyright (c) 2011-2012 by the original author or authors. * * 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. */ package io.dyn.core.handler; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; import io.dyn.core.handler.anno.Handler; import io.dyn.core.handler.anno.On; import io.dyn.core.handler.anno.Value; import io.dyn.core.handler.anno.When; import io.dyn.el.SpelExpression; import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.expression.BeanFactoryResolver; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.expression.Expression; import org.springframework.expression.ParserContext; import org.springframework.expression.spel.support.StandardEvaluationContext; import org.springframework.util.ReflectionUtils; /** * @author Jon Brisbin <jon@jbrisbin.com> */ public class AnnotationHandlerMethodResolver implements HandlerMethodResolver, ApplicationContextAware { //protected static final Logger log = Logger.logger(AnnotationHandlerMethodResolver.class); protected static ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new LocalVariableTableParameterNameDiscoverer(); protected ApplicationContext applicationContext; protected StandardEvaluationContext evalCtx = new StandardEvaluationContext(); @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (null != applicationContext) { this.applicationContext = applicationContext; evalCtx.setBeanResolver(new BeanFactoryResolver(this.applicationContext)); } } @Override public boolean supports(final Class<?> aClass) { boolean classLevelAnno = (null != AnnotationUtils.findAnnotation(aClass, Handler.class)); final AtomicBoolean hasHandlerMethod = new AtomicBoolean(false); Class<?> clazz = aClass; while (null != clazz && clazz != Object.class) { ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { if (!hasHandlerMethod.get()) { hasHandlerMethod.set(true); } } }, Handlers.USER_METHODS); clazz = clazz.getSuperclass(); } return (hasHandlerMethod.get() || classLevelAnno); } @Override public Map<Object, HandlerMethod> resolve(Class<?> aClass, Object... args) { final Map<Object, HandlerMethod> handlerMethods = new HashMap<>(); //log.debug("Finding handler methods in %s", aClass); Class<?> clazz = aClass; while (null != clazz && clazz != Object.class) { ReflectionUtils.doWithMethods(clazz, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Class<?>[] paramTypes = method.getParameterTypes(); String[] paramNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method); HandlerMethodArgument[] handlerMethodArgs = new HandlerMethodArgument[paramTypes.length]; Annotation[][] paramAnnos = method.getParameterAnnotations(); Expression[] valueExpressions = new Expression[paramTypes.length]; for (int i = 0; i < paramTypes.length; i++) { String paramName = (null != paramNames ? paramNames[i] : "arg" + i); if (paramAnnos[i].length > 0) { for (int j = 0; j < paramAnnos[i].length; j++) { if (paramAnnos[i][j] instanceof Value) { valueExpressions[i] = SpelExpression.DEFAULT_PARSER .parseExpression(((Value) paramAnnos[i][j]).value()); break; } } } handlerMethodArgs[i] = new HandlerMethodArgument(i, paramName, paramTypes[i], valueExpressions[i]); } Guard guard = null; When when = Handlers.find(When.class, method); if (null != when) { guard = new Guard(SpelExpression.DEFAULT_PARSER.parseExpression(when.value())); } On on = Handlers.find(On.class, method); String eventName = Handlers.findEventName(method); if (null != eventName) { Object key = eventName; if (eventName.contains("#{")) { key = SpelExpression.DEFAULT_PARSER.parseExpression(eventName, ParserContext.TEMPLATE_EXPRESSION); } handlerMethods.put(key, new HandlerMethod(method, handlerMethodArgs, guard)); } } }, Handlers.USER_METHODS); clazz = clazz.getSuperclass(); } return (handlerMethods.size() > 0 ? handlerMethods : null); } }