org.frameworkset.web.servlet.handler.annotations.DefaultAnnotationHandlerMapping Maven / Gradle / Ivy
Show all versions of bboss-mvc Show documentation
/*
* Copyright 2008 biaoping.yin
*
* 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.frameworkset.web.servlet.handler.annotations;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import org.frameworkset.util.ClassUtil;
import org.frameworkset.util.annotations.AnnotationUtils;
import org.frameworkset.util.annotations.HandlerMapping;
import org.frameworkset.util.annotations.HttpMethod;
import org.frameworkset.web.HttpRequestMethodNotSupportedException;
import org.frameworkset.web.servlet.handler.AbstractDetectingUrlHandlerMapping;
import org.frameworkset.web.servlet.handler.HandlerUtils;
import com.frameworkset.util.StringUtil;
/**
* Title: DefaultAnnotationHandlerMapping.java
* Description:
* bboss workgroup
* Copyright (c) 2008
* @Date 2010-10-23
* @author biaoping.yin
* @version 1.0
*/
public class DefaultAnnotationHandlerMapping extends AbstractDetectingUrlHandlerMapping {
private boolean useDefaultSuffixPattern = true;
private Map cachedMappings = new HashMap();
/**
* Set whether to register paths using the default suffix pattern as well:
* i.e. whether "/users" should be registered as "/users.*" too.
* Default is "true". Turn this convention off if you intend to interpret
* your @HandlerMapping
paths strictly.
*
Note that paths which include a ".xxx" suffix already will not be
* transformed using the default suffix pattern in any case.
*/
public void setUseDefaultSuffixPattern(boolean useDefaultSuffixPattern) {
this.useDefaultSuffixPattern = useDefaultSuffixPattern;
}
// /**
// * Checks for presence of the {@link org.frameworkset.util.annotations.HandlerMapping}
// * annotation on the handler class and on any of its methods.
// */
// protected String[] determineUrlsForHandler(String beanName) {
// ApplicationContext context = getApplicationContext();
// Pro beaninfos = context.getProBean(beanName);
// if(!beaninfos.isBean())
// return null;
// Class> handlerType = beaninfos.getBeanClass();
//// ListableBeanFactory bf = (context instanceof ConfigurableApplicationContext ?
//// ((ConfigurableApplicationContext) context).getBeanFactory() : context);
//// GenericBeanFactoryAccessor bfa = new GenericBeanFactoryAccessor(bf);
//
// //获取类级url和controller映射关系
// HandlerMapping mapping = AnnotationUtils.findAnnotation(handlerType, HandlerMapping.class);
//
// if (mapping != null) {
// // @HandlerMapping found at type level
// this.cachedMappings.put(handlerType, mapping);
// Set urls = new LinkedHashSet();
// String[] paths = mapping.value();
// if (paths.length > 0) {
// // @HandlerMapping specifies paths at type level
// for (String path : paths) {
// addUrlsForPath(urls, path);
// }
//
// return StringUtil.toStringArray(urls);
// }
// else {
// // actual paths specified by @HandlerMapping at method level
// return determineUrlsForHandlerMethods(handlerType);
// }
// }
// else if (AnnotationUtils.findAnnotation(handlerType, Controller.class) != null) {
// // @HandlerMapping to be introspected at method level
// return determineUrlsForHandlerMethods(handlerType);
// }
// else {
// return null;
// }
// }
protected String[] determineUrlsForHandler(String beanName) {
return HandlerUtils.determineUrlsForHandler(getApplicationContext(), beanName, cachedMappings);
}
// /**
// * Checks for presence of the {@link org.frameworkset.util.annotations.HandlerMapping}
// * annotation on the handler class and on any of its methods.
// */
// protected String[] determineUrlsForHandler(String beanName) {
// ApplicationContext context = getApplicationContext();
// Pro beaninfos = context.getProBean(beanName);
// if(!beaninfos.isBean())
// return null;
// final Class> handlerType = beaninfos.getBeanClass();
//// ListableBeanFactory bf = (context instanceof ConfigurableApplicationContext ?
//// ((ConfigurableApplicationContext) context).getBeanFactory() : context);
//// GenericBeanFactoryAccessor bfa = new GenericBeanFactoryAccessor(bf);
//
// //获取类级url和controller映射关系
// HandlerMapping mapping = AnnotationUtils.findAnnotation(handlerType, HandlerMapping.class);
//
// if (mapping != null) {
// // @HandlerMapping found at type level
// this.cachedMappings.put(handlerType, mapping);
//
// Set urls = new LinkedHashSet();
// final Set handlerMethods = new LinkedHashSet();
// ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
// public void doWith(Method method) {
// if (method.isAnnotationPresent(HandlerMapping.class)) {
// handlerMethods.add(ClassUtils.getMostSpecificMethod(method, handlerType));
// }
// }
// });
// String[] paths = mapping.value();
// if (paths.length > 0) {
// // @HandlerMapping specifies paths at type level
// for (String path : paths) {
//
//
// if(mapping.restful())
// {
// this.addUrlsForRestfulPath(urls, path, handlerMethods);
// }
// else
// {
// addUrlsForPath(urls, path);
// }
// }
//
// return StringUtil.toStringArray(urls);
// }
// else {
// // actual paths specified by @HandlerMapping at method level
// return determineUrlsForHandlerMethods(handlerType);
// }
// }
// else if (AnnotationUtils.findAnnotation(handlerType, Controller.class) != null) {
// // @HandlerMapping to be introspected at method level
// return determineUrlsForHandlerMethods(handlerType);
// }
// else {
// return null;
// }
// }
// /**
// * Derive URL mappings from the handler's method-level mappings.
// * @param handlerType the handler type to introspect
// * @return the array of mapped URLs
// */
// protected String[] determineUrlsForHandlerMethods(Class> handlerType) {
// final Set urls = new LinkedHashSet();
// ReflectionUtils.doWithMethods(handlerType, new ReflectionUtils.MethodCallback() {
// public void doWith(Method method) {
// HandlerMapping mapping = method.getAnnotation(HandlerMapping.class);
// if (mapping != null) {
// String[] mappedPaths = mapping.value();
// for (int i = 0; i < mappedPaths.length; i++) {
// addUrlsForPath(urls, mappedPaths[i]);
// }
// }
// }
// });
// return StringUtil.toStringArray(urls);
// }
//
// /**
// * Add URLs and/or URL patterns for the given path.
// * @param urls the Set of URLs for the current bean
// * @param path the currently introspected path
// */
// protected void addUrlsForPath(Set urls, String path) {
//// Iterator methods = handlermethods.iterator();
//// while(methods.hasNext())
//// {
//// urls.addAll(this.getUrl(path, restful, methods.next()));
// urls.add(path);
// if (this.useDefaultSuffixPattern && path.indexOf('.') == -1) {
// urls.add(path + ".*");
// }
//// }
// }
//
// /**
// * Add URLs and/or URL patterns for the given path.
// * @param urls the Set of URLs for the current bean
// * @param path the currently introspected path
// */
// protected void addUrlsForRestfulPath(Set urls, String path,Set handlermethods) {
// Iterator methods = handlermethods.iterator();
// while(methods.hasNext())
// {
// urls.addAll(this.getRestfulUrl(path, methods.next()));
//
// }
// }
//
//// protected int convert(HttpMethod requestMethod)
//// {
////
//// }
// protected Set getRestfulUrl(String path, Method method)
// {
//
// String url = path;
// Set urls = new LinkedHashSet();
// HandlerMapping mapping = method.getAnnotation(HandlerMapping.class);
//// MethodInfo methodInfo = new MethodInfo(method);
// String[] mappedPaths = mapping.value();
// if (mappedPaths != null && mappedPaths.length > 0) {
// String mappedPath = mappedPaths[0];
// StringBuilder pathUrl = new StringBuilder();
// pathUrl.append(url);
// for(int i = 0; i < mappedPath.length(); i ++ )
// {
// if(mappedPath.charAt(i) == '/')
// pathUrl.append("/*");
//
// }
// urls.add(pathUrl.toString());
// pathUrl = null;
// }
// else
// {
// urls.add(url);
// }
// return urls;
//
// }
/**
* Validate the given annotated handler against the current request.
* @see #validateMapping
*/
protected void validateHandler(Object handler, HttpServletRequest request) throws Exception {
HandlerMapping mapping = this.cachedMappings.get(ClassUtil.getClassInfo(handler.getClass()).getClazz());
if (mapping == null) {
mapping = AnnotationUtils.findAnnotation(ClassUtil.getClassInfo(handler.getClass()).getClazz(), HandlerMapping.class);
}
if (mapping != null) {
validateMapping(mapping, request);
}
}
/**
* Validate the given type-level mapping metadata against the current request,
* checking HTTP request method and parameter conditions.
* @param mapping the mapping metadata to validate
* @param request current HTTP request
* @throws Exception if validation failed
*/
protected void validateMapping(HandlerMapping mapping, HttpServletRequest request) throws Exception {
HttpMethod[] mappedMethods = mapping.method();
if (!ServletAnnotationMappingUtils.checkRequestMethod(mappedMethods, request)) {
String[] supportedMethods = new String[mappedMethods.length];
for (int i = 0; i < mappedMethods.length; i++) {
supportedMethods[i] = mappedMethods[i].name();
}
throw new HttpRequestMethodNotSupportedException(request.getMethod(), supportedMethods);
}
String[] mappedParams = mapping.params();
if (!ServletAnnotationMappingUtils.checkParameters(mappedParams, request)) {
throw new ServletException("Parameter conditions {" +
StringUtil.arrayToDelimitedString(mappedParams, ", ") +
"} not met for request parameters: " + request.getParameterMap());
}
}
@Override
public void destroy() {
// TODO Auto-generated method stub
super.destroy();
if(cachedMappings != null)
{
cachedMappings.clear();
cachedMappings = null;
}
}
}