View Javadoc

1   /*
2    * EL4J, the Extension Library for the J2EE, adds incremental enhancements to
3    * the spring framework, http://el4j.sf.net
4    * Copyright (C) 2006 by ELCA Informatique SA, Av. de la Harpe 22-24,
5    * 1000 Lausanne, Switzerland, http://www.elca.ch
6    *
7    * EL4J is published under the GNU Lesser General Public License (LGPL)
8    * Version 2.1. See http://www.gnu.org/licenses/
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13   * GNU Lesser General Public License for more details.
14   *
15   * For alternative licensing, please contact info@elca.ch
16   */
17  package ch.elca.el4j.web.context;
18  
19  import javax.servlet.ServletContext;
20  
21  import org.springframework.beans.BeanUtils;
22  import org.springframework.beans.BeansException;
23  import org.springframework.context.ApplicationContext;
24  import org.springframework.context.ApplicationContextException;
25  import org.springframework.util.ClassUtils;
26  import org.springframework.util.StringUtils;
27  import org.springframework.web.context.ConfigurableWebApplicationContext;
28  import org.springframework.web.context.ContextLoader;
29  import org.springframework.web.context.WebApplicationContext;
30  
31  /**
32   *
33   * This class extends Spring's <code>ContextLoader</code>. It inherits its
34   * complete behaviour but replaces the web application context with a
35   * {@link ch.elca.el4j.web.context.ModuleWebApplicationContext} which can be
36   * configured with inclusive configuration locations, exclusive configuration
37   * locations, and booleans indicating whether bean overriding is allowed and
38   * whether the resources retrieved by the configuration files section of the
39   * manifest files should be merged with resources found by searching in the file
40   * system.
41   *
42   * @svnLink $Revision: 4204 $;$Date: 2010-11-02 11:44:37 +0100 (Di, 02. Nov 2010) $;$Author: swisswheel $;$URL: https://el4j.svn.sourceforge.net/svnroot/el4j/branches/el4j_3_1/el4j/framework/modules/web/jar/src/main/java/ch/elca/el4j/web/context/ModuleContextLoader.java $
43   *
44   * @see org.springframework.web.context.ContextLoader
45   * @see ModuleContextLoaderListener
46   * @author Alex Mathey (AMA)
47   */
48  public class ModuleContextLoader extends ContextLoader {
49  
50  	
51  	/**
52  	 * Name of servlet context parameter that can specify the inclusive
53  	 * configuration locations for the application context.
54  	 */
55  	public static final String INCLUSIVE_LOCATIONS_PARAM = "inclusiveLocations";
56  	
57  	/**
58  	 * Name of servlet context parameter that can specify the exclusive
59  	 * configuration locations for the application context.
60  	 */
61  	public static final String EXCLUSIVE_LOCATIONS_PARAM = "exclusiveLocations";
62  	
63  	/**
64  	 * Name of servlet context parameter indicating whether bean definition
65  	 * overriding is allowed in the application context.
66  	 */
67  	public static final String BEAN_OVERRIDING_PARAM
68  		= "overrideBeanDefinitions";
69  	
70  	/**
71  	 * Name of servlet context parameter indicating whether the resources
72  	 * retrieved by the configuration files section of the manifest files should
73  	 * be merged with resources found by searching in the file system.
74  	 */
75  	public static final String MERGE_RESOURCES_PARAM = "mergeResources";
76  	
77  	/**
78  	 * {@inheritDoc}
79  	 */
80  	protected WebApplicationContext createWebApplicationContext(
81  		ServletContext servletContext, ApplicationContext parent)
82  		throws BeansException {
83  
84  		Class<?> contextClass = determineContextClass(servletContext);
85  		if (!ConfigurableWebApplicationContext.class
86  			.isAssignableFrom(contextClass)) {
87  			throw new ApplicationContextException("Custom context class ["
88  				+ contextClass.getName()
89  				+ "] is not of type ConfigurableWebApplicationContext");
90  		}
91  
92  		ConfigurableWebApplicationContext wac;
93  
94  		if (ModuleWebApplicationContext.class.isAssignableFrom(contextClass)) {
95  			String[] inclusiveConfigLocations = getInclusiveConfigLocations(
96  				servletContext);
97  			String[] exclusiveConfigLocations = getExclusiveConfigLocations(
98  				servletContext);
99  			boolean beanOverriding = isBeanDefinitionOverridingAllowed(
100 				servletContext);
101 			boolean mergeResources = isMergingWithOuterResourcesAllowed(
102 				servletContext);
103 
104 			wac = new ModuleWebApplicationContext(inclusiveConfigLocations,
105 				exclusiveConfigLocations, beanOverriding, servletContext,
106 				mergeResources, parent);
107 
108 		} else {
109 			wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
110 			wac.setServletContext(servletContext);
111 			String configLocation = servletContext.getInitParameter(CONFIG_LOCATION_PARAM);
112 			if (configLocation != null) {
113 				wac.setConfigLocations(toStringArray(configLocation));
114 			}
115 			wac.setParent(parent);
116 		}
117 		wac.refresh();
118 		return wac;
119 	}
120 
121 	/**
122 	 * {@inheritDoc}
123 	 */
124 	protected Class<?> determineContextClass(ServletContext servletContext)
125 		throws ApplicationContextException {
126 		String contextClassName = servletContext
127 			.getInitParameter(CONTEXT_CLASS_PARAM);
128 		if (contextClassName != null) {
129 			try {
130 				return ClassUtils.forName(contextClassName);
131 			} catch (ClassNotFoundException ex) {
132 				throw new ApplicationContextException(
133 					"Failed to load custom context class [" + contextClassName
134 						+ "]", ex);
135 			}
136 		} else {
137 			contextClassName
138 				= "ch.elca.el4j.web.context.ModuleWebApplicationContext";
139 			try {
140 				return ClassUtils.forName(contextClassName);
141 			} catch (ClassNotFoundException ex) {
142 				throw new ApplicationContextException(
143 					"Failed to load default context class [" + contextClassName
144 						+ "]", ex);
145 			}
146 		}
147 	}
148 	
149 	/**
150 	 * Returns the inclusive configuration locations.
151 	 *
152 	 * @param servletContext
153 	 *            current servlet context
154 	 * @return array containing the inclusive configuration locations
155 	 */
156 	protected String[] getInclusiveConfigLocations(ServletContext
157 		servletContext) {
158 		String inclusiveConfigLocations = servletContext
159 			.getInitParameter(INCLUSIVE_LOCATIONS_PARAM);
160 		if (inclusiveConfigLocations == null) {
161 			inclusiveConfigLocations = servletContext
162 				.getInitParameter(CONFIG_LOCATION_PARAM);
163 			if (inclusiveConfigLocations == null) {
164 				return null;
165 			}
166 		}
167 		return toStringArray(inclusiveConfigLocations);
168 	}
169 	
170 	/**
171 	 * Returns the exclusive configuration locations.
172 	 *
173 	 * @param servletContext
174 	 *            current servlet context
175 	 * @return array containing the inclusive configuration locations
176 	 */
177 	protected String[] getExclusiveConfigLocations(ServletContext
178 		servletContext) {
179 		String exclusiveConfigLocations = servletContext.
180 			getInitParameter(EXCLUSIVE_LOCATIONS_PARAM);
181 		if (exclusiveConfigLocations == null) {
182 			return null;
183 		}
184 		return toStringArray(exclusiveConfigLocations);
185 	}
186 	
187 	/**
188 	 * Returns whether bean definition overriding is allowed.
189 	 * @param servletContext current servlet context
190 	 * @return boolean indicating whether bean overriding is allowed
191 	 */
192 	protected boolean isBeanDefinitionOverridingAllowed(ServletContext
193 		servletContext) {
194 		boolean override = false;
195 		String beanOverriding = servletContext.getInitParameter(
196 			BEAN_OVERRIDING_PARAM);
197 		if (beanOverriding != null) {
198 			if (beanOverriding.equals("true")) {
199 				override = true;
200 			}
201 		}
202 		return override;
203 	}
204 	
205 	/**
206 	 * Returns whether the resources retrieved by the configuration files
207 	 * section of the manifest files should be merged ith resources found by
208 	 * searching in the file system.
209 	 * @param servletContext current servlet context
210 	 * @return boolean indicating whether resource merging is allowed
211 	 */
212 	protected boolean isMergingWithOuterResourcesAllowed(ServletContext
213 		servletContext) {
214 		boolean merge = true;
215 		String mergeResources = servletContext.getInitParameter(
216 			MERGE_RESOURCES_PARAM);
217 		if (mergeResources != null) {
218 			if (mergeResources.equals("false")) {
219 				merge = false;
220 			}
221 		}
222 		return merge;
223 	}
224 	
225 	/**
226 	 * Transforms a string of tokens into a string array. The tokens have to
227 	 * be separated by {@link
228 	 * ConfigurableWebApplicationContext#CONFIG_LOCATION_DELIMITERS}.
229 	 *
230 	 * @param str
231 	 *      The string to parse.
232 	 *
233 	 * @return Returns the given string's token as array.
234 	 */
235 	private String[] toStringArray(String str) {
236 		String[] result = new String[0];
237 		if (str != null) {
238 			result =  StringUtils.tokenizeToStringArray(str,
239 				ConfigurableWebApplicationContext.CONFIG_LOCATION_DELIMITERS);
240 		}
241 		return result;
242 	}
243 }