KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > info > magnolia > cms > servlets > PropertyInitializer


1 /**
2  *
3  * Magnolia and its source-code is licensed under the LGPL.
4  * You may copy, adapt, and redistribute this file for commercial or non-commercial use.
5  * When copying, adapting, or redistributing this document in keeping with the guidelines above,
6  * you are required to provide proper attribution to obinary.
7  * If you reproduce or distribute the document without making any substantive modifications to its content,
8  * please use the following attribution line:
9  *
10  * Copyright 1993-2006 obinary Ltd. (http://www.obinary.com) All rights reserved.
11  *
12  */

13 package info.magnolia.cms.servlets;
14
15 import info.magnolia.cms.beans.config.ConfigLoader;
16 import info.magnolia.cms.beans.config.ModuleRegistration;
17 import info.magnolia.cms.core.SystemProperty;
18 import info.magnolia.cms.module.ModuleDefinition;
19 import info.magnolia.cms.module.PropertyDefinition;
20 import info.magnolia.logging.Log4jConfigurer;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileNotFoundException JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.InputStream JavaDoc;
27 import java.net.InetAddress JavaDoc;
28 import java.net.UnknownHostException JavaDoc;
29 import java.text.MessageFormat JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.Map JavaDoc;
32 import java.util.Properties JavaDoc;
33
34 import javax.servlet.ServletContext JavaDoc;
35 import javax.servlet.ServletContextEvent JavaDoc;
36 import javax.servlet.ServletContextListener JavaDoc;
37
38 import org.apache.commons.collections.OrderedMap;
39 import org.apache.commons.collections.OrderedMapIterator;
40 import org.apache.commons.io.IOUtils;
41 import org.apache.commons.lang.ArrayUtils;
42 import org.apache.commons.lang.StringUtils;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46
47 /**
48  * <p>
49  * Magnolia property initializer: reads initialization parameter from a properties file. The name of the file can be
50  * defined as a context parameter in web.xml. Multiple path, comma separated, are supported (the first existing file in
51  * the list will be used), and the following variables will be used:
52  * </p>
53  * <ul>
54  * <li><code>${servername}</code>: name of the server where the webapp is running, lowercase</li>
55  * <li><code>${webapp}</code>: the latest token in the webapp path (e.g. <code>magnoliaPublic</code> for a webapp
56  * deployed ad <code>tomcat/webapps/magnoliaPublic</code>)</li>
57  * </ul>
58  * <p>
59  * If no <code>magnolia.initialization.file</code> context parameter is set, the following default is assumed:
60  * </p>
61  *
62  * <pre>
63  * &lt;context-param>
64  * &lt;param-name>magnolia.initialization.file&lt;/param-name>
65  * &lt;param-value>
66  * WEB-INF/config/${servername}/${webapp}/magnolia.properties,
67  * WEB-INF/config/${servername}/magnolia.properties,
68  * WEB-INF/config/${webapp}/magnolia.properties,
69  * WEB-INF/config/default/magnolia.properties,
70  * WEB-INF/config/magnolia.properties
71  * &lt;/param-value>
72  * &lt;/context-param>
73  * </pre>
74  *
75  * The following parameters are needed in the properties file:
76  * <dl>
77  * <dt>magnolia.cache.startdir</dt>
78  * <dd>directory used for cached pages</dd>
79  * <dt>magnolia.upload.tmpdir</dt>
80  * <dd>tmp directory for uploaded files</dd>
81  * <dt>magnolia.exchange.history</dt>
82  * <dd>history directory used for activation</dd>
83  * <dt>magnolia.repositories.config</dt>
84  * <dd>repositories configuration</dd>
85  * <dt>log4j.config</dt>
86  * <dd>Name of a log4j config file. Can be a .properties or .xml file. The value can be:
87  * <ul>
88  * <li>a full path</li>
89  * <li>a path relative to the webapp root</li>
90  * <li> a file name which will be loaded from the classpath</li>
91  * </ul>
92  * </dd>
93  * <dt>magnolia.root.sysproperty</dt>
94  * <dd>Name of a system variable which will be set to the webapp root. You can use this property in log4j configuration
95  * files to handle relative paths, such as <code>${magnolia.root}logs/magnolia-debug.log</code>. <strong>Important</strong>:
96  * if you drop multiple magnolia wars in a container which doesn't isolate system properties (e.g. tomcat) you will need
97  * to change the name of the <code>magnolia.root.sysproperty</code> variable in web.xml and in log4j configuration
98  * files.</dd>
99  * <dt>magnolia.bootstrap.dir</dt>
100  * <dd> Directory containing xml files for initialization of a blank magnolia instance. If no content is found in any of
101  * the repository, they are initialized importing xml files found in this folder. If you don't want to let magnolia
102  * automatically initialize repositories simply remove this parameter.</dd>
103  * </dl>
104  * <h3>Advance use: deployment service</h3>
105  * <p>
106  * Using the <code>${servername}</code> and <code>${webapp}</code> properties you can easily bundle in the same
107  * webapp different set of configurations which are automatically applied dependending on the server name (useful for
108  * switching between development, test and production instances where the repository configuration need to be different)
109  * or the webapp name (useful to bundle both the public and admin log4j/jndi/bootstrap configuration in the same war).
110  * By default the initializer will try to search for the file in different location with different combination of
111  * <code>servername</code> and <code>webapp</code>: the <code>default</code> fallback directory will be used if
112  * no other environment-specific directory has been added.
113  * </p>
114  * @author Fabrizio Giustina
115  * @version $Id: PropertyInitializer.java 7668 2006-11-29 16:44:13Z gjoseph $
116  */

117 public class PropertyInitializer implements ServletContextListener JavaDoc {
118
119     /**
120      * Stable serialVersionUID.
121      */

122     private static final long serialVersionUID = 222L;
123
124     /**
125      * Logger.
126      */

127     private static Logger log = LoggerFactory.getLogger(PropertyInitializer.class);
128
129     /**
130      * Context parameter name.
131      */

132     public static final String JavaDoc MAGNOLIA_INITIALIZATION_FILE = "magnolia.initialization.file"; //$NON-NLS-1$
133

134     /**
135      * Default value for the MAGNOLIA_INITIALIZATION_FILE parameter.
136      */

137     public static final String JavaDoc DEFAULT_INITIALIZATION_PARAMETER = //
138
"WEB-INF/config/${servername}/${webapp}/magnolia.properties," //$NON-NLS-1$
139
+ "WEB-INF/config/${servername}/magnolia.properties," //$NON-NLS-1$
140
+ "WEB-INF/config/${webapp}/magnolia.properties," //$NON-NLS-1$
141
+ "WEB-INF/config/default/magnolia.properties," //$NON-NLS-1$
142
+ "WEB-INF/config/magnolia.properties"; //$NON-NLS-1$
143

144     /**
145      * The properties file containing the bean default implementations
146      */

147     private static final String JavaDoc MGNL_BEANS_PROPERTIES = "/mgnl-beans.properties";
148     
149     /**
150      * Environment-specific properties.
151      */

152     protected Properties JavaDoc envProperties = new Properties JavaDoc();
153
154     /**
155      * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
156      */

157     public void contextDestroyed(ServletContextEvent JavaDoc sce) {
158         Log4jConfigurer.shutdownLogging(envProperties);
159     }
160
161     /**
162      * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent)
163      */

164     public void contextInitialized(ServletContextEvent JavaDoc sce) {
165         final ServletContext JavaDoc context = sce.getServletContext();
166
167         loadBeanProperties();
168         
169         loadModuleProperties();
170
171         String JavaDoc propertiesLocationString = context.getInitParameter(MAGNOLIA_INITIALIZATION_FILE);
172
173         if (log.isDebugEnabled()) {
174             log.debug("{} value in web.xml is :[{}]", MAGNOLIA_INITIALIZATION_FILE, propertiesLocationString); //$NON-NLS-1$
175
}
176         if (StringUtils.isEmpty(propertiesLocationString)) {
177             log.debug("{} value in web.xml is undefined, falling back to default: {}", MAGNOLIA_INITIALIZATION_FILE, DEFAULT_INITIALIZATION_PARAMETER);
178             propertiesLocationString = DEFAULT_INITIALIZATION_PARAMETER;
179         }
180
181         String JavaDoc[] propertiesLocation = StringUtils.split(propertiesLocationString, ',');
182
183         String JavaDoc servername = initServername();
184
185         String JavaDoc rootPath = initRootPath(context);
186
187         String JavaDoc webapp = initWebappName(rootPath);
188
189         if (log.isDebugEnabled()) {
190             log.debug("rootPath is {}, webapp is {}", rootPath, webapp); //$NON-NLS-1$
191
}
192
193         createApplicationDirectories(webapp);
194
195         boolean found = false;
196
197         found = loadPropertiesFiles(propertiesLocation, servername, rootPath, webapp, found);
198         
199         overloadWithSystemProperties();
200         
201         if(!found){
202             log
203             .error(MessageFormat
204                 .format(
205                     "No configuration found using location list {0}. [servername] is [{1}], [webapp] is [{2}] and base path is [{3}]", //$NON-NLS-1$
206
new Object JavaDoc[]{ArrayUtils.toString(propertiesLocation), servername, webapp, rootPath}));
207             return;
208         }
209         
210         Log4jConfigurer.initLogging(context);
211
212         new ConfigLoader(context);
213
214     }
215
216     /**
217      * Load the properties defined in the module descriptors. They can get overridden later in the properties files in WEB-INF
218      */

219     protected void loadModuleProperties() {
220         OrderedMap defs = ModuleRegistration.getInstance().getModuleDefinitions();
221         for (OrderedMapIterator iter = defs.orderedMapIterator(); iter.hasNext();) {
222             iter.next();
223             ModuleDefinition def = (ModuleDefinition) iter.getValue();
224             for (Iterator JavaDoc iter2 = def.getProperties().iterator(); iter2.hasNext();) {
225                 PropertyDefinition property = (PropertyDefinition) iter2.next();
226                 SystemProperty.setProperty(property.getName(), property.getValue());
227             }
228         }
229     }
230
231     protected boolean loadPropertiesFiles(String JavaDoc[] propertiesLocation, String JavaDoc servername, String JavaDoc rootPath, String JavaDoc webapp, boolean found) {
232         for (int j = propertiesLocation.length-1; j >= 0; j--) {
233             String JavaDoc location = StringUtils.trim(propertiesLocation[j]);
234             location = StringUtils.replace(location, "${servername}", servername); //$NON-NLS-1$
235
location = StringUtils.replace(location, "${webapp}", webapp); //$NON-NLS-1$
236

237             if(loadPropertiesFile(rootPath, location)){
238                 found = true;
239             }
240         }
241         return found;
242     }
243
244     protected String JavaDoc initWebappName(String JavaDoc rootPath) {
245         String JavaDoc webapp = StringUtils.substringAfterLast(rootPath, "/"); //$NON-NLS-1$
246
envProperties.put(SystemProperty.MAGNOLIA_WEBAPP, webapp);
247         return webapp;
248     }
249
250     protected String JavaDoc initRootPath(final ServletContext JavaDoc context) {
251         String JavaDoc rootPath = StringUtils.replace(context.getRealPath(StringUtils.EMPTY), "\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$
252
rootPath = StringUtils.removeEnd(rootPath, "/");
253         envProperties.put(SystemProperty.MAGNOLIA_APP_ROOTDIR, rootPath);
254         
255         // system property initialization
256
String JavaDoc magnoliaRootSysproperty = (String JavaDoc) envProperties.get(SystemProperty.MAGNOLIA_ROOT_SYSPROPERTY);
257         if (StringUtils.isNotEmpty(magnoliaRootSysproperty)) {
258             System.setProperty(magnoliaRootSysproperty, rootPath);
259             log.info("Setting the magnolia root system property: [" + magnoliaRootSysproperty + "] to [" + rootPath + "]"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
260
}
261         return rootPath;
262     }
263
264     protected String JavaDoc initServername() {
265         String JavaDoc servername = null;
266
267         try {
268             servername = StringUtils.lowerCase(InetAddress.getLocalHost().getHostName());
269             envProperties.put(SystemProperty.MAGNOLIA_SERVERNAME, servername);
270         }
271         catch (UnknownHostException JavaDoc e) {
272             log.error(e.getMessage());
273         }
274         return servername;
275     }
276
277     protected void loadBeanProperties() {
278         // load mgnl-beans.properties first
279
InputStream JavaDoc mgnlbeansStream = getClass().getResourceAsStream(MGNL_BEANS_PROPERTIES);
280         
281         if (mgnlbeansStream != null) {
282             Properties JavaDoc mgnlbeans = new Properties JavaDoc();
283             try {
284                 mgnlbeans.load(mgnlbeansStream);
285             }
286             catch (IOException JavaDoc e) {
287                 log.error("Unable to load {} due to an IOException: {}", MGNL_BEANS_PROPERTIES, e.getMessage());
288             }
289             finally {
290                 IOUtils.closeQuietly(mgnlbeansStream);
291             }
292
293             for (Iterator JavaDoc iter = mgnlbeans.keySet().iterator(); iter.hasNext();) {
294                 String JavaDoc key = (String JavaDoc) iter.next();
295                 SystemProperty.setProperty(key, mgnlbeans.getProperty(key));
296             }
297
298         }
299         else {
300             log
301                 .warn(
302                     "{} not found in the classpath. Check that all the needed implementation classes are defined in your custom magnolia.properties file.",
303                     MGNL_BEANS_PROPERTIES);
304         }
305     }
306
307     /**
308      * Crate the tmp and log directory
309      */

310     private void createApplicationDirectories(String JavaDoc webapp) {
311         File JavaDoc logs = new File JavaDoc(webapp + File.separator + "logs");
312         File JavaDoc tmp = new File JavaDoc(webapp + File.separator + "tmp");
313         if (!logs.exists()) {
314             logs.mkdir();
315             log.debug("Creating " + logs.getAbsoluteFile() + " folder");
316         }
317
318         if (!tmp.exists()) {
319             tmp.mkdir();
320             log.debug("Creating " + tmp.getAbsoluteFile() + " folder");
321         }
322     }
323
324     /**
325      * Try to load a magnolia.properties file
326      * @param rootPath
327      * @param location
328      * @return
329      */

330     protected boolean loadPropertiesFile(String JavaDoc rootPath, String JavaDoc location) {
331         File JavaDoc initFile = new File JavaDoc(rootPath, location);
332
333         if (!initFile.exists() || initFile.isDirectory()) {
334             if (log.isDebugEnabled()) {
335                 log.debug("Configuration file not found with path [{}]", //$NON-NLS-1$
336
initFile.getAbsolutePath());
337             }
338             return false;
339         }
340
341         InputStream JavaDoc fileStream=null;
342         try {
343             fileStream = new FileInputStream JavaDoc(initFile);
344         }
345         catch (FileNotFoundException JavaDoc e1) {
346             log.debug("Configuration file not found with path [{}]", //$NON-NLS-1$
347
initFile.getAbsolutePath());
348             return false;
349         }
350
351         try {
352             envProperties.load(fileStream);
353             log.info("Loading configuration at {}", initFile.getAbsolutePath());//$NON-NLS-1$
354
}
355         catch (Exception JavaDoc e) {
356             log.error(e.getMessage(), e);
357             return false;
358         }
359         finally {
360             IOUtils.closeQuietly(fileStream);
361         }
362         return true;
363     }
364
365     /**
366      * Overload the properties with set system properties
367      */

368     protected void overloadWithSystemProperties() {
369         Iterator JavaDoc it = envProperties.entrySet().iterator();
370         while (it.hasNext()) {
371             Map.Entry JavaDoc param = (Map.Entry JavaDoc) it.next();
372             String JavaDoc value = (String JavaDoc)param.getValue();
373             if(System.getProperties().containsKey(param.getKey())){
374                 log.info("system property found: {}", param.getKey());
375                 value = (String JavaDoc) System.getProperty((String JavaDoc)param.getKey());
376             }
377             SystemProperty.setProperty((String JavaDoc) param.getKey(), value);
378         }
379     }
380 }
Popular Tags