Java tutorial
/** * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). * * Licensed under the GPL, Version 3.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.gnu.org/licenses/gpl.html * * 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.tinygroup.springmvc.coc.impl; import org.apache.commons.lang.StringUtils; import org.springframework.util.PathMatcher; import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils.MethodFilter; 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.util.UrlPathHelper; import org.tinygroup.commons.tools.CollectionUtil; import org.tinygroup.springmvc.coc.ConventionHelper; import org.tinygroup.springmvc.coc.CustomHandlerMethodResolver; import org.tinygroup.springmvc.coc.Qualifier; import org.tinygroup.springmvc.util.WebUtil; import javax.servlet.http.HttpServletRequest; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.*; /** * * @author kevin.luy * @since 2014723 */ public abstract class AbstractConventionHandlerMethodResolver implements CustomHandlerMethodResolver { private final Map<String, Method> implicitHandlerMethods = new HashMap<String, Method>(); private Qualifier qualifier; private ConventionHelper conventionHelper; private Class<?> handlerType; public void setQualifier(Qualifier qualifier) { this.qualifier = qualifier; } public Class<?> getHandlerType() { return handlerType; } public AbstractConventionHandlerMethodResolver(Class<?> handlerType, ConventionHelper conventionHelper) { this.handlerType = handlerType; this.conventionHelper = conventionHelper; } public Collection<Method> getAllHandlerMethods() { return implicitHandlerMethods.values(); } /** * uri?? */ public Method getHandlerMethod(HttpServletRequest request) { String requestUri = getUrlPathHelper().getLookupPathForRequest(request); Method mtd = this.getHandlerMethodInternal(request, WebUtil.getUriWithoutExtension(requestUri)); if (mtd != null) { request.removeAttribute(RestfulConventionHandlerMethodResolver.RESTFUL_CONVENTION_VIEW_PATH); } return mtd; } private Method getHandlerMethodInternal(HttpServletRequest request, String noExtPath) { return getHandlerMethod(generateUriKey(request, noExtPath)); } protected String generateUriKey(HttpServletRequest request, String lookupPath) { return lookupPath; } protected Method getHandlerMethod(String urlKey) { return implicitHandlerMethods.get(urlKey); } protected UrlPathHelper getUrlPathHelper() { return this.conventionHelper.getUrlPathHelper(); } protected PathMatcher getPathMatcher() { return this.conventionHelper.getPathMatcher(); } protected void registerHandlerMethod(String urlKey, Method handlerMethod) { implicitHandlerMethods.put(urlKey, handlerMethod); } public Set<String> resolve() { final Set<String> urlList = new HashSet<String>();// for this handler String className = handlerType.getName(); // final StringBuilder uri = new StringBuilder("/"); int lastpos = className.indexOf("." + conventionHelper.getHandlerStyle()); int startpos = className.indexOf("web."); startpos += 5; String path = StringUtils.EMPTY; if (startpos < lastpos) { path = StringUtils.substring(className, startpos, lastpos); path = path.replace(".", "/"); uri.append(path).append("/"); } // uri-prefix. => /namespace/ String resourcesName = conventionHelper.getHandlerName(getHandlerType()); uri.append(resourcesName); ReflectionUtils.doWithMethods(getHandlerType(), new ReflectionUtils.MethodCallback() { public void doWith(Method method) { if (!qualify(method)) { return; } // method should be public. if (!Modifier.isPublic(method.getModifiers())) { return; } if (method.isAnnotationPresent(RequestMapping.class)) { return; } else if (method.isAnnotationPresent(InitBinder.class)) { return; } else if (method.isAnnotationPresent(ModelAttribute.class)) { return; } else { List<String> urls = doResolve(uri.toString(), method); if (!CollectionUtil.isEmpty(urls)) { for (String url : urls) { urlList.add(url); } } } } }, new MethodFilter() { // ==object.class public boolean matches(Method method) { return method.getDeclaringClass() != Object.class; } }); return urlList; } protected boolean qualify(Method method) { if (qualifier == null) return true; return qualifier.qualify(method); } protected abstract List<String> doResolve(String uriBase, Method method); public Set<String> getAllResolvedUrls() { return implicitHandlerMethods.keySet(); } protected boolean isPathMatchInternal(String pattern, String lookupPath) { if (pattern.equals(lookupPath) || getPathMatcher().match(pattern, lookupPath)) { return true; } boolean hasSuffix = pattern.indexOf('.') != -1; if (!hasSuffix && getPathMatcher().match(pattern + ".*", lookupPath)) { return true; } boolean endsWithSlash = pattern.endsWith("/"); return !endsWithSlash && getPathMatcher().match(pattern + "/", lookupPath); } }