import java.io.File;
import java.io.FileInputStream;
-import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
+import java.util.StringTokenizer;
import java.util.Vector;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.felix.framework.Felix;
-import org.apache.felix.framework.cache.BundleCache;
-import org.apache.felix.main.AutoActivator;
+import org.eclipse.core.runtime.adaptor.EclipseStarter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
public class Main {
- private final static Log log = LogFactory.getLog(Main.class);
+ private final static String DEV_BUNDLE_PREFIX = "slc.osgi.devbundle.";
public static void main(String[] args) {
- log.info("Argeo SLC Detached launcher starting...");
+ info("Argeo SLC Detached launcher starting...");
try {
// Load properties
String propertyPath = "slc-detached.properties";
Properties config = prepareConfig(propertyPath);
- // Create cache dir
- if (!config.containsKey(BundleCache.CACHE_PROFILE_DIR_PROP)) {
- final File cachedir = createTemporaryCacheDir();
- config.put(BundleCache.CACHE_PROFILE_DIR_PROP, cachedir
- .getAbsolutePath());
- }
-
// Start app (in main class loader)
startApp(config);
- // Thread.sleep(10000);
-
- // Start OSGi system
- Felix felix = startSystem(config);
- log.info("Argeo SLC Detached system started (Felix " + felix + ")");
-
- // felix.stop();
+ // Start OSGi framework
+ try {
+ startEquinox(config);
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ info("Argeo SLC Detached launcher started.");
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
protected static Properties prepareConfig(String propertyFilePath)
throws Exception {
+ // Format slc.home
+ String slcHome = System.getProperty("slc.home");
+ if (slcHome != null) {
+ slcHome = new File(slcHome).getCanonicalPath();
+ System.setProperty("slc.home", slcHome);
+ }
+
// Load config
Properties config = new Properties();
InputStream in = null;
- ;
- try {
- in = Main.class
- .getResourceAsStream("/org/argeo/slc/detached/launcher/felix.properties");
- config.load(in);
- } finally {
- if (in != null)
- in.close();
- }
-
try {
- in = new FileInputStream(propertyFilePath);
- config.load(in);
+ File file = new File(propertyFilePath);
+ if (file.exists()) {
+ in = new FileInputStream(propertyFilePath);
+ config.load(in);
+ }
} finally {
if (in != null)
in.close();
// System properties have priority.
config.putAll(System.getProperties());
+ return config;
+ }
+
+ public static void startEquinox(Properties config) throws Exception {
+ System.out.println("java.class.path="
+ + System.getProperty("java.class.path"));
+
+ File baseDir = new File(System.getProperty("user.dir"))
+ .getCanonicalFile();
+ String equinoxConfigurationPath = baseDir.getPath() + File.separator
+ + "slc-detached" + File.separator + "equinoxConfiguration";
+ String[] equinoxArgs = { "-console", "-noExit", "-clean", "-debug",
+ "-configuration", equinoxConfigurationPath };
+
+ BundleContext context = EclipseStarter.startup(equinoxArgs, null);
+
+ // Load from class path (dev environment, maven)
+ StringTokenizer st = new StringTokenizer(System
+ .getProperty("java.class.path"), File.pathSeparator);
+ while (st.hasMoreTokens()) {
+ try {
+ String path = st.nextToken();
+ String url = "reference:file:"
+ + new File(path).getCanonicalPath();
+ context.installBundle(url);
+ info("Installed from classpath " + url);
+ } catch (Exception e) {
+ bundleInstallWarn(e.getMessage());
+ }
+ }
- // Perform variable substitution for system properties.
- for (Enumeration e = config.propertyNames(); e.hasMoreElements();) {
- String name = (String) e.nextElement();
- config.setProperty(name, org.apache.felix.main.Main.substVars(
- config.getProperty(name), name, null, config));
- if (log.isTraceEnabled())
- log.trace(name + "=" + config.getProperty(name));
+ // Load from dev bundles
+ Map devBundleUrls = getDevBundleUrls(config);
+ Iterator devBundles = devBundleUrls.keySet().iterator();
+ while (devBundles.hasNext()) {
+ try {
+ String bundleName = (String) devBundles.next();
+ String url = (String) devBundleUrls.get(bundleName);
+ context.installBundle(url);
+ info("Installed as dev bundle " + url);
+ } catch (Exception e) {
+ bundleInstallWarn(e.getMessage());
+ }
}
- return config;
+ // Load from distribution
+ String slcHome = config.getProperty("slc.home");
+ if (slcHome != null) {
+ File libDir = new File(slcHome + File.separator + "lib");
+ File[] bundleFiles = libDir.listFiles();
+ for (int i = 0; i < bundleFiles.length; i++) {
+ try {
+ String url = "reference:file:"
+ + bundleFiles[i].getCanonicalPath();
+ context.installBundle(url);
+ info("INFO: Installed from SLC home " + url);
+ } catch (Exception e) {
+ bundleInstallWarn(e.getMessage());
+ }
+
+ }
+ }
+
+ // Start bundles
+ String bundleStart = config.getProperty("slc.osgi.start",
+ "org.springframework.osgi.extender,org.argeo.slc.detached");
+ StringTokenizer stBundleStart = new StringTokenizer(bundleStart, ",");
+ while (stBundleStart.hasMoreTokens()) {
+ String bundleSymbolicName = stBundleStart.nextToken();
+ startBundle(context, bundleSymbolicName);
+ }
}
- protected static File createTemporaryCacheDir() throws IOException {
- // Create a temporary bundle cache directory and
- // make sure to clean it up on exit.
- final File cachedir = File.createTempFile("argeo.slc.autoui", null);
- cachedir.delete();
- Runtime.getRuntime().addShutdownHook(new Thread() {
- public void run() {
- deleteFileOrDir(cachedir);
+ private static Map getDevBundleUrls(Properties config) {
+ Map bundles = new Hashtable();
+ Iterator keys = config.keySet().iterator();
+ while (keys.hasNext()) {
+ String key = (String) keys.next();
+ if (key.startsWith(DEV_BUNDLE_PREFIX)) {
+ String bundle = key.substring(DEV_BUNDLE_PREFIX.length());
+ String path = config.getProperty(key);
+ bundles.put(bundle, path);
}
- });
- return cachedir;
+ }
+ return bundles;
}
- public static Felix startSystem(Properties config) throws Exception {
- // Create list to hold custom framework activators.
- List list = new ArrayList();
- // Add activator to process auto-start/install properties.
- list.add(new AutoActivator(config));
- // Add our own activator.
- // list.add(new AutoUiActivator());
+ private static void startBundle(BundleContext bundleContext,
+ String symbolicName) throws BundleException {
+ info("Starting bundle " + symbolicName + "...");
+ Bundle bundle = findBundleBySymbolicName(bundleContext, symbolicName);
+ if (bundle != null)
+ bundle.start();
+ else
+ throw new RuntimeException("Bundle " + symbolicName + " not found");
+ info("Started " + symbolicName);
+ }
- // Now create an instance of the framework.
- Felix felix = new Felix(config, list);
- felix.start();
+ /** WARNING: return the first one found! */
+ private static Bundle findBundleBySymbolicName(BundleContext bundleContext,
+ String symbolicName) {
+ Bundle[] bundles = bundleContext.getBundles();
+ for (int i = 0; i < bundles.length; i++) {
+ Bundle bundle = bundles[i];
+ String bundleSymbolicName = bundle.getSymbolicName();
+ if (bundleSymbolicName == null)
+ throw new RuntimeException("Bundle " + bundle.getBundleId()
+ + " (" + bundle.getLocation()
+ + ") has no symbolic name.");
- return felix;
+ if (bundleSymbolicName.equals(symbolicName)) {
+ return bundle;
+ }
+ }
+ return null;
}
public static void startApp(Properties config) throws Exception {
- String className = config.getProperty("argeo.scl.detached.appclass");
+ String className = config.getProperty("slc.detached.appclass");
String[] uiArgs = readArgumentsFromLine(config.getProperty(
- "argeo.slc.detached.appargs", ""));
-
- // Launch main method using reflection
- Class clss = Class.forName(className);
- Class[] mainArgsClasses = new Class[] { uiArgs.getClass() };
- Object[] mainArgs = { uiArgs };
- Method mainMethod = clss.getMethod("main", mainArgsClasses);
- mainMethod.invoke(null, mainArgs);
- }
+ "slc.detached.appargs", ""));
- // protected static void automateUi(BundleContext bundleContext)
- // throws Exception {
- // // Retrieve service and execute it
- // ServiceReference ref = bundleContext
- // .getServiceReference(DetachedExecutionServer.class.getName());
- // Object service = bundleContext.getService(ref);
- //
- // log.debug("service.class=" + service.getClass());
- // DetachedExecutionServer app = (DetachedExecutionServer) service;
- // DetachedStepRequest request = new DetachedStepRequest();
- // request.setStepRef("jemmyTest");
- // app.executeStep(request);
- // }
+ if (className == null) {
+ info("No slc.detached.appclass property define: does not try to launch an app from the standard classpath.");
+ } else {
+ // Launch main method using reflection
+ Class clss = Class.forName(className);
+ Class[] mainArgsClasses = new Class[] { uiArgs.getClass() };
+ Object[] mainArgs = { uiArgs };
+ Method mainMethod = clss.getMethod("main", mainArgsClasses);
+ mainMethod.invoke(null, mainArgs);
+ }
+ }
/* UTILITIES */
return res;
}
- private static void deleteFileOrDir(File file) {
- if (file.isDirectory()) {
- File[] childs = file.listFiles();
- for (int i = 0; i < childs.length; i++) {
- deleteFileOrDir(childs[i]);
- }
- }
- file.delete();
+ private static void info(Object obj) {
+ System.out.println("[INFO] " + obj);
}
+ private static void bundleInstallWarn(Object obj) {
+ System.err.println("[WARN] " + obj);
+ }
}