]> git.argeo.org Git - lgpl/argeo-commons.git/blob - osgi/runtime/org.argeo.osgi.boot/src/main/java/org/argeo/slc/osgiboot/OsgiBoot.java
Fix typo
[lgpl/argeo-commons.git] / osgi / runtime / org.argeo.osgi.boot / src / main / java / org / argeo / slc / osgiboot / OsgiBoot.java
1 package org.argeo.slc.osgiboot;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.InputStreamReader;
8 import java.net.URL;
9 import java.util.ArrayList;
10 import java.util.HashMap;
11 import java.util.Iterator;
12 import java.util.List;
13 import java.util.Map;
14 import java.util.StringTokenizer;
15
16 import org.argeo.slc.osgiboot.internal.springutil.AntPathMatcher;
17 import org.argeo.slc.osgiboot.internal.springutil.PathMatcher;
18 import org.argeo.slc.osgiboot.internal.springutil.SystemPropertyUtils;
19 import org.osgi.framework.Bundle;
20 import org.osgi.framework.BundleContext;
21 import org.osgi.framework.BundleException;
22 import org.osgi.framework.Constants;
23 import org.osgi.framework.ServiceReference;
24 import org.osgi.service.packageadmin.PackageAdmin;
25
26 public class OsgiBoot {
27 public final static String SYMBOLIC_NAME_OSGI_BOOT = "org.argeo.osgi.boot";
28 public final static String SYMBOLIC_NAME_EQUINOX = "org.eclipse.osgi";
29
30 public final static String PROP_ARGEO_OSGI_DATA_DIR = "argeo.osgi.data.dir";
31
32 public final static String PROP_ARGEO_OSGI_START = "argeo.osgi.start";
33 public final static String PROP_ARGEO_OSGI_BUNDLES = "argeo.osgi.bundles";
34 public final static String PROP_ARGEO_OSGI_LOCATIONS = "argeo.osgi.locations";
35 public final static String PROP_ARGEO_OSGI_BASE_URL = "argeo.osgi.baseUrl";
36 public final static String PROP_ARGEO_OSGI_MODULES_URL = "argeo.osgi.modulesUrl";
37
38 public final static String PROP_ARGEO_OSGI_BOOT_DEBUG = "argeo.osgi.boot.debug";
39 public final static String PROP_ARGEO_OSGI_BOOT_DEFAULT_TIMEOUT = "argeo.osgi.boot.defaultTimeout";
40 public final static String PROP_ARGEO_OSGI_BOOT_MODULES_URL_SEPARATOR = "argeo.osgi.boot.modulesUrlSeparator";
41 public final static String PROP_ARGEO_OSGI_BOOT_SYSTEM_PROPERTIES_FILE = "argeo.osgi.boot.systemPropertiesFile";
42
43 /** @deprecated */
44 public final static String PROP_SLC_OSGI_START = "slc.osgi.start";
45 /** @deprecated */
46 public final static String PROP_SLC_OSGI_BUNDLES = "slc.osgi.bundles";
47 /** @deprecated */
48 public final static String PROP_SLC_OSGI_LOCATIONS = "slc.osgi.locations";
49 /** @deprecated */
50 public final static String PROP_SLC_OSGI_BASE_URL = "slc.osgi.baseUrl";
51 /** @deprecated */
52 public final static String PROP_SLC_OSGI_MODULES_URL = "slc.osgi.modulesUrl";
53
54 /** @deprecated */
55 public final static String PROP_SLC_OSGIBOOT_DEBUG = "slc.osgiboot.debug";
56 /** @deprecated */
57 public final static String PROP_SLC_OSGIBOOT_DEFAULT_TIMEOUT = "slc.osgiboot.defaultTimeout";
58 /** @deprecated */
59 public final static String PROP_SLC_OSGIBOOT_MODULES_URL_SEPARATOR = "slc.osgiboot.modulesUrlSeparator";
60 /** @deprecated */
61 public final static String PROP_SLC_OSGIBOOT_SYSTEM_PROPERTIES_FILE = "slc.osgiboot.systemPropertiesFile";
62
63 public final static String DEFAULT_BASE_URL = "reference:file:";
64 public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**";
65
66 private boolean debug = Boolean.valueOf(
67 System.getProperty(PROP_ARGEO_OSGI_BOOT_DEBUG, System.getProperty(
68 PROP_SLC_OSGIBOOT_DEBUG, "false"))).booleanValue();
69 /** Default is 10s (set in constructor) */
70 private long defaultTimeout;
71
72 private boolean excludeSvn = true;
73 /** Default is ',' (set in constructor) */
74 private String modulesUrlSeparator = ",";
75
76 private final BundleContext bundleContext;
77
78 public OsgiBoot(BundleContext bundleContext) {
79 this.bundleContext = bundleContext;
80 defaultTimeout = Long.parseLong(getPropertyCompat(
81 PROP_ARGEO_OSGI_BOOT_DEFAULT_TIMEOUT,
82 PROP_SLC_OSGIBOOT_DEFAULT_TIMEOUT, "10000"));
83 modulesUrlSeparator = getPropertyCompat(
84 PROP_ARGEO_OSGI_BOOT_MODULES_URL_SEPARATOR,
85 PROP_SLC_OSGIBOOT_MODULES_URL_SEPARATOR, ",");
86 initSystemProperties();
87 }
88
89 protected void initSystemProperties() {
90 String osgiInstanceArea = System.getProperty("osgi.instance.area");
91 String osgiInstanceAreaDefault = System
92 .getProperty("osgi.instance.area.default");
93 String tempDir = System.getProperty("java.io.tmpdir");
94
95 File dataDir = null;
96 if (osgiInstanceArea != null) {
97 // within OSGi with -data specified
98 osgiInstanceArea = removeFilePrefix(osgiInstanceArea);
99 dataDir = new File(osgiInstanceArea);
100 } else if (osgiInstanceAreaDefault != null) {
101 // within OSGi without -data specified
102 osgiInstanceAreaDefault = removeFilePrefix(osgiInstanceAreaDefault);
103 dataDir = new File(osgiInstanceAreaDefault);
104 } else {// outside OSGi
105 dataDir = new File(tempDir + File.separator + "argeoOsgiData");
106 }
107
108 System.setProperty(PROP_ARGEO_OSGI_DATA_DIR, dataDir.getAbsolutePath());
109
110 // TODO: Load additional system properties from file
111 // Properties additionalSystemProperties = new Properties();
112
113 }
114
115 public static String removeFilePrefix(String url) {
116 if (url.startsWith("file:"))
117 return url.substring("file:".length());
118 else if (url.startsWith("reference:file:"))
119 return url.substring("reference:file:".length());
120 else
121 return url;
122 }
123
124 public void bootstrap() {
125 long begin = System.currentTimeMillis();
126 System.out.println();
127 info("OSGi bootstrap starting...");
128 info("Writable data directory : "
129 + System.getProperty(PROP_ARGEO_OSGI_DATA_DIR)
130 + " (set as system property " + PROP_ARGEO_OSGI_DATA_DIR + ")");
131 installUrls(getBundlesUrls());
132 installUrls(getLocationsUrls());
133 installUrls(getModulesUrls());
134 checkUnresolved();
135 startBundles();
136 long duration = System.currentTimeMillis() - begin;
137 info("OSGi bootstrap completed in "
138 + Math.round(((double) duration) / 1000) + "s (" + duration
139 + "ms), " + bundleContext.getBundles().length + " bundles");
140 System.out.println();
141 }
142
143 public void installUrls(List urls) {
144 Map installedBundles = getInstalledBundles();
145 for (int i = 0; i < urls.size(); i++) {
146 String url = (String) urls.get(i);
147 try {
148 if (installedBundles.containsKey(url)) {
149 Bundle bundle = (Bundle) installedBundles.get(url);
150 // bundle.update();
151 if (debug)
152 debug("Bundle " + bundle.getSymbolicName()
153 + " already installed from " + url);
154 } else {
155 Bundle bundle = bundleContext.installBundle(url);
156 if (debug)
157 debug("Installed bundle " + bundle.getSymbolicName()
158 + " from " + url);
159 }
160 } catch (BundleException e) {
161 String message = e.getMessage();
162 if ((message.contains("Bundle \"" + SYMBOLIC_NAME_OSGI_BOOT
163 + "\"") || message.contains("Bundle \""
164 + SYMBOLIC_NAME_EQUINOX + "\""))
165 && message.contains("has already been installed")) {
166 // silent, in order to avoid warnings: we know that both
167 // have already been installed...
168 } else {
169 warn("Could not install bundle from " + url + ": "
170 + message);
171 }
172 if (debug)
173 e.printStackTrace();
174 }
175 }
176
177 }
178
179 public void installOrUpdateUrls(Map urls) {
180 Map installedBundles = getBundles();
181
182 for (Iterator modules = urls.keySet().iterator(); modules.hasNext();) {
183 String moduleName = (String) modules.next();
184 String urlStr = (String) urls.get(moduleName);
185 if (installedBundles.containsKey(moduleName)) {
186 Bundle bundle = (Bundle) installedBundles.get(moduleName);
187 InputStream in;
188 try {
189 URL url = new URL(urlStr);
190 in = url.openStream();
191 bundle.update(in);
192 info("Updated bundle " + moduleName + " from " + urlStr);
193 } catch (Exception e) {
194 throw new RuntimeException("Cannot update " + moduleName
195 + " from " + urlStr);
196 }
197 if (in != null)
198 try {
199 in.close();
200 } catch (IOException e) {
201 e.printStackTrace();
202 }
203 } else {
204 try {
205 Bundle bundle = bundleContext.installBundle(urlStr);
206 if (debug)
207 debug("Installed bundle " + bundle.getSymbolicName()
208 + " from " + urlStr);
209 } catch (BundleException e) {
210 warn("Could not install bundle from " + urlStr + ": "
211 + e.getMessage());
212 }
213 }
214 }
215
216 }
217
218 public void startBundles() {
219 String bundlesToStart = getPropertyCompat(PROP_ARGEO_OSGI_START,
220 PROP_SLC_OSGI_START);
221 startBundles(bundlesToStart);
222 }
223
224 public void startBundles(String bundlesToStartStr) {
225 if (bundlesToStartStr == null)
226 return;
227
228 StringTokenizer st = new StringTokenizer(bundlesToStartStr, ",");
229 List bundlesToStart = new ArrayList();
230 while (st.hasMoreTokens()) {
231 String name = st.nextToken().trim();
232 bundlesToStart.add(name);
233 }
234 startBundles(bundlesToStart);
235 }
236
237 public void startBundles(List bundlesToStart) {
238 if (bundlesToStart.size() == 0)
239 return;
240
241 // used to log the bundles not found
242 List notFoundBundles = new ArrayList(bundlesToStart);
243
244 Bundle[] bundles = bundleContext.getBundles();
245 long startBegin = System.currentTimeMillis();
246 for (int i = 0; i < bundles.length; i++) {
247 Bundle bundle = bundles[i];
248 String symbolicName = bundle.getSymbolicName();
249 if (bundlesToStart.contains(symbolicName))
250 try {
251 try {
252 bundle.start();
253 } catch (Exception e) {
254 warn("Start of bundle " + symbolicName
255 + " failed because of " + e
256 + ", maybe bundle is not yet resolved,"
257 + " waiting and trying again.");
258 waitForBundleResolvedOrActive(startBegin, bundle);
259 bundle.start();
260 }
261 notFoundBundles.remove(symbolicName);
262 } catch (Exception e) {
263 warn("Bundle " + symbolicName + " cannot be started: "
264 + e.getMessage());
265 if (debug)
266 e.printStackTrace();
267 // was found even if start failed
268 notFoundBundles.remove(symbolicName);
269 }
270 }
271
272 for (int i = 0; i < notFoundBundles.size(); i++)
273 warn("Bundle " + notFoundBundles.get(i)
274 + " not started because it was not found.");
275 }
276
277 protected void checkUnresolved() {
278 // Refresh
279 ServiceReference packageAdminRef = bundleContext
280 .getServiceReference(PackageAdmin.class.getName());
281 PackageAdmin packageAdmin = (PackageAdmin) bundleContext
282 .getService(packageAdminRef);
283 packageAdmin.resolveBundles(null);
284
285 Bundle[] bundles = bundleContext.getBundles();
286 List /* Bundle */unresolvedBundles = new ArrayList();
287 for (int i = 0; i < bundles.length; i++) {
288 int bundleState = bundles[i].getState();
289 if (!(bundleState == Bundle.ACTIVE
290 || bundleState == Bundle.RESOLVED || bundleState == Bundle.STARTING))
291 unresolvedBundles.add(bundles[i]);
292 }
293
294 if (unresolvedBundles.size() != 0) {
295 warn("Unresolved bundles " + unresolvedBundles);
296 }
297 }
298
299 protected void waitForBundleResolvedOrActive(long startBegin, Bundle bundle)
300 throws Exception {
301 int originalState = bundle.getState();
302 if ((originalState == Bundle.RESOLVED)
303 || (originalState == Bundle.ACTIVE))
304 return;
305
306 String originalStateStr = stateAsString(originalState);
307
308 int currentState = bundle.getState();
309 while (!(currentState == Bundle.RESOLVED || currentState == Bundle.ACTIVE)) {
310 long now = System.currentTimeMillis();
311 if ((now - startBegin) > defaultTimeout)
312 throw new Exception("Bundle " + bundle.getSymbolicName()
313 + " was not RESOLVED or ACTIVE after "
314 + (now - startBegin) + "ms (originalState="
315 + originalStateStr + ", currentState="
316 + stateAsString(currentState) + ")");
317
318 try {
319 Thread.sleep(100l);
320 } catch (InterruptedException e) {
321 // silent
322 }
323 currentState = bundle.getState();
324 }
325 }
326
327 public static String stateAsString(int state) {
328 switch (state) {
329 case Bundle.UNINSTALLED:
330 return "UNINSTALLED";
331 case Bundle.INSTALLED:
332 return "INSTALLED";
333 case Bundle.RESOLVED:
334 return "RESOLVED";
335 case Bundle.STARTING:
336 return "STARTING";
337 case Bundle.ACTIVE:
338 return "ACTIVE";
339 case Bundle.STOPPING:
340 return "STOPPING";
341 default:
342 return Integer.toString(state);
343 }
344 }
345
346 /** Key is location */
347 public Map getInstalledBundles() {
348 Map installedBundles = new HashMap();
349
350 Bundle[] bundles = bundleContext.getBundles();
351 for (int i = 0; i < bundles.length; i++) {
352 installedBundles.put(bundles[i].getLocation(), bundles[i]);
353 }
354 return installedBundles;
355 }
356
357 /** Key is symbolic name */
358 public Map getBundles() {
359 Map namedBundles = new HashMap();
360 Bundle[] bundles = bundleContext.getBundles();
361 for (int i = 0; i < bundles.length; i++) {
362 namedBundles.put(bundles[i].getSymbolicName(), bundles[i]);
363 }
364 return namedBundles;
365 }
366
367 public List getLocationsUrls() {
368 String baseUrl = getPropertyCompat(PROP_ARGEO_OSGI_BASE_URL,
369 PROP_SLC_OSGI_BASE_URL, DEFAULT_BASE_URL);
370 String bundleLocations = getPropertyCompat(PROP_ARGEO_OSGI_LOCATIONS,
371 PROP_SLC_OSGI_LOCATIONS);
372 return getLocationsUrls(baseUrl, bundleLocations);
373 }
374
375 public List getModulesUrls() {
376 List urls = new ArrayList();
377 String modulesUrlStr = getPropertyCompat(PROP_ARGEO_OSGI_MODULES_URL,
378 PROP_SLC_OSGI_MODULES_URL);
379 if (modulesUrlStr == null)
380 return urls;
381
382 String baseUrl = getPropertyCompat(PROP_ARGEO_OSGI_BASE_URL,
383 PROP_SLC_OSGI_BASE_URL);
384
385 Map installedBundles = getBundles();
386
387 BufferedReader reader = null;
388 try {
389 URL modulesUrl = new URL(modulesUrlStr);
390 reader = new BufferedReader(new InputStreamReader(modulesUrl
391 .openStream()));
392 String line = null;
393 while ((line = reader.readLine()) != null) {
394 StringTokenizer st = new StringTokenizer(line,
395 modulesUrlSeparator);
396 String moduleName = st.nextToken();
397 String moduleVersion = st.nextToken();
398 String url = st.nextToken();
399 if (baseUrl != null)
400 url = baseUrl + url;
401
402 if (installedBundles.containsKey(moduleName)) {
403 Bundle bundle = (Bundle) installedBundles.get(moduleName);
404 String bundleVersion = bundle.getHeaders().get(
405 Constants.BUNDLE_VERSION).toString();
406 int comp = compareVersions(bundleVersion, moduleVersion);
407 if (comp > 0) {
408 warn("Installed version " + bundleVersion
409 + " of bundle " + moduleName
410 + " is newer than provided version "
411 + moduleVersion);
412 } else if (comp < 0) {
413 urls.add(url);
414 info("Updated bundle " + moduleName + " with version "
415 + moduleVersion + " (old version was "
416 + bundleVersion + ")");
417 } else {
418 // do nothing
419 }
420 } else {
421 urls.add(url);
422 }
423 }
424 } catch (Exception e1) {
425 throw new RuntimeException("Cannot read url " + modulesUrlStr, e1);
426 } finally {
427 if (reader != null)
428 try {
429 reader.close();
430 } catch (IOException e) {
431 e.printStackTrace();
432 }
433 }
434 return urls;
435 }
436
437 /**
438 * @return ==0: versions are identical, <0: tested version is newer, >0:
439 * currentVersion is newer.
440 */
441 protected int compareVersions(String currentVersion, String testedVersion) {
442 List cToks = new ArrayList();
443 StringTokenizer cSt = new StringTokenizer(currentVersion, ".");
444 while (cSt.hasMoreTokens())
445 cToks.add(cSt.nextToken());
446 List tToks = new ArrayList();
447 StringTokenizer tSt = new StringTokenizer(currentVersion, ".");
448 while (tSt.hasMoreTokens())
449 tToks.add(tSt.nextToken());
450
451 int comp = 0;
452 comp: for (int i = 0; i < cToks.size(); i++) {
453 if (tToks.size() <= i) {
454 // equals until then, tested shorter
455 comp = 1;
456 break comp;
457 }
458
459 String c = (String) cToks.get(i);
460 String t = (String) tToks.get(i);
461
462 try {
463 int cInt = Integer.parseInt(c);
464 int tInt = Integer.parseInt(t);
465 if (cInt == tInt)
466 continue comp;
467 else {
468 comp = (cInt - tInt);
469 break comp;
470 }
471 } catch (NumberFormatException e) {
472 if (c.equals(t))
473 continue comp;
474 else {
475 comp = c.compareTo(t);
476 break comp;
477 }
478 }
479 }
480
481 if (comp == 0 && tToks.size() > cToks.size()) {
482 // equals until then, current shorter
483 comp = -1;
484 }
485
486 return comp;
487 }
488
489 public List getLocationsUrls(String baseUrl, String bundleLocations) {
490 List urls = new ArrayList();
491
492 if (bundleLocations == null)
493 return urls;
494 bundleLocations = SystemPropertyUtils
495 .resolvePlaceholders(bundleLocations);
496 if (debug)
497 debug(PROP_ARGEO_OSGI_LOCATIONS + "=" + bundleLocations);
498
499 StringTokenizer st = new StringTokenizer(bundleLocations,
500 File.pathSeparator);
501 while (st.hasMoreTokens()) {
502 urls.add(locationToUrl(baseUrl, st.nextToken().trim()));
503 }
504 return urls;
505 }
506
507 public List getBundlesUrls() {
508 String baseUrl = getPropertyCompat(PROP_ARGEO_OSGI_BASE_URL,
509 PROP_SLC_OSGI_BASE_URL, DEFAULT_BASE_URL);
510 String bundlePatterns = getPropertyCompat(PROP_ARGEO_OSGI_BUNDLES,
511 PROP_SLC_OSGI_BUNDLES);
512 return getBundlesUrls(baseUrl, bundlePatterns);
513 }
514
515 public List getBundlesUrls(String baseUrl, String bundlePatterns) {
516 List urls = new ArrayList();
517
518 List bundlesSets = new ArrayList();
519 if (bundlePatterns == null)
520 return urls;
521 bundlePatterns = SystemPropertyUtils
522 .resolvePlaceholders(bundlePatterns);
523 if (debug)
524 debug(PROP_ARGEO_OSGI_BUNDLES + "=" + bundlePatterns
525 + " (excludeSvn=" + excludeSvn + ")");
526
527 StringTokenizer st = new StringTokenizer(bundlePatterns, ",");
528 while (st.hasMoreTokens()) {
529 bundlesSets.add(new BundlesSet(st.nextToken()));
530 }
531
532 List included = new ArrayList();
533 PathMatcher matcher = new AntPathMatcher();
534 for (int i = 0; i < bundlesSets.size(); i++) {
535 BundlesSet bundlesSet = (BundlesSet) bundlesSets.get(i);
536 for (int j = 0; j < bundlesSet.getIncludes().size(); j++) {
537 String pattern = (String) bundlesSet.getIncludes().get(j);
538 match(matcher, included, bundlesSet.getDir(), null, pattern);
539 }
540 }
541
542 List excluded = new ArrayList();
543 for (int i = 0; i < bundlesSets.size(); i++) {
544 BundlesSet bundlesSet = (BundlesSet) bundlesSets.get(i);
545 for (int j = 0; j < bundlesSet.getExcludes().size(); j++) {
546 String pattern = (String) bundlesSet.getExcludes().get(j);
547 match(matcher, excluded, bundlesSet.getDir(), null, pattern);
548 }
549 }
550
551 for (int i = 0; i < included.size(); i++) {
552 String fullPath = (String) included.get(i);
553 if (!excluded.contains(fullPath))
554 urls.add(locationToUrl(baseUrl, fullPath));
555 }
556
557 return urls;
558 }
559
560 protected void match(PathMatcher matcher, List matched, String base,
561 String currentPath, String pattern) {
562 if (currentPath == null) {
563 // Init
564 File baseDir = new File(base.replace('/', File.separatorChar));
565 File[] files = baseDir.listFiles();
566
567 if (files == null) {
568 warn("Base dir " + baseDir + " has no children, exists="
569 + baseDir.exists() + ", isDirectory="
570 + baseDir.isDirectory());
571 return;
572 }
573
574 for (int i = 0; i < files.length; i++)
575 match(matcher, matched, base, files[i].getName(), pattern);
576 } else {
577 String fullPath = base + '/' + currentPath;
578 if (matched.contains(fullPath))
579 return;// don't try deeper if already matched
580
581 boolean ok = matcher.match(pattern, currentPath);
582 if (debug)
583 debug(currentPath + " " + (ok ? "" : " not ")
584 + " matched with " + pattern);
585 if (ok) {
586 matched.add(fullPath);
587 return;
588 } else {
589 String newFullPath = relativeToFullPath(base, currentPath);
590 File newFile = new File(newFullPath);
591 File[] files = newFile.listFiles();
592 if (files != null) {
593 for (int i = 0; i < files.length; i++) {
594 String newCurrentPath = currentPath + '/'
595 + files[i].getName();
596 if (files[i].isDirectory()) {
597 if (matcher.matchStart(pattern, newCurrentPath)) {
598 // recurse only if start matches
599 match(matcher, matched, base, newCurrentPath,
600 pattern);
601 } else {
602 if (debug)
603 debug(newCurrentPath
604 + " does not start match with "
605 + pattern);
606
607 }
608 } else {
609 boolean nonDirectoryOk = matcher.match(pattern,
610 newCurrentPath);
611 if (debug)
612 debug(currentPath + " " + (ok ? "" : " not ")
613 + " matched with " + pattern);
614 if (nonDirectoryOk)
615 matched.add(relativeToFullPath(base,
616 newCurrentPath));
617 }
618 }
619 }
620 }
621 }
622 }
623
624 protected String locationToUrl(String baseUrl, String location) {
625 int extInd = location.lastIndexOf('.');
626 String ext = null;
627 if (extInd > 0)
628 ext = location.substring(extInd);
629
630 if (baseUrl.startsWith("reference:") && ".jar".equals(ext))
631 return "file:" + location;
632 else
633 return baseUrl + location;
634 }
635
636 /** Transforms a relative path in a full system path. */
637 protected String relativeToFullPath(String basePath, String relativePath) {
638 return (basePath + '/' + relativePath).replace('/', File.separatorChar);
639 }
640
641 protected static void info(Object obj) {
642 System.out.println("# OSGiBOOT # " + obj);
643 }
644
645 protected void debug(Object obj) {
646 if (debug)
647 System.out.println("# OSGiBOOT DBG # " + obj);
648 }
649
650 protected void warn(Object obj) {
651 System.out.println("# OSGiBOOT WARN # " + obj);
652 // Because of a weird bug under Windows when starting it in a forked VM
653 // if (System.getProperty("os.name").contains("Windows"))
654 // System.out.println("# WARN " + obj);
655 // else
656 // System.err.println("# WARN " + obj);
657 }
658
659 protected String getProperty(String name, String defaultValue) {
660 final String value;
661 if (defaultValue != null)
662 value = System.getProperty(name, defaultValue);
663 else
664 value = System.getProperty(name);
665
666 if (value == null || value.equals(""))
667 return null;
668 else
669 return value;
670 }
671
672 protected String getProperty(String name) {
673 return getProperty(name, null);
674 }
675
676 protected String getPropertyCompat(String name, String oldName) {
677 return getPropertyCompat(name, oldName, null);
678 }
679
680 protected String getPropertyCompat(String name, String oldName,
681 String defaultValue) {
682 String res = null;
683
684 if (defaultValue != null) {
685 res = getProperty(name, defaultValue);
686 if (res.equals(defaultValue)) {
687 res = getProperty(oldName, defaultValue);
688 if (!res.equals(defaultValue))
689 warnDeprecated(name, oldName);
690 }
691 } else {
692 res = getProperty(name, null);
693 if (res == null) {
694 res = getProperty(oldName, null);
695 if (res != null)
696 warnDeprecated(name, oldName);
697 }
698 }
699 return res;
700 }
701
702 protected void warnDeprecated(String name, String oldName) {
703 warn("Property '" + oldName
704 + "' is deprecated and will be removed soon, use '" + name
705 + "' instead.");
706 }
707
708 public boolean getDebug() {
709 return debug;
710 }
711
712 public void setDebug(boolean debug) {
713 this.debug = debug;
714 }
715
716 public BundleContext getBundleContext() {
717 return bundleContext;
718 }
719
720 /** Whether to exclude Subversion directories (true by default) */
721 public boolean isExcludeSvn() {
722 return excludeSvn;
723 }
724
725 public void setExcludeSvn(boolean excludeSvn) {
726 this.excludeSvn = excludeSvn;
727 }
728
729 protected class BundlesSet {
730 private String baseUrl = "reference:file";// not used yet
731 private final String dir;
732 private List includes = new ArrayList();
733 private List excludes = new ArrayList();
734
735 public BundlesSet(String def) {
736 StringTokenizer st = new StringTokenizer(def, ";");
737
738 if (!st.hasMoreTokens())
739 throw new RuntimeException("Base dir not defined.");
740 try {
741 String dirPath = st.nextToken();
742
743 if (dirPath.startsWith("file:"))
744 dirPath = dirPath.substring("file:".length());
745
746 dir = new File(dirPath.replace('/', File.separatorChar))
747 .getCanonicalPath();
748 if (debug)
749 debug("Base dir: " + dir);
750 } catch (IOException e) {
751 throw new RuntimeException("Cannot convert to absolute path", e);
752 }
753
754 while (st.hasMoreTokens()) {
755 String tk = st.nextToken();
756 StringTokenizer stEq = new StringTokenizer(tk, "=");
757 String type = stEq.nextToken();
758 String pattern = stEq.nextToken();
759 if ("in".equals(type) || "include".equals(type)) {
760 includes.add(pattern);
761 } else if ("ex".equals(type) || "exclude".equals(type)) {
762 excludes.add(pattern);
763 } else if ("baseUrl".equals(type)) {
764 baseUrl = pattern;
765 } else {
766 System.err.println("Unkown bundles pattern type " + type);
767 }
768 }
769
770 if (excludeSvn && !excludes.contains(EXCLUDES_SVN_PATTERN)) {
771 excludes.add(EXCLUDES_SVN_PATTERN);
772 }
773 }
774
775 public String getDir() {
776 return dir;
777 }
778
779 public List getIncludes() {
780 return includes;
781 }
782
783 public List getExcludes() {
784 return excludes;
785 }
786
787 public String getBaseUrl() {
788 return baseUrl;
789 }
790
791 }
792
793 public void setDefaultTimeout(long defaultTimeout) {
794 this.defaultTimeout = defaultTimeout;
795 }
796
797 public void setModulesUrlSeparator(String modulesUrlSeparator) {
798 this.modulesUrlSeparator = modulesUrlSeparator;
799 }
800
801 }