X-Git-Url: http://git.argeo.org/?a=blobdiff_plain;f=org.argeo.osgi.boot%2Fsrc%2Forg%2Fargeo%2Fosgi%2Fboot%2FOsgiBuilder.java;h=28a2604a42c6c3fc6766b81ff5a94370b07d4ae8;hb=1091271b89f2d12e9898e01f6639c48831b1bc4b;hp=7a8fd96bf18ee50de3474e9e5e92aacb2aface9b;hpb=5dc0e30ff215c1604b1b0e7bf8c8699f6cd1257f;p=lgpl%2Fargeo-commons.git diff --git a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java index 7a8fd96bf..28a2604a4 100644 --- a/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java +++ b/org.argeo.osgi.boot/src/org/argeo/osgi/boot/OsgiBuilder.java @@ -1,5 +1,7 @@ package org.argeo.osgi.boot; +import java.lang.reflect.Method; +import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -11,22 +13,36 @@ import java.util.Set; import java.util.TreeMap; import org.eclipse.osgi.launch.EquinoxFactory; +import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; +import org.osgi.framework.BundleEvent; import org.osgi.framework.BundleException; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.InvalidSyntaxException; +import org.osgi.framework.ServiceReference; import org.osgi.framework.launch.Framework; import org.osgi.framework.launch.FrameworkFactory; +import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.ServiceTracker; +/** OSGi builder, focusing on ease of use for scripting. */ public class OsgiBuilder { + private final static String PROP_HTTP_PORT = "org.osgi.service.http.port"; + private final static String PROP_HTTPS_PORT = "org.osgi.service.https.port"; + private final static String PROP_OSGI_CLEAN = "osgi.clean"; + private Map startLevels = new TreeMap<>(); private List distributionBundles = new ArrayList<>(); private Map configuration = new HashMap(); private Framework framework; + private String baseUrl = null; public OsgiBuilder() { // configuration.put("osgi.clean", "true"); configuration.put(OsgiBoot.CONFIGURATION_AREA_PROP, System.getProperty(OsgiBoot.CONFIGURATION_AREA_PROP)); configuration.put(OsgiBoot.INSTANCE_AREA_PROP, System.getProperty(OsgiBoot.INSTANCE_AREA_PROP)); + configuration.put(PROP_OSGI_CLEAN, System.getProperty(PROP_OSGI_CLEAN)); } public Framework launch() { @@ -49,7 +65,7 @@ public class OsgiBuilder { OsgiBoot osgiBoot = new OsgiBoot(framework.getBundleContext()); // install bundles for (String distributionBundle : distributionBundles) { - List bundleUrls = osgiBoot.getDistributionUrls(distributionBundle, null); + List bundleUrls = osgiBoot.getDistributionUrls(distributionBundle, baseUrl); osgiBoot.installUrls(bundleUrls); } @@ -88,11 +104,179 @@ public class OsgiBuilder { return this; } + public OsgiBuilder waitForServlet(String base) { + service("(&(objectClass=javax.servlet.Servlet)(osgi.http.whiteboard.servlet.pattern=" + base + "))"); + return this; + } + + public OsgiBuilder waitForBundle(String bundles) { + List lst = new ArrayList<>(); + Collections.addAll(lst, bundles.split(",")); + BundleTracker bt = new BundleTracker(getBc(), Bundle.ACTIVE, null) { + + @Override + public Object addingBundle(Bundle bundle, BundleEvent event) { + if (lst.contains(bundle.getSymbolicName())) { + return bundle.getSymbolicName(); + } else { + return null; + } + } + }; + bt.open(); + while (bt.getTrackingCount() != lst.size()) { + try { + Thread.sleep(500l); + } catch (InterruptedException e) { + break; + } + } + bt.close(); + return this; + + } + + public OsgiBuilder main(String clssUri, String[] args) { + + // waitForBundle(bundleSymbolicName); + try { + URI uri = new URI(clssUri); + if (!"bundleclass".equals(uri.getScheme())) + throw new IllegalArgumentException("Unsupported scheme for " + clssUri); + String bundleSymbolicName = uri.getHost(); + String clss = uri.getPath().substring(1); + Bundle bundle = null; + for (Bundle b : getBc().getBundles()) { + if (bundleSymbolicName.equals(b.getSymbolicName())) { + bundle = b; + break; + } + } + if (bundle == null) + throw new OsgiBootException("Bundle " + bundleSymbolicName + " not found"); + Class c = bundle.loadClass(clss); + Object[] mainArgs = { args }; + Method mainMethod = c.getMethod("main", String[].class); + mainMethod.invoke(null, mainArgs); + } catch (Throwable e) { + throw new OsgiBootException("Cannot execute " + clssUri, e); + } + return this; + } + + public Object service(String service) { + return service(service, 0); + } + + public Object service(String service, long timeout) { + ServiceTracker st; + if (service.contains("(")) { + try { + st = new ServiceTracker<>(getBc(), FrameworkUtil.createFilter(service), null); + } catch (InvalidSyntaxException e) { + throw new IllegalArgumentException("Badly formatted filter", e); + } + } else { + st = new ServiceTracker<>(getBc(), service, null); + } + st.open(); + try { + return st.waitForService(timeout); + } catch (InterruptedException e) { + OsgiBootUtils.error("Interrupted", e); + return null; + } finally { + st.close(); + } + + } + + public void shutdown() { + checkLaunched(); + try { + framework.stop(); + } catch (BundleException e) { + e.printStackTrace(); + System.exit(1); + } + try { + framework.waitForStop(10 * 60 * 1000); + } catch (InterruptedException e) { + e.printStackTrace(); + System.exit(1); + } + System.exit(0); + } + + public void setHttpPort(Integer port) { + checkNotLaunched(); + configuration.put(PROP_HTTP_PORT, Integer.toString(port)); + } + + public void setHttpsPort(Integer port) { + checkNotLaunched(); + configuration.put(PROP_HTTPS_PORT, Integer.toString(port)); + } + + public void setClean(boolean clean) { + checkNotLaunched(); + configuration.put(PROP_OSGI_CLEAN, Boolean.toString(clean)); + } + + public Integer getHttpPort() { + if (!isLaunched()) { + if (configuration.containsKey(PROP_HTTP_PORT)) + return Integer.parseInt(configuration.get(PROP_HTTP_PORT)); + else + return -1; + } else { + // TODO wait for service? + ServiceReference sr = getBc().getServiceReference("org.osgi.service.http.HttpService"); + if (sr == null) + return -1; + Object port = sr.getProperty("http.port"); + if (port == null) + return -1; + return Integer.parseInt(port.toString()); + } + } + + public Integer getHttpsPort() { + if (!isLaunched()) { + if (configuration.containsKey(PROP_HTTPS_PORT)) + return Integer.parseInt(configuration.get(PROP_HTTPS_PORT)); + else + return -1; + } else { + // TODO wait for service? + ServiceReference sr = getBc().getServiceReference("org.osgi.service.http.HttpService"); + if (sr == null) + return -1; + Object port = sr.getProperty("https.port"); + if (port == null) + return -1; + return Integer.parseInt(port.toString()); + } + } + + public Object spring(String bundle) { + return service("(&(Bundle-SymbolicName=" + bundle + ")" + + "(objectClass=org.springframework.context.ApplicationContext))"); + } + + // + // BEAN + // + public BundleContext getBc() { checkLaunched(); return framework.getBundleContext(); } + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + // // UTILITIES //