001: /*
002: * $Id: MuleApplicationContext.java 10997 2008-02-25 18:38:06Z dfeist $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.config.spring;
012:
013: import org.mule.api.MuleContext;
014: import org.mule.api.registry.Registry;
015: import org.mule.config.ConfigResource;
016: import org.mule.util.ClassUtils;
017: import org.mule.util.IOUtils;
018:
019: import java.io.IOException;
020:
021: import org.springframework.beans.BeansException;
022: import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
023: import org.springframework.beans.factory.support.AbstractBeanFactory;
024: import org.springframework.beans.factory.support.DefaultListableBeanFactory;
025: import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
026: import org.springframework.context.ApplicationContext;
027: import org.springframework.context.support.AbstractXmlApplicationContext;
028: import org.springframework.core.io.ByteArrayResource;
029: import org.springframework.core.io.Resource;
030: import org.springframework.core.io.UrlResource;
031:
032: /**
033: * <code>MuleApplicationContext</code> is a simple extension application context
034: * that allows resources to be loaded from the Classpath of file system using the
035: * MuleBeanDefinitionReader.
036: *
037: */
038: public class MuleApplicationContext extends
039: AbstractXmlApplicationContext {
040: public static final String LEGACY_BEAN_READER_CLASS = "org.mule.config.spring.MuleBeanDefinitionReader";
041:
042: private MuleContext muleContext;
043: private Resource[] springResources;
044:
045: /**
046: * Parses configuration files creating a spring ApplicationContext which is used
047: * as a parent registry using the SpringRegistry registry implementation to wraps
048: * the spring ApplicationContext
049: *
050: * @param registry
051: * @param configResources
052: * @see org.mule.config.spring.SpringRegistry
053: */
054: public MuleApplicationContext(MuleContext muleContext,
055: Registry registry, ConfigResource[] configResources) {
056: this (muleContext, registry, configResources, true);
057: }
058:
059: /**
060: * Parses configuration files creating a spring ApplicationContext which is used
061: * as a parent registry using the SpringRegistry registry implementation to wraps
062: * the spring ApplicationContext
063: *
064: * @param registry
065: * @param configLocations
066: * @param parent
067: * @see org.mule.config.spring.SpringRegistry
068: */
069: public MuleApplicationContext(MuleContext muleContext,
070: Registry registry, ConfigResource[] configResources,
071: ApplicationContext parent) {
072: super (parent);
073: setupParentSpringRegistry(registry);
074: this .muleContext = muleContext;
075: this .springResources = convert(configResources);
076: refresh();
077: }
078:
079: /**
080: * @param registry
081: * @param configLocations
082: */
083: public MuleApplicationContext(MuleContext muleContext,
084: Registry registry, Resource[] configResources) {
085: this (muleContext, registry, configResources, true);
086: }
087:
088: /**
089: * @param registry
090: * @param configResources
091: * @param refresh
092: * @throws BeansException
093: */
094: public MuleApplicationContext(MuleContext muleContext,
095: Registry registry, ConfigResource[] configResources,
096: boolean refresh) throws BeansException {
097: this .muleContext = muleContext;
098: setupParentSpringRegistry(registry);
099: this .springResources = convert(configResources);
100: if (refresh) {
101: refresh();
102: }
103: }
104:
105: /**
106: * @param registry
107: * @param configLocations
108: * @param parent
109: */
110: public MuleApplicationContext(MuleContext muleContext,
111: Registry registry, Resource[] springResources,
112: ApplicationContext parent) throws IOException {
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,
127: Registry registry, Resource[] springResources,
128: boolean refresh) throws BeansException {
129: setupParentSpringRegistry(registry);
130: this .muleContext = muleContext;
131: this .springResources = springResources;
132: if (refresh) {
133: refresh();
134: }
135: }
136:
137: /**
138: * Sets up TransientRegistry SpringRegistry parent relationship here. This is
139: * required here before "refresh()" rather than in the configuration builder
140: * after parsing the spring config because spring executes the initialize phase
141: * for objects it manages during "refresh()" and during intialization of mule
142: * artifacts need to be able to lookup other artifacts both in TransientRegistry
143: * and in spring (using SpringRegistry facade) by using the mule Registry
144: * interface.
145: *
146: * @param registry
147: */
148: protected void setupParentSpringRegistry(Registry registry) {
149: registry.setParent(new SpringRegistry(this ));
150: }
151:
152: protected void prepareBeanFactory(
153: ConfigurableListableBeanFactory beanFactory) {
154: super .prepareBeanFactory(beanFactory);
155: beanFactory.addBeanPostProcessor(new MuleContextPostProcessor(
156: muleContext));
157: }
158:
159: private Resource[] convert(ConfigResource[] resources) {
160: Resource[] configResources = new Resource[resources.length];
161: for (int i = 0; i < resources.length; i++) {
162: ConfigResource resource = resources[i];
163: if (resource.getUrl() != null) {
164: configResources[i] = new UrlResource(resource.getUrl());
165: } else {
166: try {
167: configResources[i] = new ByteArrayResource(IOUtils
168: .toByteArray(resource.getInputStream()),
169: resource.getResourceName());
170: } catch (IOException e) {
171: //ignore, should never happen
172: }
173: }
174: }
175: return configResources;
176: }
177:
178: //@Override
179: protected Resource[] getConfigResources() {
180: return springResources;
181: }
182:
183: protected void loadBeanDefinitions(
184: DefaultListableBeanFactory beanFactory) throws IOException {
185: XmlBeanDefinitionReader beanDefinitionReader;
186:
187: //If the migration module is on the classpath, lets use the MuleBeanDefinitionReader, that allws use
188: //to process Mule 1.x configuration as well as Mule 2.x.
189: if (ClassUtils.isClassOnPath(LEGACY_BEAN_READER_CLASS,
190: getClass())) {
191: try {
192: beanDefinitionReader = (XmlBeanDefinitionReader) ClassUtils
193: .instanciateClass(LEGACY_BEAN_READER_CLASS,
194: new Object[] { beanFactory,
195: springResources });
196: } catch (Exception e) {
197: throw new RuntimeException(e);
198: }
199: } else {
200: beanDefinitionReader = new XmlBeanDefinitionReader(
201: beanFactory);
202: }
203: //hook in our custom hierarchical reader
204: beanDefinitionReader
205: .setDocumentReaderClass(MuleBeanDefinitionDocumentReader.class);
206: //add error reporting
207: beanDefinitionReader
208: .setProblemReporter(new MissingParserProblemReporter());
209: beanDefinitionReader.loadBeanDefinitions(springResources);
210: }
211:
212: //@Override
213: protected DefaultListableBeanFactory createBeanFactory() {
214: //Copy all postProcessors defined in the defaultMuleConfig so that they get applied to the child container
215: DefaultListableBeanFactory bf = super .createBeanFactory();
216: if (getParent() != null) {
217: //Copy over all processors
218: AbstractBeanFactory beanFactory = (AbstractBeanFactory) getParent()
219: .getAutowireCapableBeanFactory();
220: bf.copyConfigurationFrom(beanFactory);
221: }
222: return bf;
223: }
224:
225: }
|