/* * Copyright 2002-2007 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.servlet.config; import java.util.Properties; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.RuntimeBeanReference; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.springframework.util.StringUtils; import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; /** * Bean definition parser <code><url:urlmappings></code> tag, * resulting in a SimpleUrlHandlerMapping. * * @author Alef Arendsen */ public class UrlHandlerMappingBeanDefinitionParser implements BeanDefinitionParser { private static final String URLMAPPING = "url-mapping"; private static final String ALWAYS_USE_FULL_PATH = "always-use-full-path"; private static final String ALWAYS_USE_FULL_PATH_PROPERTY = "alwaysUseFullPath"; private static final String URL_DECODE = "url-decode"; private static final String URL_DECODE_PROPERTY = "urlDecode"; private static final String LAZY_INIT_HANDLERS = "lazy-init-handlers"; private static final String LAZY_INIT_HANLDERS_PROPERTY = "lazyInitHandlers"; private static final String DEFAULT_HANDLER = "default-handler"; private static final String HANDLER = "handler"; private static final String PATH = "path"; private static final String CONTROLLER_REF = "controller-ref"; private static final String INTERCEPTOR = "interceptor"; private static final String INTERCEPTOR_REF = "interceptor-ref"; /** * Parses the url:handlermappings element resulting in a SimpleUrlHandlerMapping * bean definition. Except for all the normal behavior, adds behavior * for HandlerInterceptors matched on a specific path. */ public BeanDefinition parse(Element element, ParserContext parserContext) { BeanDefinitionRegistry registry = parserContext.getRegistry(); NodeList handlerMappingChildren = element.getChildNodes(); int handlerCount = 0; for (int i = 0; i < handlerMappingChildren.getLength(); i++) { Node handlerMapping = handlerMappingChildren.item(i); if (URLMAPPING.equals(handlerMapping.getLocalName()) && handlerMapping.getNodeType() == Node.ELEMENT_NODE) { Element ele = (Element) handlerMapping; RootBeanDefinition handlerMappingDefinition = parseHandlerMappingDefinition(ele); handlerMappingDefinition.setSource(parserContext.extractSource(element)); handlerMappingDefinition.getPropertyValues().addPropertyValue("order", new Integer(handlerCount++)); parserContext.getReaderContext().registerWithGeneratedName(handlerMappingDefinition); } } return null; } private RootBeanDefinition parseHandlerMappingDefinition(Element element) { Properties mappings = new Properties(); ManagedList interceptors = new ManagedList(); NodeList childNodes = element.getChildNodes(); // parse url mappings for (int i = 0; i < childNodes.getLength(); i++) { Node childElement = childNodes.item(i); // just to be sure that it's really a urlmapping if (HANDLER.equals(childElement.getLocalName()) && childElement.getNodeType() == Node.ELEMENT_NODE) { // parse handler mapping mapping paths to urls Element el = (Element)childElement; String path = el.getAttribute(PATH); String ref = el.getAttribute(CONTROLLER_REF); mappings.put(path, ref); } else if (INTERCEPTOR.equals(childElement.getLocalName()) && childElement.getNodeType() == Node.ELEMENT_NODE) { // parse interceptor Element el = (Element)childElement; String ref = el.getAttribute(INTERCEPTOR_REF); interceptors.add(new RuntimeBeanReference(ref)); } } // create root bean definition RootBeanDefinition definition = new RootBeanDefinition(); definition.setBeanClass(SimpleUrlHandlerMapping.class); definition.getPropertyValues().addPropertyValue("mappings", mappings); definition.getPropertyValues().addPropertyValue("interceptors", interceptors); // parse attributes setPropertyIfAvailable(element, ALWAYS_USE_FULL_PATH, ALWAYS_USE_FULL_PATH_PROPERTY, definition); setPropertyIfAvailable(element, URL_DECODE, URL_DECODE_PROPERTY, definition); setPropertyIfAvailable(element, LAZY_INIT_HANDLERS, LAZY_INIT_HANLDERS_PROPERTY, definition); String defaultHandler = element.getAttribute(DEFAULT_HANDLER); if (StringUtils.hasText(defaultHandler)) { definition.getPropertyValues().addPropertyValue("defaultHandler", defaultHandler); } return definition; } private void setPropertyIfAvailable(Element el, String attribute, String property, RootBeanDefinition definition) { String propertyValue = el.getAttribute(attribute); if (StringUtils.hasText(propertyValue)) { definition.getPropertyValues().addPropertyValue(property, propertyValue); } } }