1 package org
.argeo
.slc
.osgiboot
;
3 import java
.io
.BufferedReader
;
5 import java
.io
.FileReader
;
6 import java
.io
.IOException
;
7 import java
.util
.ArrayList
;
8 import java
.util
.HashMap
;
11 import java
.util
.StringTokenizer
;
13 import org
.argeo
.slc
.osgiboot
.internal
.springutil
.AntPathMatcher
;
14 import org
.argeo
.slc
.osgiboot
.internal
.springutil
.PathMatcher
;
15 import org
.argeo
.slc
.osgiboot
.internal
.springutil
.SystemPropertyUtils
;
16 import org
.osgi
.framework
.Bundle
;
17 import org
.osgi
.framework
.BundleActivator
;
18 import org
.osgi
.framework
.BundleContext
;
19 import org
.osgi
.framework
.BundleException
;
21 public class Activator
implements BundleActivator
{
22 public final static String PROP_SLC_OSGI_START
= "slc.osgi.start";
23 public final static String PROP_SLC_OSGI_BUNDLES
= "slc.osgi.bundles";
24 public final static String PROP_SLC_OSGI_DEV_BASES
= "slc.osgi.devBases";
25 public final static String PROP_SLC_OSGI_DEV_PATTERNS
= "slc.osgi.devPatterns";
26 public final static String PROP_SLC_OSGI_LOCATIONS
= "slc.osgi.locations";
27 public final static String PROP_SLC_OSGI_BASE_URL
= "slc.osgi.baseUrl";
28 public final static String PROP_SLC_MAVEN_DEPENDENCY_FILE
= "slc.maven.dependencyFile";
29 public final static String PROP_SLC_OSGIBOOT_DEBUG
= "slc.osgiboot.debug";
31 private static Boolean debug
= Boolean
.parseBoolean(System
.getProperty(
32 PROP_SLC_OSGIBOOT_DEBUG
, "false"));
34 public void start(BundleContext bundleContext
) throws Exception
{
36 info("SLC OSGi bootstrap starting...");
37 // installUrls(bundleContext, getDevLocationsUrls());
39 installUrls(bundleContext
, getBundlesUrls());
41 installUrls(bundleContext
, getLocationsUrls());
43 installUrls(bundleContext
, getMavenUrls());
45 startBundles(bundleContext
);
47 info("SLC OSGi bootstrap completed");
48 } catch (Exception e
) {
54 public void stop(BundleContext context
) throws Exception
{
57 protected static void installUrls(BundleContext bundleContext
,
59 Map
<String
, Bundle
> installedBundles
= getInstalledBundles(bundleContext
);
60 for (String url
: urls
) {
62 if (installedBundles
.containsKey(url
)) {
63 Bundle bundle
= installedBundles
.get(url
);
66 debug("Bundle " + bundle
.getSymbolicName()
67 + " already installed from " + url
);
69 Bundle bundle
= bundleContext
.installBundle(url
);
71 debug("Installed bundle " + bundle
.getSymbolicName()
74 } catch (BundleException e
) {
75 warn("Could not install bundle from " + url
+ ": "
82 protected List
<String
> getLocationsUrls() {
83 List
<String
> urlsProvided
= new ArrayList
<String
>();
85 String baseUrl
= getProperty(PROP_SLC_OSGI_BASE_URL
, "reference:file:");
86 String bundlesList
= getProperty(PROP_SLC_OSGI_LOCATIONS
);
87 if (bundlesList
== null)
89 bundlesList
= SystemPropertyUtils
.resolvePlaceholders(bundlesList
);
91 StringTokenizer st
= new StringTokenizer(bundlesList
,
93 while (st
.hasMoreTokens()) {
94 urlsProvided
.add(baseUrl
+ st
.nextToken().trim());
99 protected List
<String
> getDevLocationsUrls() {
100 List
<String
> urls
= new ArrayList
<String
>();
102 String devBase
= getProperty(PROP_SLC_OSGI_DEV_BASES
);
103 String devPatterns
= getProperty(PROP_SLC_OSGI_DEV_PATTERNS
);
106 devBase
= SystemPropertyUtils
.resolvePlaceholders(devBase
);
107 devBase
= devBase
.replace(File
.separatorChar
, '/');
108 devPatterns
= SystemPropertyUtils
.resolvePlaceholders(devPatterns
);
110 List
<String
> bases
= new ArrayList
<String
>();
111 StringTokenizer st
= new StringTokenizer(devBase
, ",");
112 while (st
.hasMoreTokens()) {
113 String token
= st
.nextToken().trim();
114 char lastChar
= token
.charAt(token
.length() - 1);
120 List
<String
> patterns
= new ArrayList
<String
>();
121 st
= new StringTokenizer(devPatterns
, ";");
122 while (st
.hasMoreTokens()) {
123 patterns
.add(st
.nextToken().trim());
126 List
<String
> matched
= new ArrayList
<String
>();
127 PathMatcher matcher
= new AntPathMatcher();
128 for (String base
: bases
)
129 for (String pattern
: patterns
)
130 match(matcher
, matched
, base
, null, pattern
);
132 for (String fullPath
: matched
)
133 urls
.add("reference:file:" + fullPath
);
138 protected List
<String
> getBundlesUrls() {
139 List
<String
> urls
= new ArrayList
<String
>();
141 List
<BundlesSet
> bundlesSets
= new ArrayList
<BundlesSet
>();
142 String bundles
= getProperty(PROP_SLC_OSGI_BUNDLES
);
145 info(PROP_SLC_OSGI_BUNDLES
+ "=" + bundles
);
147 StringTokenizer st
= new StringTokenizer(bundles
, ",");
148 while (st
.hasMoreTokens()) {
149 bundlesSets
.add(new BundlesSet(st
.nextToken()));
152 List
<String
> included
= new ArrayList
<String
>();
153 PathMatcher matcher
= new AntPathMatcher();
154 for (BundlesSet bundlesSet
: bundlesSets
)
155 for (String pattern
: bundlesSet
.getIncludes())
156 match(matcher
, included
, bundlesSet
.getDir(), null, pattern
);
158 List
<String
> excluded
= new ArrayList
<String
>();
159 for (BundlesSet bundlesSet
: bundlesSets
)
160 for (String pattern
: bundlesSet
.getExcludes())
161 match(matcher
, excluded
, bundlesSet
.getDir(), null, pattern
);
163 for (String fullPath
: included
) {
164 if (!excluded
.contains(fullPath
))
165 urls
.add("reference:file:" + fullPath
);
171 private class BundlesSet
{
172 private String baseUrl
= "reference:file";
173 private final String dir
;
174 private List
<String
> includes
= new ArrayList
<String
>();
175 private List
<String
> excludes
= new ArrayList
<String
>();
177 public BundlesSet(String def
) {
178 StringTokenizer st
= new StringTokenizer(def
, ";");
180 if (!st
.hasMoreTokens())
181 throw new RuntimeException("Base dir not defined.");
183 String dirPath
= st
.nextToken();
184 dir
= new File(dirPath
.replace('/', File
.separatorChar
))
187 debug("Base dir: " + dir
);
188 } catch (IOException e
) {
189 throw new RuntimeException("Cannot convert to absolute path", e
);
192 while (st
.hasMoreTokens()) {
193 String tk
= st
.nextToken();
194 StringTokenizer stEq
= new StringTokenizer(tk
, "=");
195 String type
= stEq
.nextToken();
196 String pattern
= stEq
.nextToken();
197 if ("in".equals(type
) || "include".equals(type
)) {
198 includes
.add(pattern
);
199 } else if ("ex".equals(type
) || "exclude".equals(type
)) {
200 excludes
.add(pattern
);
201 } else if ("baseUrl".equals(type
)) {
204 System
.err
.println("Unkown bundles pattern type " + type
);
209 public String
getDir() {
213 public List
<String
> getIncludes() {
217 public List
<String
> getExcludes() {
221 public String
getBaseUrl() {
227 protected void match(PathMatcher matcher
, List
<String
> matched
,
228 String base
, String currentPath
, String pattern
) {
229 if (currentPath
== null) {
231 File baseDir
= new File(base
.replace('/', File
.separatorChar
));
232 File
[] files
= baseDir
.listFiles();
235 warn("Base dir " + baseDir
+ " has no children, exists="
236 + baseDir
.exists() + ", isDirectory="
237 + baseDir
.isDirectory());
241 for (File file
: files
)
242 match(matcher
, matched
, base
, file
.getName(), pattern
);
244 String fullPath
= base
+ '/' + currentPath
;
245 if (matched
.contains(fullPath
))
246 return;// don't try deeper if already matched
248 boolean ok
= matcher
.match(pattern
, currentPath
);
250 debug(currentPath
+ " " + (ok ?
"" : " not ")
251 + " matched with " + pattern
);
253 matched
.add(fullPath
);
256 String newFullPath
= (base
+ '/' + currentPath
).replace('/',
258 File
[] files
= new File(newFullPath
).listFiles();
260 for (File file
: files
)
261 if (file
.isDirectory()) {
262 String newCurrentPath
= currentPath
+ '/'
264 if (matcher
.matchStart(pattern
, newCurrentPath
)) {
265 // recurse only if start matches
266 match(matcher
, matched
, base
, newCurrentPath
,
271 + " does not start match with "
277 warn("Not a directory: " + newFullPath
);
283 protected List
<String
> getMavenUrls() throws Exception
{
284 String baseUrl
= "reference:file:" + System
.getProperty("user.home")
285 + "/.m2/repository/";
286 String config
= getProperty(PROP_SLC_MAVEN_DEPENDENCY_FILE
);
288 return new ArrayList
<String
>();
290 List
<MavenFile
> mavenFiles
= new ArrayList
<MavenFile
>();
291 BufferedReader in
= new BufferedReader(new FileReader(config
));
293 while ((line
= in
.readLine()) != null) {
298 .startsWith("The following files have been resolved:"))
301 mavenFiles
.add(convert(line
));
302 } catch (Exception e
) {
303 warn("Could not load line " + line
);
307 return asUrls(baseUrl
, mavenFiles
);
310 protected void startBundles(BundleContext bundleContext
) throws Exception
{
311 String bundlesToStart
= getProperty(PROP_SLC_OSGI_START
);
312 if (bundlesToStart
== null)
315 StringTokenizer st
= new StringTokenizer(bundlesToStart
, ",");
316 Map
<String
, Bundle
> bundles
= getBundles(bundleContext
);
317 while (st
.hasMoreTokens()) {
318 String name
= st
.nextToken().trim();
319 Bundle bundle
= bundles
.get(name
);
323 } catch (Exception e
) {
324 warn("Bundle " + name
+ " cannot be started: "
328 warn("Bundle " + name
+ " not installed.");
333 /** Key is location */
334 protected static Map
<String
, Bundle
> getInstalledBundles(
335 BundleContext bundleContext
) {
336 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
338 for (Bundle bundle
: bundleContext
.getBundles()) {
339 installedBundles
.put(bundle
.getLocation(), bundle
);
341 return installedBundles
;
344 /** Key is symbolic name */
345 protected static Map
<String
, Bundle
> getBundles(BundleContext bundleContext
) {
346 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
347 for (Bundle bundle
: bundleContext
.getBundles())
348 installedBundles
.put(bundle
.getSymbolicName(), bundle
);
349 return installedBundles
;
352 protected static List
<String
> asUrls(String baseUrl
,
353 List
<MavenFile
> mavenFiles
) {
354 List
<String
> urls
= new ArrayList
<String
>();
355 for (MavenFile mf
: mavenFiles
)
356 urls
.add(convertToUrl(baseUrl
, mf
));
360 protected static String
convertToUrl(String baseUrl
, MavenFile mf
) {
361 return baseUrl
+ mf
.getGroupId().replace('.', '/') + '/'
362 + mf
.getArtifactId() + '/' + mf
.getVersion() + '/'
363 + mf
.getArtifactId() + '-' + mf
.getVersion() + '.'
367 protected static MavenFile
convert(String str
) {
368 StringTokenizer st
= new StringTokenizer(str
, ":");
369 MavenFile component
= new MavenFile();
370 component
.setGroupId(st
.nextToken());
371 component
.setArtifactId(st
.nextToken());
372 component
.setType(st
.nextToken());
373 component
.setVersion(st
.nextToken());
374 component
.setScope(st
.nextToken());
378 protected static String
getProperty(String name
, String defaultValue
) {
380 if (defaultValue
!= null)
381 value
= System
.getProperty(name
, defaultValue
);
383 value
= System
.getProperty(name
);
385 if (value
== null || value
.equals(""))
391 protected static String
getProperty(String name
) {
392 return getProperty(name
, null);
395 private static void info(Object obj
) {
396 System
.out
.println("# INFO " + obj
);
399 private static void debug(Object obj
) {
401 System
.out
.println("# DBUG " + obj
);
404 private static void warn(Object obj
) {
405 System
.out
.println("# WARN " + obj
);
406 // if (System.getProperty("os.name").contains("Windows"))
407 // System.out.println("# WARN " + obj);
409 // System.err.println("# WARN " + obj);
412 static class MavenFile
{
413 private String groupId
;
414 private String artifactId
;
415 private String version
;
417 private String classifier
;
418 private String scope
;
420 public String
getScope() {
424 public void setScope(String scope
) {
428 private String distributionId
;
430 public String
getDistributionId() {
431 return distributionId
;
434 public void setDistributionId(String distributionId
) {
435 this.distributionId
= distributionId
;
438 public String
getGroupId() {
442 public void setGroupId(String groupId
) {
443 this.groupId
= groupId
;
446 public String
getArtifactId() {
450 public void setArtifactId(String artifactId
) {
451 this.artifactId
= artifactId
;
454 public String
getVersion() {
458 public void setVersion(String version
) {
459 this.version
= version
;
462 public String
getType() {
466 public void setType(String type
) {
470 public String
getClassifier() {
474 public void setClassifier(String classifier
) {
475 this.classifier
= classifier
;