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