org.springframework.web.bind.annotation.support.HandlerMethodResolver Maven / Gradle / Ivy
/*
* Copyright 2002-2015 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 org.springframework.web.bind.annotation.support;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
/**
* Support class for resolving web method annotations in a handler type.
* Processes {@code @RequestMapping}, {@code @InitBinder},
* {@code @ModelAttribute} and {@code @SessionAttributes}.
*
* Used by {@link org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter}
* and {@link org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter}.
*
* @author Juergen Hoeller
* @since 2.5.2
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.web.bind.annotation.InitBinder
* @see org.springframework.web.bind.annotation.ModelAttribute
* @see org.springframework.web.bind.annotation.SessionAttributes
* @deprecated as of 4.3, in favor of the {@code HandlerMethod}-based MVC infrastructure
*/
@Deprecated
public class HandlerMethodResolver {
private final Set handlerMethods = new LinkedHashSet();
private final Set initBinderMethods = new LinkedHashSet();
private final Set modelAttributeMethods = new LinkedHashSet();
private RequestMapping typeLevelMapping;
private boolean sessionAttributesFound;
private final Set sessionAttributeNames = new HashSet();
private final Set> sessionAttributeTypes = new HashSet>();
private final Set actualSessionAttributeNames =
Collections.newSetFromMap(new ConcurrentHashMap(4));
/**
* Initialize a new HandlerMethodResolver for the specified handler type.
* @param handlerType the handler class to introspect
*/
public void init(final Class handlerType) {
Set> handlerTypes = new LinkedHashSet>();
Class specificHandlerType = null;
if (!Proxy.isProxyClass(handlerType)) {
handlerTypes.add(handlerType);
specificHandlerType = handlerType;
}
handlerTypes.addAll(Arrays.asList(handlerType.getInterfaces()));
for (Class currentHandlerType : handlerTypes) {
final Class targetClass = (specificHandlerType != null ? specificHandlerType : currentHandlerType);
ReflectionUtils.doWithMethods(currentHandlerType, new ReflectionUtils.MethodCallback() {
@Override
public void doWith(Method method) {
Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
Method bridgedMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
if (isHandlerMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isHandlerMethod(bridgedMethod))) {
handlerMethods.add(specificMethod);
}
else if (isInitBinderMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isInitBinderMethod(bridgedMethod))) {
initBinderMethods.add(specificMethod);
}
else if (isModelAttributeMethod(specificMethod) &&
(bridgedMethod == specificMethod || !isModelAttributeMethod(bridgedMethod))) {
modelAttributeMethods.add(specificMethod);
}
}
}, ReflectionUtils.USER_DECLARED_METHODS);
}
this.typeLevelMapping = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
SessionAttributes sessionAttributes = AnnotationUtils.findAnnotation(handlerType, SessionAttributes.class);
this.sessionAttributesFound = (sessionAttributes != null);
if (this.sessionAttributesFound) {
this.sessionAttributeNames.addAll(Arrays.asList(sessionAttributes.names()));
this.sessionAttributeTypes.addAll(Arrays.asList(sessionAttributes.types()));
}
}
protected boolean isHandlerMethod(Method method) {
return AnnotationUtils.findAnnotation(method, RequestMapping.class) != null;
}
protected boolean isInitBinderMethod(Method method) {
return AnnotationUtils.findAnnotation(method, InitBinder.class) != null;
}
protected boolean isModelAttributeMethod(Method method) {
return AnnotationUtils.findAnnotation(method, ModelAttribute.class) != null;
}
public final boolean hasHandlerMethods() {
return !this.handlerMethods.isEmpty();
}
public final Set getHandlerMethods() {
return this.handlerMethods;
}
public final Set getInitBinderMethods() {
return this.initBinderMethods;
}
public final Set getModelAttributeMethods() {
return this.modelAttributeMethods;
}
public boolean hasTypeLevelMapping() {
return (this.typeLevelMapping != null);
}
public RequestMapping getTypeLevelMapping() {
return this.typeLevelMapping;
}
public boolean hasSessionAttributes() {
return this.sessionAttributesFound;
}
public boolean isSessionAttribute(String attrName, Class attrType) {
if (this.sessionAttributeNames.contains(attrName) || this.sessionAttributeTypes.contains(attrType)) {
this.actualSessionAttributeNames.add(attrName);
return true;
}
else {
return false;
}
}
public Set getActualSessionAttributeNames() {
return this.actualSessionAttributeNames;
}
}