1 package org
.argeo
.osgi
.boot
;
3 import java
.util
.ArrayList
;
4 import java
.util
.Collections
;
5 import java
.util
.HashMap
;
6 import java
.util
.HashSet
;
9 import java
.util
.Properties
;
11 import java
.util
.TreeMap
;
13 import org
.eclipse
.osgi
.launch
.EquinoxFactory
;
14 import org
.osgi
.framework
.Bundle
;
15 import org
.osgi
.framework
.BundleContext
;
16 import org
.osgi
.framework
.BundleEvent
;
17 import org
.osgi
.framework
.BundleException
;
18 import org
.osgi
.framework
.FrameworkUtil
;
19 import org
.osgi
.framework
.InvalidSyntaxException
;
20 import org
.osgi
.framework
.ServiceReference
;
21 import org
.osgi
.framework
.launch
.Framework
;
22 import org
.osgi
.framework
.launch
.FrameworkFactory
;
23 import org
.osgi
.util
.tracker
.BundleTracker
;
24 import org
.osgi
.util
.tracker
.ServiceTracker
;
26 /** OSGi builder, focusing on ease of use for scripting. */
27 public class OsgiBuilder
{
28 private Map
<Integer
, StartLevel
> startLevels
= new TreeMap
<>();
29 private List
<String
> distributionBundles
= new ArrayList
<>();
31 private Map
<String
, String
> configuration
= new HashMap
<String
, String
>();
32 private Framework framework
;
33 private String baseUrl
= null;
35 public OsgiBuilder() {
36 // configuration.put("osgi.clean", "true");
37 configuration
.put(OsgiBoot
.CONFIGURATION_AREA_PROP
, System
.getProperty(OsgiBoot
.CONFIGURATION_AREA_PROP
));
38 configuration
.put(OsgiBoot
.INSTANCE_AREA_PROP
, System
.getProperty(OsgiBoot
.INSTANCE_AREA_PROP
));
41 public Framework
launch() {
43 FrameworkFactory frameworkFactory
= new EquinoxFactory();
44 framework
= frameworkFactory
.newFramework(configuration
);
47 } catch (BundleException e
) {
48 throw new OsgiBootException("Cannot start OSGi framework", e
);
51 BundleContext bc
= framework
.getBundleContext();
52 String osgiData
= bc
.getProperty(OsgiBoot
.INSTANCE_AREA_PROP
);
53 // String osgiConf = bc.getProperty(OsgiBoot.CONFIGURATION_AREA_PROP);
54 String osgiConf
= framework
.getDataFile("").getAbsolutePath();
55 if (OsgiBootUtils
.isDebug())
56 OsgiBootUtils
.debug("OSGi starting - data: " + osgiData
+ " conf: " + osgiConf
);
58 OsgiBoot osgiBoot
= new OsgiBoot(framework
.getBundleContext());
60 for (String distributionBundle
: distributionBundles
) {
61 List
<String
> bundleUrls
= osgiBoot
.getDistributionUrls(distributionBundle
, baseUrl
);
62 osgiBoot
.installUrls(bundleUrls
);
66 osgiBoot
.startBundles(startLevelsToProperties());
68 // if (OsgiBootUtils.isDebug())
69 // for (Bundle bundle : bc.getBundles()) {
70 // OsgiBootUtils.debug(bundle.getLocation());
75 public OsgiBuilder
conf(String key
, String value
) {
77 configuration
.put(key
, value
);
81 public OsgiBuilder
install(String uri
) {
82 // TODO dynamic install
84 if (!distributionBundles
.contains(uri
))
85 distributionBundles
.add(uri
);
89 public OsgiBuilder
start(int startLevel
, String bundle
) {
93 if (!startLevels
.containsKey(startLevel
))
94 startLevels
.put(startLevel
, new StartLevel());
95 sl
= startLevels
.get(startLevel
);
100 public OsgiBuilder
waitForBundle(String bundles
) {
101 List
<String
> lst
= new ArrayList
<>();
102 Collections
.addAll(lst
, bundles
.split(","));
103 BundleTracker
<Object
> bt
= new BundleTracker
<Object
>(getBc(), Bundle
.ACTIVE
, null) {
106 public Object
addingBundle(Bundle bundle
, BundleEvent event
) {
107 if (lst
.contains(bundle
.getSymbolicName())) {
108 return bundle
.getSymbolicName();
115 while (bt
.getTrackingCount() != lst
.size()) {
118 } catch (InterruptedException e
) {
127 public Object
service(String service
) {
128 return service(service
, 0);
131 public Object
service(String service
, long timeout
) {
132 ServiceTracker
<Object
, Object
> st
;
133 if (service
.contains("(")) {
135 st
= new ServiceTracker
<>(getBc(), FrameworkUtil
.createFilter(service
), null);
136 } catch (InvalidSyntaxException e
) {
137 throw new IllegalArgumentException("Badly formatted filter", e
);
140 st
= new ServiceTracker
<>(getBc(), service
, null);
144 return st
.waitForService(timeout
);
145 } catch (InterruptedException e
) {
146 OsgiBootUtils
.error("Interrupted", e
);
154 public void shutdown() {
158 } catch (BundleException e
) {
163 framework
.waitForStop(10 * 60 * 1000);
164 } catch (InterruptedException e
) {
171 public Integer
getHttpPort() {
172 ServiceReference
<?
> sr
= getBc().getServiceReference("org.osgi.service.http.HttpService");
175 Object port
= sr
.getProperty("http.port");
178 return Integer
.parseInt(port
.toString());
181 public Integer
getHttpsPort() {
182 ServiceReference
<?
> sr
= getBc().getServiceReference("org.osgi.service.http.HttpService");
185 Object port
= sr
.getProperty("https.port");
188 return Integer
.parseInt(port
.toString());
191 public Object
spring(String bundle
) {
192 return service("(&(Bundle-SymbolicName=" + bundle
+ ")"
193 + "(objectClass=org.springframework.context.ApplicationContext))");
200 public BundleContext
getBc() {
202 return framework
.getBundleContext();
205 public void setBaseUrl(String baseUrl
) {
206 this.baseUrl
= baseUrl
;
212 private Properties
startLevelsToProperties() {
213 Properties properties
= new Properties();
214 for (Integer startLevel
: startLevels
.keySet()) {
215 String property
= OsgiBoot
.PROP_ARGEO_OSGI_START
+ "." + startLevel
;
216 StringBuilder value
= new StringBuilder();
217 for (String bundle
: startLevels
.get(startLevel
).getBundles()) {
218 value
.append(bundle
);
221 // TODO remove trailing comma
222 properties
.put(property
, value
.toString());
227 private void checkLaunched() {
229 throw new OsgiBootException("OSGi runtime is not launched");
232 private void checkNotLaunched() {
234 throw new OsgiBootException("OSGi runtime already launched");
237 private boolean isLaunched() {
238 return framework
!= null;
241 private static class StartLevel
{
242 private Set
<String
> bundles
= new HashSet
<>();
244 public void add(String bundle
) {
245 String
[] b
= bundle
.split(",");
246 Collections
.addAll(bundles
, b
);
249 public Set
<String
> getBundles() {