All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver Maven / Gradle / Ivy

There is a newer version: 5.3.34
Show newest version
/*
 * 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.beans.factory.xml;

import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.BeanUtils;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
 * Default implementation of the {@link NamespaceHandler}. Resolves namespace URIs
 * to implementation classes based on the mappings contained in mapping file.
 *
 * 

By default, this implementation looks for the mapping file at * META-INF/spring.handlers, but this can be changed using the * {@link #DefaultNamespaceHandlerResolver(ClassLoader, String)} constructor. * * @author Rob Harrop * @author Juergen Hoeller * @since 2.0 * @see NamespaceHandler * @see DefaultBeanDefinitionDocumentReader */ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver { /** * The location to look for the mapping files. Can be present in multiple JAR files. */ private static final String SPRING_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers"; /** Logger available to subclasses */ protected final Log logger = LogFactory.getLog(getClass()); /** Stores the mappings from namespace URI Strings to NamespaceHandler instances */ private Map handlerMappings; /** * Create a new DefaultNamespaceHandlerResolver using the * default mapping file location. *

This constructor will result in the thread context ClassLoader being used * to load resources. * @see #SPRING_HANDLER_MAPPINGS_LOCATION */ public DefaultNamespaceHandlerResolver() { this(null, SPRING_HANDLER_MAPPINGS_LOCATION); } /** * Create a new DefaultNamespaceHandlerResolver using the * default mapping file location. * @param classLoader the {@link ClassLoader} instance used to load mapping resources (may be null, in * which case the thread context ClassLoader will be used) * @see #SPRING_HANDLER_MAPPINGS_LOCATION */ public DefaultNamespaceHandlerResolver(ClassLoader classLoader) { this(classLoader, SPRING_HANDLER_MAPPINGS_LOCATION); } /** * Create a new DefaultNamespaceHandlerResolver using the * supplied mapping file location. * @param classLoader the {@link ClassLoader} instance used to load mapping resources (may be null, in * which case the thread context ClassLoader will be used) * @param handlerMappingsLocation the mapping file location * @see #SPRING_HANDLER_MAPPINGS_LOCATION */ public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) { Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null"); ClassLoader classLoaderToUse = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader()); initHandlerMappings(classLoaderToUse, handlerMappingsLocation); } /** * Load the namespace URI -> NamespaceHandler class mappings from the configured * mapping file. Converts the class names into actual class instances and checks that * they implement the NamespaceHandler interface. Pre-instantiates an instance * of each NamespaceHandler and maps that instance to the corresponding * namespace URI. */ private void initHandlerMappings(ClassLoader classLoader, String handlerMappingsLocation) { Properties mappings = loadMappings(classLoader, handlerMappingsLocation); if (logger.isDebugEnabled()) { logger.debug("Loaded mappings [" + mappings + "]"); } this.handlerMappings = new HashMap(mappings.size()); for (Enumeration en = mappings.propertyNames(); en.hasMoreElements();) { String namespaceUri = (String) en.nextElement(); String className = mappings.getProperty(namespaceUri); try { Class handlerClass = ClassUtils.forName(className, classLoader); if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) { throw new IllegalArgumentException("Class [" + className + "] does not implement the NamespaceHandler interface"); } NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); namespaceHandler.init(); this.handlerMappings.put(namespaceUri, namespaceHandler); } catch (ClassNotFoundException ex) { if (logger.isDebugEnabled()) { logger.debug("Ignoring namespace handler [" + className + "]: handler class not found", ex); } } catch (LinkageError err) { if (logger.isWarnEnabled()) { logger.warn("Ignoring namespace handler [" + className + "]: problem with handler class file or dependent class", err); } } } } private Properties loadMappings(ClassLoader classLoader, String handlerMappingsLocation) { try { return PropertiesLoaderUtils.loadAllProperties(handlerMappingsLocation, classLoader); } catch (IOException ex) { throw new IllegalStateException( "Unable to load NamespaceHandler mappings from location [" + handlerMappingsLocation + "]. Root cause: " + ex); } } /** * Locate the {@link NamespaceHandler} for the supplied namespace URI * from the configured mappings. * @param namespaceUri the relevant namespace URI * @return the located {@link NamespaceHandler}, or null if none found */ public NamespaceHandler resolve(String namespaceUri) { return (NamespaceHandler) this.handlerMappings.get(namespaceUri); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy