blob: 4eb219e838f776a72c1f2cdb6d297ff889d8e6b8 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2006, 2010 VMware Inc.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html and the Apache License v2.0
* is available at http://www.opensource.org/licenses/apache2.0.php.
* You may elect to redistribute this code under either of these licenses.
*
* Contributors:
* VMware Inc.
*****************************************************************************/
package org.eclipse.gemini.blueprint.test.platform;
import java.io.File;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.felix.framework.Felix;
import org.apache.felix.framework.util.StringMap;
import org.apache.felix.main.AutoProcessor;
import org.apache.felix.main.Main;
import org.eclipse.gemini.blueprint.test.internal.util.IOUtils;
import org.osgi.framework.BundleContext;
import org.springframework.beans.BeanUtils;
import org.springframework.util.ClassUtils;
/**
* Apache Felix (1.0.3+/1.4.x+/2.0.x) OSGi platform. Automatically detects the available version on the classpath and
* uses the appropriate means to configure and instantiate it.
*
* @author Costin Leau
*/
public class FelixPlatform extends AbstractOsgiPlatform {
private static abstract class Felix1XPlatform implements Platform {
private static final Constructor<?> CTOR;
static {
Class<?> autoActivator =
ClassUtils.resolveClassName("org.apache.felix.main.AutoActivator", Felix1XPlatform.class
.getClassLoader());
try {
CTOR = autoActivator.getConstructor(Map.class);
} catch (Exception ex) {
throw new IllegalStateException("Cannot instantiate class " + autoActivator, ex);
}
}
private Felix felix;
public final BundleContext start() throws Exception {
// load properties
Map<String, String> configMap = getConfiguration();
// pass the auto activator as a list
List<Object> list = new ArrayList<Object>(1);
list.add(BeanUtils.instantiateClass(CTOR, configMap));
felix = createFelix(configMap, list);
felix.start();
return felix.getBundleContext();
}
public final void stop() throws Exception {
felix.stop();
}
abstract Felix createFelix(Map<String, String> configMap, List<?> activators) throws Exception;
}
// private static class Felix10XPlatform extends Felix1XPlatform {
//
// private static final Constructor<Felix> CTOR;
// static {
// try {
// CTOR = Felix.class.getConstructor(Map.class, List.class);
// } catch (NoSuchMethodException ex) {
// throw new IllegalStateException("Cannot find Felix constructor", ex);
// }
// }
//
// @Override
// Felix createFelix(Map<Object, Object> configMap, List<?> activators) throws Exception {
//
// return CTOR.newInstance(configMap, activators);
// }
// }
// private static class Felix14XPlatform extends Felix1XPlatform {
//
// @Override
// Felix createFelix(Map<Object, Object> configMap, List<?> activators) throws Exception {
// configMap.put("felix.systembundle.activators", activators);
// return new Felix(configMap);
// }
// }
private static class Felix20XPlatform implements Platform {
private FrameworkTemplate fwkTemplate;
private final Log log;
Felix20XPlatform(Log log) {
this.log = log;
}
public BundleContext start() throws Exception {
Map<String, String> configMap = getConfiguration();
Felix fx = new Felix(configMap);
fwkTemplate = new DefaultFrameworkTemplate(fx, log);
fwkTemplate.init();
BundleContext context = fx.getBundleContext();
AutoProcessor.process(configMap, context);
fwkTemplate.start();
return context;
}
public void stop() throws Exception {
fwkTemplate.stopAndWait(1000);
}
}
// private static enum FelixVersion {
// V_10X, V_14X, V_20X
// }
// private static FelixVersion FELIX_VERSION;
private static final Log log = LogFactory.getLog(FelixPlatform.class);
private static final String FELIX_PROFILE_DIR_PROPERTY = "felix.cache.profiledir";
/** new property in 1.4.0 replacing cache.profiledir */
private static final String OSGI_STORAGE_PROPERTY = "org.osgi.framework.storage";
// static {
// ClassLoader loader = Felix.class.getClassLoader();
// detect available Felix version
// if (ClassUtils.isPresent("org.apache.felix.main.AutoProcessor", loader)) {
// FELIX_VERSION = FelixVersion.V_20X;
// } else {
// if (ClassUtils.isPresent("org.apache.felix.main.RegularBundleInfo", loader)) {
// FELIX_VERSION = FelixVersion.V_14X;
// }
// FELIX_VERSION = FelixVersion.V_10X;
// }
// }
private BundleContext context;
private File felixStorageDir;
private Platform platform;
public FelixPlatform() {
toString = "Felix OSGi Platform";
}
Properties getPlatformProperties() {
// load Felix configuration
Properties props = new Properties();
createStorageDir(props);
// disable logging
props.put("felix.log.level", "0");
// use embedded mode
props.put("felix.embedded.execution", "true");
return props;
}
public BundleContext getBundleContext() {
return context;
}
/**
* Configuration settings for the OSGi test run.
*
* @return
*/
private void createStorageDir(Properties configProperties) {
// create a temporary file if none is set
if (felixStorageDir == null) {
felixStorageDir = createTempDir("felix");
felixStorageDir.deleteOnExit();
if (log.isTraceEnabled())
log.trace("Felix storage dir is " + felixStorageDir.getAbsolutePath());
}
configProperties.setProperty(FELIX_PROFILE_DIR_PROPERTY, this.felixStorageDir.getAbsolutePath());
configProperties.setProperty(OSGI_STORAGE_PROPERTY, this.felixStorageDir.getAbsolutePath());
configProperties.setProperty("org.osgi.framework.storage.clean", "onFirstInit");
}
public void start() throws Exception {
if (platform == null) {
// initialize properties and set them as system wide so Felix can pick them up
Map<Object, Object> configProperties = getConfigurationProperties();
System.getProperties().putAll(configProperties);
platform = new Felix20XPlatform(LogFactory.getLog(Felix20XPlatform.class));
// switch (FELIX_VERSION) {
// case V_20X:
// platform = new Felix20XPlatform(null);
// break;
// case V_14X:
// platform = new Felix14XPlatform();
// break;
// // fallback to 10-12 version
// default:
// platform = new Felix10XPlatform();
// break;
// }
context = platform.start();
}
}
/**
* Returns the platform configuration for creating a Felix instance. Uses Felix classes to load and process the
* system properties.
*
* @return Felix configuration
*/
private static Map<String, String> getConfiguration() {
// Load system properties.
Main.loadSystemProperties();
// Read configuration properties.
Map<String, String> configProps = Main.loadConfigProperties();
if (configProps == null) {
configProps = new HashMap<String, String>();
}
// Copy framework properties from the system properties.
Main.copySystemProperties(configProps);
// Create a (Felix specific) case-insensitive property map
// return new StringMap(configProps, false);
return configProps;
}
public void stop() throws Exception {
if (platform != null) {
try {
platform.stop();
} finally {
context = null;
platform = null;
// remove cache folder
IOUtils.delete(felixStorageDir);
}
}
}
}