View Javadoc

1   /*
2    * $Id: MuleApplicationContext.java 10997 2008-02-25 18:38:06Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.spring;
12  
13  import org.mule.api.MuleContext;
14  import org.mule.api.registry.Registry;
15  import org.mule.config.ConfigResource;
16  import org.mule.util.ClassUtils;
17  import org.mule.util.IOUtils;
18  
19  import java.io.IOException;
20  
21  import org.springframework.beans.BeansException;
22  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
23  import org.springframework.beans.factory.support.AbstractBeanFactory;
24  import org.springframework.beans.factory.support.DefaultListableBeanFactory;
25  import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
26  import org.springframework.context.ApplicationContext;
27  import org.springframework.context.support.AbstractXmlApplicationContext;
28  import org.springframework.core.io.ByteArrayResource;
29  import org.springframework.core.io.Resource;
30  import org.springframework.core.io.UrlResource;
31  
32  /**
33   * <code>MuleApplicationContext</code> is a simple extension application context
34   * that allows resources to be loaded from the Classpath of file system using the
35   * MuleBeanDefinitionReader.
36   *
37   */
38  public class MuleApplicationContext extends AbstractXmlApplicationContext
39  {
40      public static final String LEGACY_BEAN_READER_CLASS = "org.mule.config.spring.MuleBeanDefinitionReader";
41  
42      private MuleContext muleContext;
43      private Resource[] springResources;
44  
45      /**
46       * Parses configuration files creating a spring ApplicationContext which is used
47       * as a parent registry using the SpringRegistry registry implementation to wraps
48       * the spring ApplicationContext
49       * 
50       * @param registry
51       * @param configResources
52       * @see org.mule.config.spring.SpringRegistry
53       */
54      public MuleApplicationContext(MuleContext muleContext, Registry registry, ConfigResource[] configResources)
55      {
56          this(muleContext, registry, configResources, true);
57      }
58      
59      /**
60       * Parses configuration files creating a spring ApplicationContext which is used
61       * as a parent registry using the SpringRegistry registry implementation to wraps
62       * the spring ApplicationContext
63       * 
64       * @param registry
65       * @param configLocations
66       * @param parent 
67       * @see org.mule.config.spring.SpringRegistry
68       */
69      public MuleApplicationContext(MuleContext muleContext, Registry registry, ConfigResource[] configResources, ApplicationContext parent)
70      {
71          super(parent);
72          setupParentSpringRegistry(registry);
73          this.muleContext = muleContext;
74          this.springResources = convert(configResources);
75          refresh();
76      }
77  
78      
79      /**
80       * @param registry
81       * @param configLocations
82       */
83      public MuleApplicationContext(MuleContext muleContext, Registry registry, Resource[] configResources)
84      {
85          this(muleContext, registry, configResources, true);
86      }
87  
88      /**
89       * @param registry
90       * @param configResources
91       * @param refresh
92       * @throws BeansException
93       */
94      public MuleApplicationContext(MuleContext muleContext, Registry registry, ConfigResource[] configResources, boolean refresh)
95              throws BeansException
96      {
97          this.muleContext = muleContext;
98          setupParentSpringRegistry(registry);
99          this.springResources = convert(configResources);
100         if (refresh)
101         {
102             refresh();
103         }
104     }
105 
106     /**
107      * @param registry
108      * @param configLocations
109      * @param parent 
110      */
111     public MuleApplicationContext(MuleContext muleContext, Registry registry, Resource[] springResources, ApplicationContext parent) throws IOException
112     {
113         super(parent);
114         this.muleContext = muleContext;
115         setupParentSpringRegistry(registry);
116         this.springResources = springResources;
117         refresh();
118     }
119 
120     /**
121      * @param registry
122      * @param configLocations
123      * @param refresh
124      * @throws BeansException 
125      */
126     public MuleApplicationContext(MuleContext muleContext, Registry registry, Resource[] springResources, boolean refresh)
127             throws BeansException
128     {
129         setupParentSpringRegistry(registry);
130         this.muleContext = muleContext;
131         this.springResources = springResources;
132         if (refresh)
133         {
134             refresh();
135         }
136     }
137 
138     /**
139      * Sets up TransientRegistry SpringRegistry parent relationship here. This is
140      * required here before "refresh()" rather than in the configuration builder
141      * after parsing the spring config because spring executes the initialize phase
142      * for objects it manages during "refresh()" and during intialization of mule
143      * artifacts need to be able to lookup other artifacts both in TransientRegistry
144      * and in spring (using SpringRegistry facade) by using the mule Registry
145      * interface.
146      *
147      * @param registry
148      */
149     protected void setupParentSpringRegistry(Registry registry)
150     {
151         registry.setParent(new SpringRegistry(this));
152     }
153 
154     protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
155         super.prepareBeanFactory(beanFactory);
156         beanFactory.addBeanPostProcessor(new MuleContextPostProcessor(muleContext));
157     }
158 
159     private Resource[] convert(ConfigResource[] resources)
160     {
161         Resource[] configResources = new Resource[resources.length];
162         for (int i = 0; i < resources.length; i++)
163         {
164             ConfigResource resource = resources[i];
165             if(resource.getUrl()!=null)
166             {
167                 configResources[i] = new UrlResource(resource.getUrl());
168             }
169             else
170             {
171                 try
172                 {
173                     configResources[i] = new ByteArrayResource(IOUtils.toByteArray(resource.getInputStream()), resource.getResourceName());
174                 }
175                 catch (IOException e)
176                 {
177                     //ignore, should never happen
178                 }
179             }
180         }
181         return configResources;
182     }
183 
184     //@Override
185     protected Resource[] getConfigResources()
186     {
187         return springResources;
188     }
189 
190     protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException
191     {
192         XmlBeanDefinitionReader beanDefinitionReader;
193 
194         //If the migration module is on the classpath, lets use the MuleBeanDefinitionReader, that allws use
195         //to process Mule 1.x configuration as well as Mule 2.x.
196         if (ClassUtils.isClassOnPath(LEGACY_BEAN_READER_CLASS, getClass()))
197         {
198             try
199             {
200                 beanDefinitionReader = (XmlBeanDefinitionReader) ClassUtils.instanciateClass(
201                         LEGACY_BEAN_READER_CLASS, new Object[] {beanFactory, springResources});
202             }
203             catch (Exception e)
204             {
205                 throw new RuntimeException(e);
206             }
207         }
208         else
209         {
210             beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
211         }
212         //hook in our custom hierarchical reader
213         beanDefinitionReader.setDocumentReaderClass(MuleBeanDefinitionDocumentReader.class);
214         //add error reporting
215         beanDefinitionReader.setProblemReporter(new MissingParserProblemReporter());
216         beanDefinitionReader.loadBeanDefinitions(springResources);
217     }
218 
219     //@Override
220     protected DefaultListableBeanFactory createBeanFactory()
221     {
222         //Copy all postProcessors defined in the defaultMuleConfig so that they get applied to the child container
223         DefaultListableBeanFactory bf = super.createBeanFactory();
224         if(getParent()!=null)
225         {
226             //Copy over all processors
227             AbstractBeanFactory beanFactory = (AbstractBeanFactory)getParent().getAutowireCapableBeanFactory();
228             bf.copyConfigurationFrom(beanFactory);
229         }
230         return bf;
231     }
232 
233 }