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 Thread.currentThread().setContextClassLoader(component.getClass().getClassLoader());
075
076 SpringLoader springLoader = createSpringLoader();
077 springLoader.setKernel(kernel);
078 springLoader.setBaseDir(new File(serviceUnitRootPath));
079 springLoader.setXmlPreprocessors(getXmlPreProcessors(serviceUnitRootPath));
080 springLoader.setBeanFactoryPostProcessors(getBeanFactoryPostProcessors(serviceUnitRootPath));
081
082 ServiceName configurationName = springLoader.load(getXBeanFile());
083 kernel.startService(configurationName);
084 su.setConfiguration(configurationName);
085 // Use SU classloader
086 Thread.currentThread().setContextClassLoader(su.getConfigurationClassLoader());
087 // Retrieve endpoints
088 List services = getServices(kernel);
089 if (services == null || services.size() == 0) {
090 throw failure("deploy", "No endpoints found", null);
091 }
092 for (Iterator iter = services.iterator(); iter.hasNext();) {
093 Endpoint endpoint = (Endpoint) iter.next();
094 endpoint.setServiceUnit(su);
095 validate(endpoint);
096 su.addEndpoint(endpoint);
097 }
098 if (su.getEndpoints().size() == 0) {
099 throw failure("deploy", "No endpoint found", null);
100 }
101 return su;
102 } catch (Throwable e) {
103 // There is a chance the thread context classloader has been changed by the xbean kernel,
104 // so put back a good one
105 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
106 kernel.destroy();
107 if (e instanceof DeploymentException) {
108 throw ((DeploymentException) e);
109 } else {
110 throw failure("deploy", "Could not deploy xbean service unit", e);
111 }
112 } finally {
113 Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
114 }
115 }
116
117 /**
118 * A factory method to allow derived classes to create alternative spring loaders
119 */
120 protected SpringLoader createSpringLoader() {
121 return new SpringLoader();
122 }
123
124 protected List getServices(Kernel kernel) throws DeploymentException {
125 return kernel.getServices(Endpoint.class);
126 }
127
128 protected List getXmlPreProcessors(String serviceUnitRootPath) {
129 JBIContainer container = null;
130 try {
131 container = ((ComponentContextImpl) component.getComponentContext()).getContainer();
132 } catch (Throwable t) { }
133 FileSystemRepository repository = new FileSystemRepository(new File(serviceUnitRootPath));
134 ClassLoaderXmlPreprocessor classLoaderXmlPreprocessor = new ClassLoaderXmlPreprocessor(repository, container);
135 return Collections.singletonList(classLoaderXmlPreprocessor);
136 }
137
138 protected List getBeanFactoryPostProcessors(String serviceUnitRootPath) {
139 PropertyPlaceholderConfigurer propertyPlaceholder = new PropertyPlaceholderConfigurer();
140 FileSystemResource propertiesFile = new FileSystemResource(
141 new File(serviceUnitRootPath) + "/" + getXBeanFile()
142 + ".properties");
143 if (propertiesFile.getFile().exists()) {
144 propertyPlaceholder.setLocation(propertiesFile);
145 return Collections.singletonList(propertyPlaceholder);
146 }
147 return Collections.EMPTY_LIST;
148 }
149
150 }