KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > beans > factory > xml > DefaultNamespaceHandlerResolver


1 /*
2  * Copyright 2002-2007 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.beans.factory.xml;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Enumeration JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Map JavaDoc;
23 import java.util.Properties JavaDoc;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 import org.springframework.beans.BeanUtils;
29 import org.springframework.core.io.support.PropertiesLoaderUtils;
30 import org.springframework.util.Assert;
31 import org.springframework.util.ClassUtils;
32
33 /**
34  * Default implementation of the {@link NamespaceHandler}. Resolves namespace URIs
35  * to implementation classes based on the mappings contained in mapping file.
36  *
37  * <p>By default, this implementation looks for the mapping file at
38  * <code>META-INF/spring.handlers</code>, but this can be changed using the
39  * {@link #DefaultNamespaceHandlerResolver(ClassLoader, String)} constructor.
40  *
41  * @author Rob Harrop
42  * @author Juergen Hoeller
43  * @since 2.0
44  * @see NamespaceHandler
45  * @see DefaultBeanDefinitionDocumentReader
46  */

47 public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver {
48
49     /**
50      * The location to look for the mapping files. Can be present in multiple JAR files.
51      */

52     private static final String JavaDoc SPRING_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";
53
54
55     /** Logger available to subclasses */
56     protected final Log logger = LogFactory.getLog(getClass());
57
58     /** Stores the mappings from namespace URI Strings to NamespaceHandler instances */
59     private Map JavaDoc handlerMappings;
60
61
62     /**
63      * Create a new <code>DefaultNamespaceHandlerResolver</code> using the
64      * default mapping file location.
65      * <p>This constructor will result in the thread context ClassLoader being used
66      * to load resources.
67      * @see #SPRING_HANDLER_MAPPINGS_LOCATION
68      */

69     public DefaultNamespaceHandlerResolver() {
70         this(null, SPRING_HANDLER_MAPPINGS_LOCATION);
71     }
72
73
74     /**
75      * Create a new <code>DefaultNamespaceHandlerResolver</code> using the
76      * default mapping file location.
77      * @param classLoader the {@link ClassLoader} instance used to load mapping resources (may be <code>null</code>, in
78      * which case the thread context ClassLoader will be used)
79      * @see #SPRING_HANDLER_MAPPINGS_LOCATION
80      */

81     public DefaultNamespaceHandlerResolver(ClassLoader JavaDoc classLoader) {
82         this(classLoader, SPRING_HANDLER_MAPPINGS_LOCATION);
83     }
84
85     /**
86      * Create a new <code>DefaultNamespaceHandlerResolver</code> using the
87      * supplied mapping file location.
88      * @param classLoader the {@link ClassLoader} instance used to load mapping resources (may be <code>null</code>, in
89      * which case the thread context ClassLoader will be used)
90      * @param handlerMappingsLocation the mapping file location
91      * @see #SPRING_HANDLER_MAPPINGS_LOCATION
92      */

93     public DefaultNamespaceHandlerResolver(ClassLoader JavaDoc classLoader, String JavaDoc handlerMappingsLocation) {
94         Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null");
95         ClassLoader JavaDoc classLoaderToUse = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
96         initHandlerMappings(classLoaderToUse, handlerMappingsLocation);
97     }
98
99
100     /**
101      * Load the namespace URI -> <code>NamespaceHandler</code> class mappings from the configured
102      * mapping file. Converts the class names into actual class instances and checks that
103      * they implement the <code>NamespaceHandler</code> interface. Pre-instantiates an instance
104      * of each <code>NamespaceHandler</code> and maps that instance to the corresponding
105      * namespace URI.
106      */

107     private void initHandlerMappings(ClassLoader JavaDoc classLoader, String JavaDoc handlerMappingsLocation) {
108         Properties JavaDoc mappings = loadMappings(classLoader, handlerMappingsLocation);
109         if (logger.isDebugEnabled()) {
110             logger.debug("Loaded mappings [" + mappings + "]");
111         }
112         this.handlerMappings = new HashMap JavaDoc(mappings.size());
113         for (Enumeration JavaDoc en = mappings.propertyNames(); en.hasMoreElements();) {
114             String JavaDoc namespaceUri = (String JavaDoc) en.nextElement();
115             String JavaDoc className = mappings.getProperty(namespaceUri);
116             try {
117                 Class JavaDoc handlerClass = ClassUtils.forName(className, classLoader);
118                 if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
119                     throw new IllegalArgumentException JavaDoc("Class [" + className +
120                             "] does not implement the NamespaceHandler interface");
121                 }
122                 NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
123                 namespaceHandler.init();
124                 this.handlerMappings.put(namespaceUri, namespaceHandler);
125             }
126             catch (ClassNotFoundException JavaDoc ex) {
127                 if (logger.isDebugEnabled()) {
128                     logger.debug("Ignoring namespace handler [" + className + "]: handler class not found", ex);
129                 }
130             }
131             catch (LinkageError JavaDoc err) {
132                 if (logger.isWarnEnabled()) {
133                     logger.warn("Ignoring namespace handler [" + className +
134                             "]: problem with handler class file or dependent class", err);
135                 }
136             }
137         }
138     }
139
140     private Properties JavaDoc loadMappings(ClassLoader JavaDoc classLoader, String JavaDoc handlerMappingsLocation) {
141         try {
142             return PropertiesLoaderUtils.loadAllProperties(handlerMappingsLocation, classLoader);
143         }
144         catch (IOException JavaDoc ex) {
145             throw new IllegalStateException JavaDoc(
146                     "Unable to load NamespaceHandler mappings from location [" +
147                     handlerMappingsLocation + "]. Root cause: " + ex);
148         }
149     }
150
151
152     /**
153      * Locate the {@link NamespaceHandler} for the supplied namespace URI
154      * from the configured mappings.
155      * @param namespaceUri the relevant namespace URI
156      * @return the located {@link NamespaceHandler}, or <code>null</code> if none found
157      */

158     public NamespaceHandler resolve(String JavaDoc namespaceUri) {
159         return (NamespaceHandler) this.handlerMappings.get(namespaceUri);
160     }
161
162 }
163
Popular Tags