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:";
26 public final static String EXCLUDES_SVN_PATTERN
= "**/.svn/**";
28 private Boolean debug
= Boolean
.parseBoolean(System
.getProperty(
29 PROP_SLC_OSGIBOOT_DEBUG
, "false"));
31 private boolean excludeSvn
= true;
33 private final BundleContext bundleContext
;
35 public OsgiBoot(BundleContext bundleContext
) {
36 this.bundleContext
= bundleContext
;
39 public void installUrls(List
<String
> urls
) {
40 Map
<String
, Bundle
> installedBundles
= getInstalledBundles();
41 for (String url
: urls
) {
43 if (installedBundles
.containsKey(url
)) {
44 Bundle bundle
= installedBundles
.get(url
);
47 debug("Bundle " + bundle
.getSymbolicName()
48 + " already installed from " + url
);
50 Bundle bundle
= bundleContext
.installBundle(url
);
52 debug("Installed bundle " + bundle
.getSymbolicName()
55 } catch (BundleException e
) {
56 warn("Could not install bundle from " + url
+ ": "
63 public void startBundles() throws Exception
{
64 String bundlesToStart
= getProperty(PROP_SLC_OSGI_START
);
65 startBundles(bundlesToStart
);
68 public void startBundles(String bundlesToStart
) throws Exception
{
69 if (bundlesToStart
== null)
72 StringTokenizer st
= new StringTokenizer(bundlesToStart
, ",");
73 Map
<String
, Bundle
> bundles
= getBundles();
74 while (st
.hasMoreTokens()) {
75 String name
= st
.nextToken().trim();
76 Bundle bundle
= bundles
.get(name
);
80 } catch (Exception e
) {
81 warn("Bundle " + name
+ " cannot be started: "
85 warn("Bundle " + name
+ " not installed.");
90 /** Key is location */
91 public Map
<String
, Bundle
> getInstalledBundles() {
92 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
94 for (Bundle bundle
: bundleContext
.getBundles()) {
95 installedBundles
.put(bundle
.getLocation(), bundle
);
97 return installedBundles
;
100 /** Key is symbolic name */
101 public Map
<String
, Bundle
> getBundles() {
102 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
103 for (Bundle bundle
: bundleContext
.getBundles())
104 installedBundles
.put(bundle
.getSymbolicName(), bundle
);
105 return installedBundles
;
108 public List
<String
> getLocationsUrls() {
109 String baseUrl
= getProperty(PROP_SLC_OSGI_BASE_URL
, DEFAULT_BASE_URL
);
110 String bundleLocations
= getProperty(PROP_SLC_OSGI_LOCATIONS
);
111 return getLocationsUrls(baseUrl
, bundleLocations
);
114 public List
<String
> getLocationsUrls(String baseUrl
, String bundleLocations
) {
115 List
<String
> urls
= new ArrayList
<String
>();
117 if (bundleLocations
== null)
119 bundleLocations
= SystemPropertyUtils
120 .resolvePlaceholders(bundleLocations
);
122 debug(PROP_SLC_OSGI_LOCATIONS
+ "=" + bundleLocations
);
124 StringTokenizer st
= new StringTokenizer(bundleLocations
,
126 while (st
.hasMoreTokens()) {
127 urls
.add(baseUrl
+ st
.nextToken().trim());
132 public List
<String
> getBundlesUrls() {
133 String baseUrl
= getProperty(PROP_SLC_OSGI_BASE_URL
, DEFAULT_BASE_URL
);
134 String bundlePatterns
= getProperty(PROP_SLC_OSGI_BUNDLES
);
135 return getBundlesUrls(baseUrl
, bundlePatterns
);
138 public List
<String
> getBundlesUrls(String baseUrl
, String bundlePatterns
) {
139 List
<String
> urls
= new ArrayList
<String
>();
141 List
<BundlesSet
> bundlesSets
= new ArrayList
<BundlesSet
>();
142 if (bundlePatterns
== null)
144 bundlePatterns
= SystemPropertyUtils
145 .resolvePlaceholders(bundlePatterns
);
147 debug(PROP_SLC_OSGI_BUNDLES
+ "=" + bundlePatterns
148 + " (excludeSvn=" + excludeSvn
+ ")");
150 StringTokenizer st
= new StringTokenizer(bundlePatterns
, ",");
151 while (st
.hasMoreTokens()) {
152 bundlesSets
.add(new BundlesSet(st
.nextToken()));
155 List
<String
> included
= new ArrayList
<String
>();
156 PathMatcher matcher
= new AntPathMatcher();
157 for (BundlesSet bundlesSet
: bundlesSets
)
158 for (String pattern
: bundlesSet
.getIncludes())
159 match(matcher
, included
, bundlesSet
.getDir(), null, pattern
);
161 List
<String
> excluded
= new ArrayList
<String
>();
162 for (BundlesSet bundlesSet
: bundlesSets
)
163 for (String pattern
: bundlesSet
.getExcludes())
164 match(matcher
, excluded
, bundlesSet
.getDir(), null, pattern
);
166 for (String fullPath
: included
) {
167 if (!excluded
.contains(fullPath
))
168 urls
.add(baseUrl
+ fullPath
);
174 protected void match(PathMatcher matcher
, List
<String
> matched
,
175 String base
, String currentPath
, String pattern
) {
176 if (currentPath
== null) {
178 File baseDir
= new File(base
.replace('/', File
.separatorChar
));
179 File
[] files
= baseDir
.listFiles();
182 warn("Base dir " + baseDir
+ " has no children, exists="
183 + baseDir
.exists() + ", isDirectory="
184 + baseDir
.isDirectory());
188 for (File file
: files
)
189 match(matcher
, matched
, base
, file
.getName(), pattern
);
191 String fullPath
= base
+ '/' + currentPath
;
192 if (matched
.contains(fullPath
))
193 return;// don't try deeper if already matched
195 boolean ok
= matcher
.match(pattern
, currentPath
);
197 debug(currentPath
+ " " + (ok ?
"" : " not ")
198 + " matched with " + pattern
);
200 matched
.add(fullPath
);
203 String newFullPath
= (base
+ '/' + currentPath
).replace('/',
205 File
[] files
= new File(newFullPath
).listFiles();
207 for (File file
: files
)
208 if (file
.isDirectory()) {
209 String newCurrentPath
= currentPath
+ '/'
211 if (matcher
.matchStart(pattern
, newCurrentPath
)) {
212 // recurse only if start matches
213 match(matcher
, matched
, base
, newCurrentPath
,
218 + " does not start match with "
224 warn("Not a directory: " + newFullPath
);
230 protected void info(Object obj
) {
231 System
.out
.println("# INFO " + obj
);
234 protected void debug(Object obj
) {
236 System
.out
.println("# DBUG " + obj
);
239 protected void warn(Object obj
) {
240 System
.out
.println("# WARN " + obj
);
241 // Because of a weird bug under Windows when starting it in a forked VM
242 // if (System.getProperty("os.name").contains("Windows"))
243 // System.out.println("# WARN " + obj);
245 // System.err.println("# WARN " + obj);
248 protected String
getProperty(String name
, String defaultValue
) {
250 if (defaultValue
!= null)
251 value
= System
.getProperty(name
, defaultValue
);
253 value
= System
.getProperty(name
);
255 if (value
== null || value
.equals(""))
261 protected String
getProperty(String name
) {
262 return getProperty(name
, null);
265 public Boolean
getDebug() {
269 public void setDebug(Boolean debug
) {
273 public BundleContext
getBundleContext() {
274 return bundleContext
;
277 /** Whether to exclude Subversion directories (true by default) */
278 public boolean isExcludeSvn() {
282 public void setExcludeSvn(boolean excludeSvn
) {
283 this.excludeSvn
= excludeSvn
;
286 protected class BundlesSet
{
287 private String baseUrl
= "reference:file";// not used yet
288 private final String dir
;
289 private List
<String
> includes
= new ArrayList
<String
>();
290 private List
<String
> excludes
= new ArrayList
<String
>();
292 public BundlesSet(String def
) {
293 StringTokenizer st
= new StringTokenizer(def
, ";");
295 if (!st
.hasMoreTokens())
296 throw new RuntimeException("Base dir not defined.");
298 String dirPath
= st
.nextToken();
299 dir
= new File(dirPath
.replace('/', File
.separatorChar
))
302 debug("Base dir: " + dir
);
303 } catch (IOException e
) {
304 throw new RuntimeException("Cannot convert to absolute path", e
);
307 while (st
.hasMoreTokens()) {
308 String tk
= st
.nextToken();
309 StringTokenizer stEq
= new StringTokenizer(tk
, "=");
310 String type
= stEq
.nextToken();
311 String pattern
= stEq
.nextToken();
312 if ("in".equals(type
) || "include".equals(type
)) {
313 includes
.add(pattern
);
314 } else if ("ex".equals(type
) || "exclude".equals(type
)) {
315 excludes
.add(pattern
);
316 } else if ("baseUrl".equals(type
)) {
319 System
.err
.println("Unkown bundles pattern type " + type
);
323 if (excludeSvn
&& !excludes
.contains(EXCLUDES_SVN_PATTERN
)) {
324 excludes
.add(EXCLUDES_SVN_PATTERN
);
328 public String
getDir() {
332 public List
<String
> getIncludes() {
336 public List
<String
> getExcludes() {
340 public String
getBaseUrl() {