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.handlermapping; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping; import org.tinygroup.springmvc.coc.ConventionHelper; import org.tinygroup.springmvc.util.WebUtil; import org.tinygroup.weblayer.WebContext; import org.tinygroup.weblayer.mvc.WebContextAware; import org.tinygroup.weblayer.webcontext.util.WebContextUtil; import javax.servlet.http.HttpServletRequest; import java.util.*; /** * * @author kevin.luy * @since 2014719 */ public class DefaultCOCUrlHandlerMapping extends DefaultAnnotationHandlerMapping { private static final Log logger = LogFactory.getLog(DefaultCOCUrlHandlerMapping.class); private ConventionHelper conventionHelper; public void setConventionHelper(ConventionHelper conventionHelper) { this.conventionHelper = conventionHelper; } @Override protected String[] determineUrlsForHandler(String beanName) { String[] urls = super.determineUrlsForHandler(beanName); try { // requestMapping Object obj = getApplicationContext().getBean(beanName); if (urls == null && conventionHelper.isHandler(obj)) { // desicide url urls = conventionHelper.determineUrl(obj); } } catch (Exception e) { if (logger.isWarnEnabled()) { logger.warn("resolve the uris mapping for handler err!", e); } } return urls; } protected Object lookupHandler(String urlPath, HttpServletRequest request) throws Exception { // ??? // Direct match? Object handler = getHandlerMap().get(urlPath); if (handler != null) { // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } validateHandler(handler, request); return buildPathExposingHandler(handler, urlPath, urlPath, null); } // +++ convention match ??match String noExtPath = WebUtil.getUriWithoutExtension(urlPath); boolean hasExtension = !StringUtils.equals(urlPath, noExtPath); // for Pattern match? List<String> matchingPatterns = new ArrayList<String>(); if (hasExtension) { // ??? handler = getHandlerMap().get(noExtPath); if (handler != null) { // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } if (logger.isDebugEnabled()) { logger.debug("Convention Matching for request [" + urlPath + "] are " + noExtPath); } validateHandler(handler, request); return buildPathExposingHandler(handler, urlPath, urlPath, null); } // pattern match for (String registeredPattern : getHandlerMap().keySet()) { if (getPathMatcher().match(registeredPattern, urlPath)) { // ? users/1.htm match // users/{id}???? if (!conventionHelper.isConventional(registeredPattern)) { matchingPatterns.add(registeredPattern); continue; } } // condition: convention && request path has extension if ((hasExtension && getPathMatcher().match(registeredPattern, noExtPath))) { // if request path has extension ,then add the extension to // pattern matchingPatterns.add(registeredPattern); } } } else {// ? // pattern match for (String registeredPattern : getHandlerMap().keySet()) { if (getPathMatcher().match(registeredPattern, urlPath)) { matchingPatterns.add(registeredPattern); } } } String bestPatternMatch = null; Comparator<String> patternComparator = getPathMatcher().getPatternComparator(urlPath); if (!matchingPatterns.isEmpty()) { Collections.sort(matchingPatterns, patternComparator); if (logger.isDebugEnabled()) { logger.debug("Matching patterns for request [" + urlPath + "] are " + matchingPatterns); } bestPatternMatch = matchingPatterns.get(0); } if (bestPatternMatch != null) { handler = getHandlerMap().get(bestPatternMatch); // Bean name or resolved handler? if (handler instanceof String) { String handlerName = (String) handler; handler = getApplicationContext().getBean(handlerName); } validateHandler(handler, request); if (conventionHelper.isConventional(bestPatternMatch) && hasExtension) { urlPath = noExtPath; } String pathWithinMapping = getPathMatcher().extractPathWithinPattern(bestPatternMatch, urlPath); // There might be multiple 'best patterns', let's make sure we have // the correct URI template variables // for all of them Map<String, String> uriTemplateVariables = new LinkedHashMap<String, String>(); for (String matchingPattern : matchingPatterns) { if (patternComparator.compare(bestPatternMatch, matchingPattern) == 0) { uriTemplateVariables .putAll(getPathMatcher().extractUriTemplateVariables(matchingPattern, urlPath)); } } if (logger.isDebugEnabled()) { logger.debug("URI Template variables for request [" + urlPath + "] are " + uriTemplateVariables); } return buildPathExposingHandler(handler, bestPatternMatch, pathWithinMapping, uriTemplateVariables); } // No handler found... return null; } /** * Validate the given annotated handler against the current request. * handlerWebContextAware?, * * @see #validateMapping */ @Override protected void validateHandler(Object handler, HttpServletRequest request) throws Exception { super.validateHandler(handler, request); if (handler instanceof WebContextAware) { WebContext webContext = WebContextUtil.getWebContext(request); WebContextAware webContextAware = (WebContextAware) handler; webContextAware.setContext(webContext); } } }