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 org.apache.servicemix.common.AbstractDeployer;
020 import org.apache.servicemix.common.Endpoint;
021 import org.apache.servicemix.common.ServiceMixComponent;
022 import org.apache.servicemix.common.ServiceUnit;
023 import org.apache.servicemix.jbi.container.JBIContainer;
024 import org.apache.servicemix.jbi.framework.ComponentContextImpl;
025 import org.apache.xbean.kernel.Kernel;
026 import org.apache.xbean.kernel.KernelFactory;
027 import org.apache.xbean.kernel.ServiceName;
028 import org.apache.xbean.server.repository.FileSystemRepository;
029 import org.apache.xbean.server.spring.loader.SpringLoader;
030 import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
031 import org.springframework.core.io.FileSystemResource;
032
033 import javax.jbi.component.ComponentContext;
034 import javax.jbi.management.DeploymentException;
035 import java.io.File;
036 import java.util.Collections;
037 import java.util.Iterator;
038 import java.util.List;
039
040 public class AbstractXBeanDeployer extends AbstractDeployer {
041
042 public AbstractXBeanDeployer(ServiceMixComponent component) {
043 super(component);
044 }
045
046 protected String getXBeanFile() {
047 return "xbean";
048 }
049
050 /* (non-Javadoc)
051 * @see org.apache.servicemix.common.Deployer#canDeploy(java.lang.String, java.lang.String)
052 */
053 public boolean canDeploy(String serviceUnitName, String serviceUnitRootPath) {
054 File xbean = new File(serviceUnitRootPath, getXBeanFile() + ".xml");
055 if (logger.isDebugEnabled()) {
056 logger.debug("Looking for " + xbean + ": " + xbean.exists());
057 }
058 return xbean.exists();
059 }
060
061 /* (non-Javadoc)
062 * @see org.apache.servicemix.common.Deployer#deploy(java.lang.String, java.lang.String)
063 */
064 public ServiceUnit deploy(String serviceUnitName, String serviceUnitRootPath) throws DeploymentException {
065 Kernel kernel = KernelFactory.newInstance().createKernel(component.getComponentName() + "/" + serviceUnitName);
066 try {
067 // Create service unit
068 XBeanServiceUnit su = new XBeanServiceUnit();
069 su.setKernel(kernel);
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 SpringLoader springLoader = createSpringLoader();
078 springLoader.setKernel(kernel);
079 springLoader.setBaseDir(new File(serviceUnitRootPath));
080 springLoader.setXmlPreprocessors(getXmlPreProcessors(serviceUnitRootPath));
081 springLoader.setBeanFactoryPostProcessors(getBeanFactoryPostProcessors(serviceUnitRootPath));
082
083 ServiceName configurationName = springLoader.load(getXBeanFile());
084 kernel.startService(configurationName);
085 su.setConfiguration(configurationName);
086 // Use SU classloader
087 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
088 // Retrieve endpoints
089 List services = getServices(kernel);
090 if (services == null || services.size() == 0) {
091 throw failure("deploy", "No endpoints found", null);
092 }
093 for (Iterator iter = services.iterator(); iter.hasNext();) {
094 Endpoint endpoint = (Endpoint) iter.next();
095 endpoint.setServiceUnit(su);
096 validate(endpoint);
097 su.addEndpoint(endpoint);
098 }
099 if (su.getEndpoints().size() == 0) {
100 throw failure("deploy", "No endpoint found", null);
101 }
102 return su;
103 } catch (Throwable e) {
104 // There is a chance the thread context classloader has been changed by the xbean kernel,
105 // so put back a good one
106 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
107 kernel.destroy();
108 if (e instanceof DeploymentException) {
109 throw ((DeploymentException) e);
110 } else {
111 throw failure("deploy", "Could not deploy xbean service unit", e);
112 }
113 } finally {
114 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
115 }
116 }
117
118 /**
119 * A factory method to allow derived classes to create alternative spring loaders
120 */
121 protected SpringLoader createSpringLoader() {
122 return new SpringLoader();
123 }
124
125 protected List getServices(Kernel kernel) throws DeploymentException {
126 return kernel.getServices(Endpoint.class);
127 }
128
129 protected List getXmlPreProcessors(String serviceUnitRootPath) {
130 JBIContainer container = null;
131 try {
132 container = ((ComponentContextImpl) component.getComponentContext()).getContainer();
133 } catch (Throwable t) { }
134 FileSystemRepository repository = new FileSystemRepository(new File(serviceUnitRootPath));
135 ClassLoaderXmlPreprocessor classLoaderXmlPreprocessor = new ClassLoaderXmlPreprocessor(repository, container);
136 return Collections.singletonList(classLoaderXmlPreprocessor);
137 }
138
139 protected List getBeanFactoryPostProcessors(String serviceUnitRootPath) {
140 PropertyPlaceholderConfigurer propertyPlaceholder = new PropertyPlaceholderConfigurer();
141 FileSystemResource propertiesFile = new FileSystemResource(
142 new File(serviceUnitRootPath) + "/" + getXBeanFile()
143 + ".properties");
144 if (propertiesFile.getFile().exists()) {
145 propertyPlaceholder.setLocation(propertiesFile);
146 return Collections.singletonList(propertyPlaceholder);
147 }
148 return Collections.EMPTY_LIST;
149 }
150
151 }