View Javadoc

1   /*
2    * $Id: MuleXmlBuilderContextListener.java 21163 2011-02-01 14:44:53Z aperepel $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.config.builders;
12  
13  import org.mule.MuleServer;
14  import org.mule.api.MuleContext;
15  import org.mule.api.MuleException;
16  import org.mule.api.config.ConfigurationException;
17  import org.mule.api.config.MuleProperties;
18  import org.mule.api.context.MuleContextBuilder;
19  import org.mule.api.context.MuleContextFactory;
20  import org.mule.api.lifecycle.InitialisationException;
21  import org.mule.config.DefaultMuleConfiguration;
22  import org.mule.config.PropertiesMuleConfigurationFactory;
23  import org.mule.config.spring.SpringXmlConfigurationBuilder;
24  import org.mule.context.DefaultMuleContextBuilder;
25  import org.mule.context.DefaultMuleContextFactory;
26  import org.mule.util.FilenameUtils;
27  import org.mule.util.StringUtils;
28  
29  import java.io.File;
30  
31  import javax.servlet.ServletContext;
32  import javax.servlet.ServletContextEvent;
33  import javax.servlet.ServletContextListener;
34  
35  import org.apache.commons.logging.Log;
36  import org.apache.commons.logging.LogFactory;
37  import org.springframework.context.ApplicationContext;
38  import org.springframework.web.context.WebApplicationContext;
39  
40  /**
41   * <code>MuleXmlBuilderContextListener</code> is a bootstrap listener used to
42   * construct a {@link org.mule.api.MuleContext} instance. This listener delegates to the
43   * <i>MuleXmlConfigurationBuilder</i>.
44   * <p>
45   * The location of the configuration file can be specified in a init parameter called
46   * <i>org.mule.config</i>, the value can be a path on the local file system or on
47   * the classpath. If a config parameter is not specified a default <i>mule-config.xml</i>
48   * will be used.
49   * </p>
50   * 
51   * @see SpringXmlConfigurationBuilder
52   */
53  
54  public class MuleXmlBuilderContextListener implements ServletContextListener
55  {
56      /**
57       * One or more Mule config files.
58       */
59      public static final String INIT_PARAMETER_MULE_CONFIG = "org.mule.config";
60  
61      public static final String INIT_PARAMETER_MULE_APP_CONFIG = "org.mule.app.config";
62  
63      /**
64       * Name of the temp dir param as per the servlet spec. The object will be a java.io.File.
65       */
66      public static final String ATTR_JAVAX_SERVLET_CONTEXT_TEMPDIR = "javax.servlet.context.tempdir";
67  
68      protected MuleContext muleContext;
69  
70      protected transient final Log logger = LogFactory.getLog(MuleXmlBuilderContextListener.class);
71  
72      public void contextInitialized(ServletContextEvent event)
73      {
74          initialize(event.getServletContext());
75      }
76  
77      public void initialize(ServletContext context)
78      {
79          String config = context.getInitParameter(INIT_PARAMETER_MULE_CONFIG);
80          if (config == null)
81          {
82              config = getDefaultConfigResource();
83              if (logger.isDebugEnabled())
84              {
85                  logger.debug("No Mule config file(s) specified, using default: " + config);
86              }
87          }
88          else
89          {
90              if (logger.isDebugEnabled())
91              {
92                  logger.debug("Mule config file(s): " + config);
93              }
94          }
95  
96          try
97          {
98              muleContext = createMuleContext(config, context);
99              context.setAttribute(MuleProperties.MULE_CONTEXT_PROPERTY, muleContext);
100             muleContext.start();
101         }
102         catch (MuleException ex)
103         {
104             context.log(ex.getMessage(), ex);
105             // Logging is not configured OOTB for Tomcat, so we'd better make a
106             // start-up failure plain to see.
107             ex.printStackTrace();
108         }
109         catch (Error error)
110         {
111             // WSAD doesn't always report the java.lang.Error, log it
112             context.log(error.getMessage(), error);
113             // Logging is not configured OOTB for Tomcat, so we'd better make a
114             // start-up failure plain to see.
115             error.printStackTrace();
116             throw error;
117         }
118     }
119 
120     /**
121      * Creates the MuleContext based on the configuration resource(s) and possibly 
122      * init parameters for the Servlet.
123      */
124     protected MuleContext createMuleContext(String configResource, ServletContext servletContext)
125         throws ConfigurationException, InitialisationException
126     {
127         String serverId = StringUtils.defaultIfEmpty(servletContext.getInitParameter("mule.serverId"), null);
128 
129         // serverId will be used as a sub-folder in Mule working directory (.mule)
130 
131         if (serverId == null)
132         {
133             // guess this app's context name from the temp/work dir the container created us
134             // Servlet 2.5 has servletContext.getContextPath(), but we can't force users to upgrade yet
135             final File tempDir = (File) servletContext.getAttribute(ATTR_JAVAX_SERVLET_CONTEXT_TEMPDIR);
136             final String contextName = FilenameUtils.getBaseName(tempDir.toString());
137             serverId = contextName;
138         }
139 
140         WebappMuleXmlConfigurationBuilder builder = new WebappMuleXmlConfigurationBuilder(servletContext, configResource);
141         MuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
142 
143         String muleAppConfig = servletContext.getInitParameter(INIT_PARAMETER_MULE_APP_CONFIG) != null
144             ? servletContext.getInitParameter(INIT_PARAMETER_MULE_APP_CONFIG)
145             : PropertiesMuleConfigurationFactory.getMuleAppConfiguration(configResource);
146         
147         DefaultMuleConfiguration muleConfiguration = new PropertiesMuleConfigurationFactory(muleAppConfig).createConfiguration();
148 
149         /*
150             We deliberately enable container mode here to allow for multi-tenant environment (multiple WARs
151             embedding Mule instance each). See property javadocs for more info.
152          */
153         muleConfiguration.setContainerMode(true);
154 
155         if (serverId != null)
156         {
157             muleConfiguration.setId(serverId);
158         }
159         MuleContextBuilder muleContextBuilder = new DefaultMuleContextBuilder();
160         muleContextBuilder.setMuleConfiguration(muleConfiguration);
161 
162         // Support Spring-first configuration in webapps
163         final ApplicationContext parentContext = (ApplicationContext) servletContext.getAttribute(
164                                                         WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
165         if (parentContext != null)
166         {
167             builder.setParentContext(parentContext);
168         }
169         return muleContextFactory.createMuleContext(builder, muleContextBuilder);
170     }
171 
172     /**
173      * If no config location resource is configured on the servlet context, the value
174      * returned from this method will be used to initialise the MuleManager.
175      * 
176      * @return the default config resource location
177      */
178     protected String getDefaultConfigResource()
179     {
180         return MuleServer.DEFAULT_CONFIGURATION;
181     }
182 
183     public void contextDestroyed(ServletContextEvent event)
184     {
185         destroy();
186     }
187 
188     public void destroy()
189     {
190         if (muleContext != null)
191         {
192             if (!muleContext.isDisposing() || !muleContext.isDisposed())
193             {
194                 muleContext.dispose();
195             }
196         }
197     }
198 }