X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.slc.detached.launcher%2Fsrc%2Fmain%2Fjava%2Forg%2Fargeo%2Fslc%2Fdetached%2Flauncher%2FMain.java;h=d7da1e673910b880aca9da684317a3d50111f180;hb=47ac61a1d8b3d6db956ac5007a05238b2f506b2e;hp=fe69e30c56af83cd95c2b7dceb7ff0e62b99fd1b;hpb=bd289ae8e8a75c6ca1ecbe4fc86960607b6846de;p=gpl%2Fargeo-slc.git diff --git a/org.argeo.slc.detached.launcher/src/main/java/org/argeo/slc/detached/launcher/Main.java b/org.argeo.slc.detached.launcher/src/main/java/org/argeo/slc/detached/launcher/Main.java index fe69e30c5..d7da1e673 100644 --- a/org.argeo.slc.detached.launcher/src/main/java/org/argeo/slc/detached/launcher/Main.java +++ b/org.argeo.slc.detached.launcher/src/main/java/org/argeo/slc/detached/launcher/Main.java @@ -2,49 +2,48 @@ package org.argeo.slc.detached.launcher; 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.io.IOUtils; -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); + public final static String PROP_SLC_HOME = "slc.home"; + public final static String PROP_SLC_OSGI_START = "slc.osgi.start"; + public final static String PROP_SLC_OSGI_SCAN_CLASSPATH = "slc.osgi.scanClasspath"; + public final static String PROP_SLC_OSGI_EQUINOX_ARGS = "slc.osgi.equinox.args"; + + 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); @@ -54,24 +53,15 @@ public class Main { protected static Properties prepareConfig(String propertyFilePath) throws Exception { // Format slc.home - String slcHome = System.getProperty("slc.home"); + String slcHome = System.getProperty(PROP_SLC_HOME); if (slcHome != null) { slcHome = new File(slcHome).getCanonicalPath(); - System.setProperty("slc.home", slcHome); + System.setProperty(PROP_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 { - IOUtils.closeQuietly(in); - } - try { File file = new File(propertyFilePath); if (file.exists()) { @@ -79,50 +69,154 @@ public class Main { config.load(in); } } finally { - IOUtils.closeQuietly(in); + if (in != null) + in.close(); } // System properties have priority. config.putAll(System.getProperties()); + return config; + } + + public static void startEquinox(Properties config) throws Exception { + info("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 equinoxArgsLineDefault = "-console -noExit -clean -debug -configuration " + + equinoxConfigurationPath; + String equinoxArgsLine = config.getProperty(PROP_SLC_OSGI_EQUINOX_ARGS, + equinoxArgsLineDefault); + // String[] equinoxArgs = { "-console", "-noExit", "-clean", "-debug", + // "-configuration", equinoxConfigurationPath }; + String[] equinoxArgs = equinoxArgsLine.split(" "); + + BundleContext context = EclipseStarter.startup(equinoxArgs, null); + + List installBundleNames = new ArrayList(); - // 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 class path (dev environment, maven) + if (config.getProperty(PROP_SLC_OSGI_SCAN_CLASSPATH, "false").equals( + "true")) { + 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(); + Bundle bundle = context.installBundle(url); + installBundleNames.add(bundle.getSymbolicName()); + info("Installed from classpath " + url); + } catch (Exception e) { + bundleInstallWarn(e.getMessage()); + } + } } - return config; + // 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); + Bundle bundle = context.installBundle(url); + installBundleNames.add(bundle.getSymbolicName()); + info("Installed as dev bundle " + url); + } catch (Exception e) { + bundleInstallWarn(e.getMessage()); + } + } + + // Load from distribution + String slcHome = config.getProperty(PROP_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(); + Bundle bundle = context.installBundle(url); + installBundleNames.add(bundle.getSymbolicName()); + info("INFO: Installed from SLC home " + url); + } catch (Exception e) { + bundleInstallWarn(e.getMessage()); + } + + } + } + + // Start bundles + String bundleStart = config.getProperty(PROP_SLC_OSGI_START, + "org.springframework.osgi.extender,org.argeo.slc.detached"); + + if (bundleStart.trim().equals("*")) { + for (int i = 0; i < installBundleNames.size(); i++) { + String bundleSymbolicName = installBundleNames.get(i) + .toString(); + try { + startBundle(context, bundleSymbolicName); + } catch (Exception e) { + bundleInstallWarn(e.getMessage()); + } + } + } else { + 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 { @@ -130,32 +224,18 @@ public class Main { String[] uiArgs = readArgumentsFromLine(config.getProperty( "slc.detached.appargs", "")); - if (className == null) - throw new Exception( - "A main class has to be defined with teh system property slc.detached.appclass"); - - // 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); + 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); + } } - // 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); - // } - /* UTILITIES */ /** @@ -204,14 +284,11 @@ public class Main { 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); + } }