KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > web > servlet > handler > metadata > AbstractPathMapHandlerMapping


1 /*
2  * Copyright 2002-2006 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.web.servlet.handler.metadata;
18
19 import org.springframework.beans.BeansException;
20 import org.springframework.beans.factory.BeanInitializationException;
21 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
22 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
23 import org.springframework.context.ConfigurableApplicationContext;
24 import org.springframework.core.Constants;
25 import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
26
27 /**
28  * Abstract implementation of the HandlerMapping interface that recognizes
29  * metadata attributes of type PathMap on application Controllers and automatically
30  * wires them into the current servlet's WebApplicationContext.
31  *
32  * <p>The path must be mapped to the relevant Spring DispatcherServlet in /WEB-INF/web.xml.
33  * It's possible to have multiple PathMap attributes on the one controller class.
34  *
35  * <p>Controllers instantiated by this class may have dependencies on middle tier
36  * objects, expressed via JavaBean properties or constructor arguments. These will
37  * be resolved automatically.
38  *
39  * <p>You will normally use this HandlerMapping with at most one DispatcherServlet in your
40  * web application. Otherwise you'll end with one instance of the mapped controller for
41  * each DispatcherServlet's context. You <i>might</i> want this -- for example, if
42  * one's using a .pdf mapping and a PDF view, and another a JSP view, or if
43  * using different middle tier objects, but should understand the implications. All
44  * Controllers with attributes will be picked up by each DispatcherServlet's context.
45  *
46  * @author Rod Johnson
47  * @author Juergen Hoeller
48  */

49 public abstract class AbstractPathMapHandlerMapping extends AbstractUrlHandlerMapping {
50
51     /** Constants instance for AutowireCapableBeanFactory */
52     private static final Constants constants = new Constants(AutowireCapableBeanFactory.class);
53
54     private int autowireMode = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
55
56     private boolean dependencyCheck = true;
57
58
59     /**
60      * Set the autowire mode for handlers, by the name of the corresponding constant
61      * in the AutowireCapableBeanFactory interface, e.g. "AUTOWIRE_BY_NAME".
62      * @param constantName name of the constant
63      * @throws java.lang.IllegalArgumentException if an invalid constant was specified
64      * @see #setAutowireMode
65      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_NAME
66      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_TYPE
67      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_CONSTRUCTOR
68      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_AUTODETECT
69      */

70     public void setAutowireModeName(String JavaDoc constantName) throws IllegalArgumentException JavaDoc {
71         setAutowireMode(constants.asNumber(constantName).intValue());
72     }
73
74     /**
75      * Set the autowire mode for handlers. This determines whether any automagical
76      * detection and setting of bean references will happen.
77      * <p>Default is AUTOWIRE_AUTODETECT, which means either constructor autowiring or
78      * autowiring by type (depending on the constructors available in the class).
79      * @param autowireMode the autowire mode to set.
80      * Must be one of the constants defined in the AutowireCapableBeanFactory interface.
81      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_NAME
82      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_BY_TYPE
83      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_CONSTRUCTOR
84      * @see org.springframework.beans.factory.config.AutowireCapableBeanFactory#AUTOWIRE_AUTODETECT
85      */

86     public void setAutowireMode(int autowireMode) {
87         this.autowireMode = autowireMode;
88     }
89
90     /**
91      * Set whether to perform a dependency check for objects on autowired handlers.
92      * Not applicable to autowiring a constructor, thus ignored there.
93      * <p>Default is "true".
94      */

95     public void setDependencyCheck(boolean dependencyCheck) {
96         this.dependencyCheck = dependencyCheck;
97     }
98
99
100     /**
101      * Calls the <code>detectAndCreateHandlers</code> method in addition
102      * to the superclass's initialization.
103      * @see #detectAndCreateHandlers
104      */

105     public void initApplicationContext() throws BeansException {
106         super.initApplicationContext();
107
108         if (!(getApplicationContext() instanceof ConfigurableApplicationContext)) {
109             throw new IllegalStateException JavaDoc(
110                     "[" + getClass().getName() + "] needs to run in a ConfigurableApplicationContext");
111         }
112         ConfigurableListableBeanFactory beanFactory =
113                 ((ConfigurableApplicationContext) getApplicationContext()).getBeanFactory();
114         detectAndCreateHandlers(beanFactory);
115     }
116
117     /**
118      * Look for all classes with a PathMap class attribute, instantiate them in
119      * the owning ApplicationContext, and register them as MVC handlers usable
120      * by the current DispatcherServlet.
121      * @param beanFactory the ConfigurableListableBeanFactory to register the
122      * created handler instances with
123      * @throws BeansException if handler detection or creation failed
124      * @see PathMap
125      * @see #getClassesWithPathMapAttributes()
126      * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#createBean
127      * @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#registerSingleton
128      */

129     protected void detectAndCreateHandlers(ConfigurableListableBeanFactory beanFactory) throws BeansException {
130         try {
131             Class JavaDoc[] handlerClasses = getClassesWithPathMapAttributes();
132             if (logger.isDebugEnabled()) {
133                 logger.debug("Found " + handlerClasses.length + " attribute-targeted handlers");
134             }
135
136             // for each Class returned by the Commons Attribute indexer
137
for (int i = 0; i < handlerClasses.length; i++) {
138                 Class JavaDoc handlerClass = handlerClasses[i];
139
140                 // Autowire the given handler class via AutowireCapableBeanFactory.
141
// Either autowires a constructor or by type, depending on the
142
// constructors available in the given class.
143
Object JavaDoc handler = beanFactory.createBean(handlerClass, this.autowireMode, this.dependencyCheck);
144
145                 // We now have an "autowired" handler, that may reference beans in the
146
// application context. We now add the new handler to the factory.
147
// This isn't necessary for the handler to work, but is useful if we want
148
// to enumerate controllers in the factory etc.
149
beanFactory.registerSingleton(handlerClass.getName(), handler);
150
151                 // There may be multiple paths mapped to this handler.
152
PathMap[] pathMaps = getPathMapAttributes(handlerClass);
153                 registerHandler(pathMaps, handler);
154             }
155         }
156         catch (BeansException ex) {
157             throw ex;
158         }
159         catch (Exception JavaDoc ex) {
160             throw new BeanInitializationException("Could not retrieve PathMap attributes", ex);
161         }
162     }
163
164     /**
165      * Register the given handler for the URL paths indicated by the given PathMaps.
166      * @param pathMaps the PathMap attributes for the handler class
167      * @param handler the handler instance
168      * @throws BeansException if the handler couldn't be registered
169      * @throws IllegalStateException if there is a conflicting handler registered
170      */

171     protected void registerHandler(PathMap[] pathMaps, Object JavaDoc handler) throws BeansException, IllegalStateException JavaDoc {
172         for (int j = 0; j < pathMaps.length; j++) {
173             PathMap pathMap = pathMaps[j];
174             String JavaDoc path = pathMap.getUrl();
175             if (!path.startsWith("/")) {
176                 path = "/" + path;
177             }
178             registerHandler(path, handler);
179         }
180     }
181
182
183     /**
184      * Use an attribute index to get a Collection of Class objects
185      * with the required PathMap attribute.
186      * @return a array of Class objects
187      */

188     protected abstract Class JavaDoc[] getClassesWithPathMapAttributes() throws Exception JavaDoc;
189
190     /**
191      * Use Attributes API to find PathMap attributes for the given handler class.
192      * We know there's at least one, as the getClassNamesWithPathMapAttributes
193      * method return this class name.
194      * @param handlerClass the handler class to look for
195      * @return an array of PathMap objects
196      */

197     protected abstract PathMap[] getPathMapAttributes(Class JavaDoc handlerClass) throws Exception JavaDoc;
198
199 }
200
Popular Tags