001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.common.xbean;
018
019 import java.io.File;
020 import java.util.ArrayList;
021 import java.util.Collection;
022 import java.util.Collections;
023 import java.util.HashMap;
024 import java.util.Iterator;
025 import java.util.List;
026 import java.util.Map;
027
028 import javax.jbi.management.DeploymentException;
029
030 import org.apache.servicemix.common.AbstractDeployer;
031 import org.apache.servicemix.common.Endpoint;
032 import org.apache.servicemix.common.EndpointComponentContext;
033 import org.apache.servicemix.common.ServiceMixComponent;
034 import org.apache.servicemix.common.ServiceUnit;
035 import org.apache.xbean.spring.context.FileSystemXmlApplicationContext;
036 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
037 import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
038 import org.springframework.context.support.AbstractXmlApplicationContext;
039 import org.springframework.core.io.FileSystemResource;
040
041 public class AbstractXBeanDeployer extends AbstractDeployer {
042
043 public AbstractXBeanDeployer(ServiceMixComponent component) {
044 super(component);
045 }
046
047 protected String getXBeanFile() {
048 return "xbean";
049 }
050
051 /* (non-Javadoc)
052 * @see org.apache.servicemix.common.Deployer#canDeploy(java.lang.String, java.lang.String)
053 */
054 public boolean canDeploy(String serviceUnitName, String serviceUnitRootPath) {
055 File xbean = new File(serviceUnitRootPath, getXBeanFile() + ".xml");
056 if (logger.isDebugEnabled()) {
057 logger.debug("Looking for " + xbean + ": " + xbean.exists());
058 }
059 return xbean.exists();
060 }
061
062 /* (non-Javadoc)
063 * @see org.apache.servicemix.common.Deployer#deploy(java.lang.String, java.lang.String)
064 */
065 public ServiceUnit deploy(String serviceUnitName, String serviceUnitRootPath) throws DeploymentException {
066 AbstractXmlApplicationContext applicationContext = null;
067 try {
068 // Create service unit
069 XBeanServiceUnit su = new XBeanServiceUnit();
070 su.setComponent(component);
071 su.setName(serviceUnitName);
072 su.setRootPath(serviceUnitRootPath);
073 // Load configuration
074 ClassLoader classLoader = component.getClass().getClassLoader();
075 Thread.currentThread().setContextClassLoader(classLoader);
076
077 File baseDir = new File(serviceUnitRootPath);
078 String location = getXBeanFile();
079 applicationContext = createApplicationContext(serviceUnitRootPath);
080
081 for (Iterator iter = getBeanFactoryPostProcessors(serviceUnitRootPath).iterator(); iter.hasNext();) {
082 BeanFactoryPostProcessor processor = (BeanFactoryPostProcessor) iter.next();
083 applicationContext.addBeanFactoryPostProcessor(processor);
084 }
085
086 applicationContext.refresh();
087 su.setApplicationContext(applicationContext);
088 // Use SU classloader
089 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
090 initApplicationContext(applicationContext);
091
092 // Retrieve endpoints
093 Collection<Endpoint> endpoints = getServices(applicationContext);
094 for (Endpoint endpoint : endpoints) {
095 endpoint.setServiceUnit(su);
096 validate(endpoint);
097 su.addEndpoint(endpoint);
098 }
099 validate(su);
100 return su;
101 } catch (Throwable e) {
102 logger.error(e);
103 if (applicationContext != null) {
104 try {
105 applicationContext.destroy();
106 } catch (Exception ne) {
107 logger.error(ne);
108 }
109 }
110 // There is a chance the thread context classloader has been changed by the xbean kernel,
111 // so put back a good one
112 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
113 if (e instanceof DeploymentException) {
114 throw ((DeploymentException) e);
115 } else {
116 throw failure("deploy", "Could not deploy xbean service unit", e);
117 }
118 } finally {
119 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
120 }
121 }
122
123 protected void initApplicationContext(AbstractXmlApplicationContext applicationContext) throws Exception {
124 }
125
126 protected Collection<Endpoint> getServices(AbstractXmlApplicationContext applicationContext) throws Exception {
127 return applicationContext.getBeansOfType(Endpoint.class).values();
128 }
129
130 protected FileSystemXmlApplicationContext createApplicationContext(String serviceUnitRootPath) {
131 File baseDir = new File(serviceUnitRootPath);
132 String location = getXBeanFile();
133 return new FileSystemXmlApplicationContext(
134 new String[] { "/" + baseDir.toURI().resolve(location).getPath() + ".xml" },
135 false,
136 getXmlPreProcessors(serviceUnitRootPath));
137 }
138
139 protected List getXmlPreProcessors(String serviceUnitRootPath) {
140 ClassLoaderXmlPreprocessor classLoaderXmlPreprocessor = new ClassLoaderXmlPreprocessor(new File(serviceUnitRootPath), component);
141 return Collections.singletonList(classLoaderXmlPreprocessor);
142 }
143
144 protected List getBeanFactoryPostProcessors(String serviceUnitRootPath) {
145 List processors = new ArrayList();
146 // Property place holder
147 PropertyPlaceholderConfigurer propertyPlaceholder = new PropertyPlaceholderConfigurer();
148 FileSystemResource propertiesFile = new FileSystemResource(new File(serviceUnitRootPath) + "/" + getXBeanFile() + ".properties");
149 if (propertiesFile.getFile().exists()) {
150 propertyPlaceholder.setLocation(propertiesFile);
151 processors.add(propertyPlaceholder);
152 }
153 // Parent beans map
154 Map beans = getParentBeansMap();
155 if (beans != null) {
156 processors.add(new ParentBeanFactoryPostProcessor(beans));
157 }
158 return processors;
159 }
160
161 protected Map getParentBeansMap() {
162 Map beans = new HashMap();
163 beans.put("context", new EndpointComponentContext(component.getComponentContext()));
164 beans.put("component", component);
165 Object smx3 = component.getSmx3Container();
166 if (smx3 != null) {
167 beans.put("container", smx3);
168 }
169 return beans;
170 }
171
172 }