1 package org
.argeo
.slc
.osgiboot
;
4 import java
.io
.IOException
;
5 import java
.util
.ArrayList
;
6 import java
.util
.HashMap
;
9 import java
.util
.StringTokenizer
;
11 import org
.argeo
.slc
.osgiboot
.internal
.springutil
.AntPathMatcher
;
12 import org
.argeo
.slc
.osgiboot
.internal
.springutil
.PathMatcher
;
13 import org
.argeo
.slc
.osgiboot
.internal
.springutil
.SystemPropertyUtils
;
14 import org
.osgi
.framework
.Bundle
;
15 import org
.osgi
.framework
.BundleContext
;
16 import org
.osgi
.framework
.BundleException
;
18 public class OsgiBoot
{
19 public final static String PROP_SLC_OSGI_START
= "slc.osgi.start";
20 public final static String PROP_SLC_OSGI_BUNDLES
= "slc.osgi.bundles";
21 public final static String PROP_SLC_OSGI_LOCATIONS
= "slc.osgi.locations";
22 public final static String PROP_SLC_OSGI_BASE_URL
= "slc.osgi.baseUrl";
23 public final static String PROP_SLC_OSGIBOOT_DEBUG
= "slc.osgiboot.debug";
25 public final static String DEFAULT_BASE_URL
= "reference:file:";
27 private Boolean debug
= Boolean
.parseBoolean(System
.getProperty(
28 PROP_SLC_OSGIBOOT_DEBUG
, "false"));
30 private final BundleContext bundleContext
;
32 public OsgiBoot(BundleContext bundleContext
) {
33 this.bundleContext
= bundleContext
;
36 public void installUrls(List
<String
> urls
) {
37 Map
<String
, Bundle
> installedBundles
= getInstalledBundles();
38 for (String url
: urls
) {
40 if (installedBundles
.containsKey(url
)) {
41 Bundle bundle
= installedBundles
.get(url
);
44 debug("Bundle " + bundle
.getSymbolicName()
45 + " already installed from " + url
);
47 Bundle bundle
= bundleContext
.installBundle(url
);
49 debug("Installed bundle " + bundle
.getSymbolicName()
52 } catch (BundleException e
) {
53 warn("Could not install bundle from " + url
+ ": "
60 public void startBundles() throws Exception
{
61 String bundlesToStart
= getProperty(PROP_SLC_OSGI_START
);
62 startBundles(bundlesToStart
);
65 public void startBundles(String bundlesToStart
) throws Exception
{
66 if (bundlesToStart
== null)
69 StringTokenizer st
= new StringTokenizer(bundlesToStart
, ",");
70 Map
<String
, Bundle
> bundles
= getBundles();
71 while (st
.hasMoreTokens()) {
72 String name
= st
.nextToken().trim();
73 Bundle bundle
= bundles
.get(name
);
77 } catch (Exception e
) {
78 warn("Bundle " + name
+ " cannot be started: "
82 warn("Bundle " + name
+ " not installed.");
87 /** Key is location */
88 public Map
<String
, Bundle
> getInstalledBundles() {
89 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
91 for (Bundle bundle
: bundleContext
.getBundles()) {
92 installedBundles
.put(bundle
.getLocation(), bundle
);
94 return installedBundles
;
97 /** Key is symbolic name */
98 public Map
<String
, Bundle
> getBundles() {
99 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
100 for (Bundle bundle
: bundleContext
.getBundles())
101 installedBundles
.put(bundle
.getSymbolicName(), bundle
);
102 return installedBundles
;
105 public List
<String
> getLocationsUrls() {
106 String baseUrl
= getProperty(PROP_SLC_OSGI_BASE_URL
, DEFAULT_BASE_URL
);
107 String bundleLocations
= getProperty(PROP_SLC_OSGI_LOCATIONS
);
108 return getLocationsUrls(baseUrl
, bundleLocations
);
111 public List
<String
> getLocationsUrls(String baseUrl
, String bundleLocations
) {
112 List
<String
> urls
= new ArrayList
<String
>();
114 if (bundleLocations
== null)
116 bundleLocations
= SystemPropertyUtils
117 .resolvePlaceholders(bundleLocations
);
119 StringTokenizer st
= new StringTokenizer(bundleLocations
,
121 while (st
.hasMoreTokens()) {
122 urls
.add(baseUrl
+ st
.nextToken().trim());
127 public List
<String
> getBundlesUrls() {
128 String baseUrl
= getProperty(PROP_SLC_OSGI_BASE_URL
, DEFAULT_BASE_URL
);
129 String bundlePatterns
= getProperty(PROP_SLC_OSGI_BUNDLES
);
130 return getBundlesUrls(baseUrl
, bundlePatterns
);
133 public List
<String
> getBundlesUrls(String baseUrl
, String bundlePatterns
) {
134 List
<String
> urls
= new ArrayList
<String
>();
136 List
<BundlesSet
> bundlesSets
= new ArrayList
<BundlesSet
>();
137 if (bundlePatterns
== null)
139 // TODO: resolve placeholders
140 info(PROP_SLC_OSGI_BUNDLES
+ "=" + bundlePatterns
);
142 StringTokenizer st
= new StringTokenizer(bundlePatterns
, ",");
143 while (st
.hasMoreTokens()) {
144 bundlesSets
.add(new BundlesSet(st
.nextToken()));
147 List
<String
> included
= new ArrayList
<String
>();
148 PathMatcher matcher
= new AntPathMatcher();
149 for (BundlesSet bundlesSet
: bundlesSets
)
150 for (String pattern
: bundlesSet
.getIncludes())
151 match(matcher
, included
, bundlesSet
.getDir(), null, pattern
);
153 List
<String
> excluded
= new ArrayList
<String
>();
154 for (BundlesSet bundlesSet
: bundlesSets
)
155 for (String pattern
: bundlesSet
.getExcludes())
156 match(matcher
, excluded
, bundlesSet
.getDir(), null, pattern
);
158 for (String fullPath
: included
) {
159 if (!excluded
.contains(fullPath
))
160 urls
.add(baseUrl
+ fullPath
);
166 protected void match(PathMatcher matcher
, List
<String
> matched
,
167 String base
, String currentPath
, String pattern
) {
168 if (currentPath
== null) {
170 File baseDir
= new File(base
.replace('/', File
.separatorChar
));
171 File
[] files
= baseDir
.listFiles();
174 warn("Base dir " + baseDir
+ " has no children, exists="
175 + baseDir
.exists() + ", isDirectory="
176 + baseDir
.isDirectory());
180 for (File file
: files
)
181 match(matcher
, matched
, base
, file
.getName(), pattern
);
183 String fullPath
= base
+ '/' + currentPath
;
184 if (matched
.contains(fullPath
))
185 return;// don't try deeper if already matched
187 boolean ok
= matcher
.match(pattern
, currentPath
);
189 debug(currentPath
+ " " + (ok ?
"" : " not ")
190 + " matched with " + pattern
);
192 matched
.add(fullPath
);
195 String newFullPath
= (base
+ '/' + currentPath
).replace('/',
197 File
[] files
= new File(newFullPath
).listFiles();
199 for (File file
: files
)
200 if (file
.isDirectory()) {
201 String newCurrentPath
= currentPath
+ '/'
203 if (matcher
.matchStart(pattern
, newCurrentPath
)) {
204 // recurse only if start matches
205 match(matcher
, matched
, base
, newCurrentPath
,
210 + " does not start match with "
216 warn("Not a directory: " + newFullPath
);
222 protected void info(Object obj
) {
223 System
.out
.println("# INFO " + obj
);
226 protected void debug(Object obj
) {
228 System
.out
.println("# DBUG " + obj
);
231 protected void warn(Object obj
) {
232 System
.out
.println("# WARN " + obj
);
233 // Because of a weird bug under Windows when starting it in a forked VM
234 // if (System.getProperty("os.name").contains("Windows"))
235 // System.out.println("# WARN " + obj);
237 // System.err.println("# WARN " + obj);
240 protected String
getProperty(String name
, String defaultValue
) {
242 if (defaultValue
!= null)
243 value
= System
.getProperty(name
, defaultValue
);
245 value
= System
.getProperty(name
);
247 if (value
== null || value
.equals(""))
253 protected String
getProperty(String name
) {
254 return getProperty(name
, null);
257 public Boolean
getDebug() {
261 public void setDebug(Boolean debug
) {
265 public BundleContext
getBundleContext() {
266 return bundleContext
;
269 private class BundlesSet
{
270 private String baseUrl
= "reference:file";// not used yet
271 private final String dir
;
272 private List
<String
> includes
= new ArrayList
<String
>();
273 private List
<String
> excludes
= new ArrayList
<String
>();
275 public BundlesSet(String def
) {
276 StringTokenizer st
= new StringTokenizer(def
, ";");
278 if (!st
.hasMoreTokens())
279 throw new RuntimeException("Base dir not defined.");
281 String dirPath
= st
.nextToken();
282 dir
= new File(dirPath
.replace('/', File
.separatorChar
))
285 debug("Base dir: " + dir
);
286 } catch (IOException e
) {
287 throw new RuntimeException("Cannot convert to absolute path", e
);
290 while (st
.hasMoreTokens()) {
291 String tk
= st
.nextToken();
292 StringTokenizer stEq
= new StringTokenizer(tk
, "=");
293 String type
= stEq
.nextToken();
294 String pattern
= stEq
.nextToken();
295 if ("in".equals(type
) || "include".equals(type
)) {
296 includes
.add(pattern
);
297 } else if ("ex".equals(type
) || "exclude".equals(type
)) {
298 excludes
.add(pattern
);
299 } else if ("baseUrl".equals(type
)) {
302 System
.err
.println("Unkown bundles pattern type " + type
);
307 public String
getDir() {
311 public List
<String
> getIncludes() {
315 public List
<String
> getExcludes() {
319 public String
getBaseUrl() {