2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.osgi
.boot
;
18 import static org
.argeo
.osgi
.boot
.OsgiBootUtils
.debug
;
19 import static org
.argeo
.osgi
.boot
.OsgiBootUtils
.warn
;
22 import java
.util
.ArrayList
;
23 import java
.util
.HashMap
;
24 import java
.util
.Iterator
;
25 import java
.util
.List
;
27 import java
.util
.Properties
;
29 import java
.util
.SortedMap
;
30 import java
.util
.StringTokenizer
;
31 import java
.util
.TreeMap
;
33 import org
.argeo
.osgi
.boot
.internal
.springutil
.AntPathMatcher
;
34 import org
.argeo
.osgi
.boot
.internal
.springutil
.PathMatcher
;
35 import org
.argeo
.osgi
.boot
.internal
.springutil
.SystemPropertyUtils
;
36 import org
.osgi
.framework
.Bundle
;
37 import org
.osgi
.framework
.BundleContext
;
38 import org
.osgi
.framework
.BundleException
;
39 import org
.osgi
.framework
.FrameworkEvent
;
40 import org
.osgi
.framework
.Version
;
41 import org
.osgi
.framework
.startlevel
.BundleStartLevel
;
42 import org
.osgi
.framework
.startlevel
.FrameworkStartLevel
;
43 import org
.osgi
.framework
.wiring
.FrameworkWiring
;
46 * Basic provisioning of an OSGi runtime via file path patterns and system
47 * properties. The approach is to generate list of URLs based on various
48 * methods, configured via properties.
50 public class OsgiBoot
implements OsgiBootConstants
{
51 public final static String PROP_ARGEO_OSGI_START
= "argeo.osgi.start";
52 public final static String PROP_ARGEO_OSGI_BUNDLES
= "argeo.osgi.bundles";
53 public final static String PROP_ARGEO_OSGI_BASE_URL
= "argeo.osgi.baseUrl";
54 public final static String PROP_ARGEO_OSGI_LOCAL_CACHE
= "argeo.osgi.localCache";
55 public final static String PROP_ARGEO_OSGI_DISTRIBUTION_URL
= "argeo.osgi.distributionUrl";
58 public final static String PROP_ARGEO_OSGI_BOOT_DEBUG
= "argeo.osgi.boot.debug";
59 // public final static String PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN =
60 // "argeo.osgi.boot.excludeSvn";
62 public final static String PROP_ARGEO_OSGI_BOOT_SYSTEM_PROPERTIES_FILE
= "argeo.osgi.boot.systemPropertiesFile";
63 public final static String PROP_ARGEO_OSGI_BOOT_APPCLASS
= "argeo.osgi.boot.appclass";
64 public final static String PROP_ARGEO_OSGI_BOOT_APPARGS
= "argeo.osgi.boot.appargs";
66 public final static String DEFAULT_BASE_URL
= "reference:file:";
67 // public final static String EXCLUDES_SVN_PATTERN = "**/.svn/**";
69 // OSGi system properties
70 final static String PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL
= "osgi.bundles.defaultStartLevel";
71 final static String PROP_OSGI_STARTLEVEL
= "osgi.startLevel";
72 final static String INSTANCE_AREA_PROP
= "osgi.instance.area";
73 final static String CONFIGURATION_AREA_PROP
= "osgi.configuration.area";
76 public final static String SYMBOLIC_NAME_OSGI_BOOT
= "org.argeo.osgi.boot";
77 public final static String SYMBOLIC_NAME_EQUINOX
= "org.eclipse.osgi";
79 /** Exclude svn metadata implicitely(a bit costly) */
80 // private boolean excludeSvn =
81 // Boolean.valueOf(System.getProperty(PROP_ARGEO_OSGI_BOOT_EXCLUDE_SVN,
87 private long defaultTimeout
= 10000l;
89 private final BundleContext bundleContext
;
90 private final String localCache
;
96 public OsgiBoot(BundleContext bundleContext
) {
97 this.bundleContext
= bundleContext
;
98 localCache
= getProperty(PROP_ARGEO_OSGI_LOCAL_CACHE
,
99 "file://" + System
.getProperty("user.home") + "/.m2/repository/");
105 /** Bootstraps the OSGi runtime */
106 public void bootstrap() {
108 long begin
= System
.currentTimeMillis();
109 System
.out
.println();
110 String osgiInstancePath
= bundleContext
.getProperty(INSTANCE_AREA_PROP
);
112 .info("OSGi bootstrap starting" + (osgiInstancePath
!= null ?
" (" + osgiInstancePath
+ ")" : ""));
113 installUrls(getBundlesUrls());
114 installUrls(getDistributionUrls());
116 long duration
= System
.currentTimeMillis() - begin
;
117 OsgiBootUtils
.info("OSGi bootstrap completed in " + Math
.round(((double) duration
) / 1000) + "s ("
118 + duration
+ "ms), " + bundleContext
.getBundles().length
+ " bundles");
119 } catch (RuntimeException e
) {
120 OsgiBootUtils
.error("OSGi bootstrap FAILED", e
);
125 if (OsgiBootUtils
.debug
) {
126 OsgiBootDiagnostics diagnostics
= new OsgiBootDiagnostics(bundleContext
);
127 diagnostics
.checkUnresolved();
128 Map
<String
, Set
<String
>> duplicatePackages
= diagnostics
.findPackagesExportedTwice();
129 if (duplicatePackages
.size() > 0) {
130 OsgiBootUtils
.info("Packages exported twice:");
131 Iterator
<String
> it
= duplicatePackages
.keySet().iterator();
132 while (it
.hasNext()) {
133 String pkgName
= it
.next();
134 OsgiBootUtils
.info(pkgName
);
135 Set
<String
> bdles
= duplicatePackages
.get(pkgName
);
136 Iterator
<String
> bdlesIt
= bdles
.iterator();
137 while (bdlesIt
.hasNext())
138 OsgiBootUtils
.info(" " + bdlesIt
.next());
142 System
.out
.println();
148 /** Install a single url. Convenience method. */
149 public Bundle
installUrl(String url
) {
150 List
<String
> urls
= new ArrayList
<String
>();
153 return (Bundle
) getBundlesByLocation().get(url
);
156 /** Install the bundles at this URL list. */
157 public void installUrls(List
<String
> urls
) {
158 Map
<String
, Bundle
> installedBundles
= getBundlesByLocation();
159 for (int i
= 0; i
< urls
.size(); i
++) {
160 String url
= (String
) urls
.get(i
);
161 installUrl(url
, installedBundles
);
166 /** Actually install the provided URL */
167 protected void installUrl(String url
, Map
<String
, Bundle
> installedBundles
) {
169 if (installedBundles
.containsKey(url
)) {
170 Bundle bundle
= (Bundle
) installedBundles
.get(url
);
171 if (OsgiBootUtils
.debug
)
172 debug("Bundle " + bundle
.getSymbolicName() + " already installed from " + url
);
173 } else if (url
.contains("/" + SYMBOLIC_NAME_EQUINOX
+ "/")
174 || url
.contains("/" + SYMBOLIC_NAME_OSGI_BOOT
+ "/")) {
175 if (OsgiBootUtils
.debug
)
179 Bundle bundle
= bundleContext
.installBundle(url
);
180 if (url
.startsWith("http"))
182 .info("Installed " + bundle
.getSymbolicName() + "-" + bundle
.getVersion() + " from " + url
);
183 else if (OsgiBootUtils
.debug
)
185 "Installed " + bundle
.getSymbolicName() + "-" + bundle
.getVersion() + " from " + url
);
186 assert bundle
.getSymbolicName() != null;
187 // uninstall previous versions
188 bundles
: for (Bundle b
: bundleContext
.getBundles()) {
189 if (b
.getSymbolicName() == null)
191 if (bundle
.getSymbolicName().equals(b
.getSymbolicName())) {
192 Version bundleV
= bundle
.getVersion();
193 Version bV
= b
.getVersion();
196 if (bundleV
.getMajor() == bV
.getMajor() && bundleV
.getMinor() == bV
.getMinor()) {
197 if (bundleV
.getMicro() > bV
.getMicro()) {
198 // uninstall older bundles
200 OsgiBootUtils
.debug("Uninstalled " + b
);
201 } else if (bundleV
.getMicro() < bV
.getMicro()) {
202 // uninstall just installed bundle if newer
204 OsgiBootUtils
.debug("Uninstalled " + bundle
);
207 // uninstall any other with same major/minor
208 if (!bundleV
.getQualifier().equals(bV
.getQualifier())) {
210 OsgiBootUtils
.debug("Uninstalled " + b
);
217 } catch (BundleException e
) {
218 String message
= e
.getMessage();
219 if ((message
.contains("Bundle \"" + SYMBOLIC_NAME_OSGI_BOOT
+ "\"")
220 || message
.contains("Bundle \"" + SYMBOLIC_NAME_EQUINOX
+ "\""))
221 && message
.contains("is already installed")) {
222 // silent, in order to avoid warnings: we know that both
223 // have already been installed...
225 OsgiBootUtils
.warn("Could not install bundle from " + url
+ ": " + message
);
227 if (OsgiBootUtils
.debug
&& !message
.contains("is already installed"))
235 public void startBundles() {
236 startBundles(System
.getProperties());
239 public void startBundles(Properties properties
) {
240 FrameworkStartLevel frameworkStartLevel
= bundleContext
.getBundle(0).adapt(FrameworkStartLevel
.class);
242 // default and active start levels from System properties
243 Integer defaultStartLevel
= new Integer(
244 Integer
.parseInt(getProperty(PROP_OSGI_BUNDLES_DEFAULTSTARTLEVEL
, "4")));
245 Integer activeStartLevel
= new Integer(getProperty(PROP_OSGI_STARTLEVEL
, "6"));
247 SortedMap
<Integer
, List
<String
>> startLevels
= new TreeMap
<Integer
, List
<String
>>();
248 computeStartLevels(startLevels
, properties
, defaultStartLevel
);
249 // inverts the map for the time being, TODO optimise
250 Map
<String
, Integer
> bundleStartLevels
= new HashMap
<>();
251 for (Integer level
: startLevels
.keySet()) {
252 for (String bsn
: startLevels
.get(level
))
253 bundleStartLevels
.put(bsn
, level
);
255 for (Bundle bundle
: bundleContext
.getBundles()) {
256 String bsn
= bundle
.getSymbolicName();
257 if (bundleStartLevels
.containsKey(bsn
)) {
258 BundleStartLevel bundleStartLevel
= bundle
.adapt(BundleStartLevel
.class);
259 Integer level
= bundleStartLevels
.get(bsn
);
260 if (bundleStartLevel
.getStartLevel() != level
|| !bundleStartLevel
.isPersistentlyStarted()) {
261 bundleStartLevel
.setStartLevel(level
);
264 } catch (BundleException e
) {
265 OsgiBootUtils
.error("Cannot mark " + bsn
+ " as started", e
);
268 OsgiBootUtils
.debug(bsn
+ " starts at level " + level
);
272 frameworkStartLevel
.setStartLevel(activeStartLevel
, (FrameworkEvent event
) -> {
274 OsgiBootUtils
.debug("Framework event: " + event
);
275 int initialStartLevel
= frameworkStartLevel
.getInitialBundleStartLevel();
276 int startLevel
= frameworkStartLevel
.getStartLevel();
277 OsgiBootUtils
.debug("Framework start level: " + startLevel
+ " (initial: " + initialStartLevel
+ ")");
281 private static void computeStartLevels(SortedMap
<Integer
, List
<String
>> startLevels
, Properties properties
,
282 Integer defaultStartLevel
) {
284 // default (and previously, only behaviour)
285 appendToStartLevels(startLevels
, defaultStartLevel
, properties
.getProperty(PROP_ARGEO_OSGI_START
, ""));
287 // list argeo.osgi.start.* system properties
288 Iterator
<Object
> keys
= properties
.keySet().iterator();
289 final String prefix
= PROP_ARGEO_OSGI_START
+ ".";
290 while (keys
.hasNext()) {
291 String key
= keys
.next().toString();
292 if (key
.startsWith(prefix
)) {
294 String suffix
= key
.substring(prefix
.length());
295 String
[] tokens
= suffix
.split("\\.");
296 if (tokens
.length
> 0 && !tokens
[0].trim().equals(""))
298 // first token is start level
299 startLevel
= new Integer(tokens
[0]);
300 } catch (NumberFormatException e
) {
301 startLevel
= defaultStartLevel
;
304 startLevel
= defaultStartLevel
;
306 // append bundle names
307 String bundleNames
= properties
.getProperty(key
);
308 appendToStartLevels(startLevels
, startLevel
, bundleNames
);
313 /** Append a comma-separated list of bundles to the start levels. */
314 private static void appendToStartLevels(SortedMap
<Integer
, List
<String
>> startLevels
, Integer startLevel
,
316 if (str
== null || str
.trim().equals(""))
319 if (!startLevels
.containsKey(startLevel
))
320 startLevels
.put(startLevel
, new ArrayList
<String
>());
321 String
[] bundleNames
= str
.split(",");
322 for (int i
= 0; i
< bundleNames
.length
; i
++) {
323 if (bundleNames
[i
] != null && !bundleNames
[i
].trim().equals(""))
324 (startLevels
.get(startLevel
)).add(bundleNames
[i
]);
329 * Start the provided list of bundles
331 * @return whether all bundles are now in active state
335 public boolean startBundles(List
<String
> bundlesToStart
) {
336 if (bundlesToStart
.size() == 0)
339 // used to monitor ACTIVE states
340 List
<Bundle
> startedBundles
= new ArrayList
<Bundle
>();
341 // used to log the bundles not found
342 List
<String
> notFoundBundles
= new ArrayList
<String
>(bundlesToStart
);
344 Bundle
[] bundles
= bundleContext
.getBundles();
345 long startBegin
= System
.currentTimeMillis();
346 for (int i
= 0; i
< bundles
.length
; i
++) {
347 Bundle bundle
= bundles
[i
];
348 String symbolicName
= bundle
.getSymbolicName();
349 if (bundlesToStart
.contains(symbolicName
))
353 if (OsgiBootUtils
.debug
)
354 debug("Bundle " + symbolicName
+ " started");
355 } catch (Exception e
) {
356 OsgiBootUtils
.warn("Start of bundle " + symbolicName
+ " failed because of " + e
357 + ", maybe bundle is not yet resolved," + " waiting and trying again.");
358 waitForBundleResolvedOrActive(startBegin
, bundle
);
360 startedBundles
.add(bundle
);
362 notFoundBundles
.remove(symbolicName
);
363 } catch (Exception e
) {
364 OsgiBootUtils
.warn("Bundle " + symbolicName
+ " cannot be started: " + e
.getMessage());
365 if (OsgiBootUtils
.debug
)
367 // was found even if start failed
368 notFoundBundles
.remove(symbolicName
);
372 for (int i
= 0; i
< notFoundBundles
.size(); i
++)
373 OsgiBootUtils
.warn("Bundle '" + notFoundBundles
.get(i
) + "' not started because it was not found.");
375 // monitors that all bundles are started
376 long beginMonitor
= System
.currentTimeMillis();
377 boolean allStarted
= !(startedBundles
.size() > 0);
378 List
<String
> notStarted
= new ArrayList
<String
>();
379 while (!allStarted
&& (System
.currentTimeMillis() - beginMonitor
) < defaultTimeout
) {
380 notStarted
= new ArrayList
<String
>();
382 for (int i
= 0; i
< startedBundles
.size(); i
++) {
383 Bundle bundle
= (Bundle
) startedBundles
.get(i
);
384 // TODO check behaviour of lazs bundles
385 if (bundle
.getState() != Bundle
.ACTIVE
) {
387 notStarted
.add(bundle
.getSymbolicName());
392 } catch (InterruptedException e
) {
396 long duration
= System
.currentTimeMillis() - beginMonitor
;
399 for (int i
= 0; i
< notStarted
.size(); i
++)
400 OsgiBootUtils
.warn("Bundle '" + notStarted
.get(i
) + "' not ACTIVE after " + (duration
/ 1000) + "s");
405 /** Waits for a bundle to become active or resolved */
407 private void waitForBundleResolvedOrActive(long startBegin
, Bundle bundle
) throws Exception
{
408 int originalState
= bundle
.getState();
409 if ((originalState
== Bundle
.RESOLVED
) || (originalState
== Bundle
.ACTIVE
))
412 String originalStateStr
= OsgiBootUtils
.stateAsString(originalState
);
414 int currentState
= bundle
.getState();
415 while (!(currentState
== Bundle
.RESOLVED
|| currentState
== Bundle
.ACTIVE
)) {
416 long now
= System
.currentTimeMillis();
417 if ((now
- startBegin
) > defaultTimeout
* 10)
418 throw new Exception("Bundle " + bundle
.getSymbolicName() + " was not RESOLVED or ACTIVE after "
419 + (now
- startBegin
) + "ms (originalState=" + originalStateStr
+ ", currentState="
420 + OsgiBootUtils
.stateAsString(currentState
) + ")");
424 } catch (InterruptedException e
) {
427 currentState
= bundle
.getState();
432 * BUNDLE PATTERNS INSTALLATION
435 * Computes a list of URLs based on Ant-like include/exclude patterns defined by
436 * ${argeo.osgi.bundles} with the following format:<br>
437 * <code>/base/directory;in=*.jar;in=**;ex=org.eclipse.osgi_*;jar</code><br>
438 * WARNING: <code>/base/directory;in=*.jar,\</code> at the end of a file,
439 * without a new line causes a '.' to be appended with unexpected side effects.
441 public List
<String
> getBundlesUrls() {
442 String bundlePatterns
= getProperty(PROP_ARGEO_OSGI_BUNDLES
);
443 return getBundlesUrls(bundlePatterns
);
447 * Compute a list of URLs to install based on the provided patterns, with
450 public List
<String
> getBundlesUrls(String bundlePatterns
) {
451 String baseUrl
= getProperty(PROP_ARGEO_OSGI_BASE_URL
, DEFAULT_BASE_URL
);
452 return getBundlesUrls(baseUrl
, bundlePatterns
);
455 /** Implements the path matching logic */
456 public List
<String
> getBundlesUrls(String baseUrl
, String bundlePatterns
) {
457 List
<String
> urls
= new ArrayList
<String
>();
458 if (bundlePatterns
== null)
461 bundlePatterns
= SystemPropertyUtils
.resolvePlaceholders(bundlePatterns
);
462 if (OsgiBootUtils
.debug
)
463 debug(PROP_ARGEO_OSGI_BUNDLES
+ "=" + bundlePatterns
);
465 StringTokenizer st
= new StringTokenizer(bundlePatterns
, ",");
466 List
<BundlesSet
> bundlesSets
= new ArrayList
<BundlesSet
>();
467 while (st
.hasMoreTokens()) {
468 String token
= st
.nextToken();
469 if (new File(token
).exists()) {
470 String url
= locationToUrl(baseUrl
, token
);
473 bundlesSets
.add(new BundlesSet(token
));
477 List
<String
> included
= new ArrayList
<String
>();
478 PathMatcher matcher
= new AntPathMatcher();
479 for (int i
= 0; i
< bundlesSets
.size(); i
++) {
480 BundlesSet bundlesSet
= (BundlesSet
) bundlesSets
.get(i
);
481 for (int j
= 0; j
< bundlesSet
.getIncludes().size(); j
++) {
482 String pattern
= (String
) bundlesSet
.getIncludes().get(j
);
483 match(matcher
, included
, bundlesSet
.getDir(), null, pattern
);
488 List
<String
> excluded
= new ArrayList
<String
>();
489 for (int i
= 0; i
< bundlesSets
.size(); i
++) {
490 BundlesSet bundlesSet
= (BundlesSet
) bundlesSets
.get(i
);
491 for (int j
= 0; j
< bundlesSet
.getExcludes().size(); j
++) {
492 String pattern
= (String
) bundlesSet
.getExcludes().get(j
);
493 match(matcher
, excluded
, bundlesSet
.getDir(), null, pattern
);
498 for (int i
= 0; i
< included
.size(); i
++) {
499 String fullPath
= (String
) included
.get(i
);
500 if (!excluded
.contains(fullPath
))
501 urls
.add(locationToUrl(baseUrl
, fullPath
));
508 * DISTRIBUTION JAR INSTALLATION
510 public List
<String
> getDistributionUrls() {
511 String distributionUrl
= getProperty(PROP_ARGEO_OSGI_DISTRIBUTION_URL
);
512 String baseUrl
= getProperty(PROP_ARGEO_OSGI_BASE_URL
);
513 return getDistributionUrls(distributionUrl
, baseUrl
);
516 public List
<String
> getDistributionUrls(String distributionUrl
, String baseUrl
) {
517 List
<String
> urls
= new ArrayList
<String
>();
518 if (distributionUrl
== null)
521 DistributionBundle distributionBundle
;
522 if (distributionUrl
.startsWith("http") || distributionUrl
.startsWith("file")) {
523 distributionBundle
= new DistributionBundle(distributionUrl
);
525 distributionBundle
.setBaseUrl(baseUrl
);
528 if (baseUrl
== null) {
529 baseUrl
= localCache
;
532 if (distributionUrl
.contains(":")) {
533 // TODO make it safer
534 String
[] parts
= distributionUrl
.trim().split(":");
535 String
[] categoryParts
= parts
[0].split("\\.");
536 String artifactId
= parts
[1];
537 String version
= parts
[2];
538 StringBuilder sb
= new StringBuilder();
539 for (String categoryPart
: categoryParts
) {
540 sb
.append(categoryPart
).append('/');
542 sb
.append(artifactId
).append('/');
543 sb
.append(version
).append('/');
544 sb
.append(artifactId
).append('-').append(version
).append(".jar");
545 distributionUrl
= sb
.toString();
548 distributionBundle
= new DistributionBundle(baseUrl
, distributionUrl
, localCache
);
550 // if (baseUrl != null && !(distributionUrl.startsWith("http") ||
551 // distributionUrl.startsWith("file"))) {
553 // distributionBundle = new DistributionBundle(baseUrl, distributionUrl,
556 // distributionBundle = new DistributionBundle(distributionUrl);
557 // if (baseUrl != null)
558 // distributionBundle.setBaseUrl(baseUrl);
560 distributionBundle
.processUrl();
561 return distributionBundle
.listUrls();
565 * HIGH LEVEL UTILITIES
567 /** Actually performs the matching logic. */
568 protected void match(PathMatcher matcher
, List
<String
> matched
, String base
, String currentPath
, String pattern
) {
569 if (currentPath
== null) {
571 File baseDir
= new File(base
.replace('/', File
.separatorChar
));
572 File
[] files
= baseDir
.listFiles();
575 if (OsgiBootUtils
.debug
)
576 OsgiBootUtils
.warn("Base dir " + baseDir
+ " has no children, exists=" + baseDir
.exists()
577 + ", isDirectory=" + baseDir
.isDirectory());
581 for (int i
= 0; i
< files
.length
; i
++)
582 match(matcher
, matched
, base
, files
[i
].getName(), pattern
);
584 String fullPath
= base
+ '/' + currentPath
;
585 if (matched
.contains(fullPath
))
586 return;// don't try deeper if already matched
588 boolean ok
= matcher
.match(pattern
, currentPath
);
590 // debug(currentPath + " " + (ok ? "" : " not ")
591 // + " matched with " + pattern);
593 matched
.add(fullPath
);
596 String newFullPath
= relativeToFullPath(base
, currentPath
);
597 File newFile
= new File(newFullPath
);
598 File
[] files
= newFile
.listFiles();
600 for (int i
= 0; i
< files
.length
; i
++) {
601 String newCurrentPath
= currentPath
+ '/' + files
[i
].getName();
602 if (files
[i
].isDirectory()) {
603 if (matcher
.matchStart(pattern
, newCurrentPath
)) {
604 // recurse only if start matches
605 match(matcher
, matched
, base
, newCurrentPath
, pattern
);
607 if (OsgiBootUtils
.debug
)
608 debug(newCurrentPath
+ " does not start match with " + pattern
);
612 boolean nonDirectoryOk
= matcher
.match(pattern
, newCurrentPath
);
613 if (OsgiBootUtils
.debug
)
614 debug(currentPath
+ " " + (ok ?
"" : " not ") + " matched with " + pattern
);
616 matched
.add(relativeToFullPath(base
, newCurrentPath
));
624 protected void matchFile() {
629 * LOW LEVEL UTILITIES
632 * The bundles already installed. Key is location (String) , value is a
635 public Map
<String
, Bundle
> getBundlesByLocation() {
636 Map
<String
, Bundle
> installedBundles
= new HashMap
<String
, Bundle
>();
637 Bundle
[] bundles
= bundleContext
.getBundles();
638 for (int i
= 0; i
< bundles
.length
; i
++) {
639 installedBundles
.put(bundles
[i
].getLocation(), bundles
[i
]);
641 return installedBundles
;
645 * The bundles already installed. Key is symbolic name (String) , value is a
648 public Map
<String
, Bundle
> getBundlesBySymbolicName() {
649 Map
<String
, Bundle
> namedBundles
= new HashMap
<String
, Bundle
>();
650 Bundle
[] bundles
= bundleContext
.getBundles();
651 for (int i
= 0; i
< bundles
.length
; i
++) {
652 namedBundles
.put(bundles
[i
].getSymbolicName(), bundles
[i
]);
657 /** Creates an URL from a location */
658 protected String
locationToUrl(String baseUrl
, String location
) {
659 return baseUrl
+ location
;
662 /** Transforms a relative path in a full system path. */
663 protected String
relativeToFullPath(String basePath
, String relativePath
) {
664 return (basePath
+ '/' + relativePath
).replace('/', File
.separatorChar
);
667 private void refreshFramework() {
668 Bundle systemBundle
= bundleContext
.getBundle(0);
669 FrameworkWiring frameworkWiring
= systemBundle
.adapt(FrameworkWiring
.class);
670 frameworkWiring
.refreshBundles(null);
674 * Gets a property value
676 * @return null when defaultValue is ""
678 public String
getProperty(String name
, String defaultValue
) {
679 String value
= bundleContext
.getProperty(name
);
681 return defaultValue
; // may be null
686 public String
getProperty(String name
) {
687 return getProperty(name
, null);
694 public boolean getDebug() {
695 return OsgiBootUtils
.debug
;
698 // public void setDebug(boolean debug) {
699 // this.debug = debug;
702 public BundleContext
getBundleContext() {
703 return bundleContext
;
706 public String
getLocalCache() {
710 // public void setDefaultTimeout(long defaultTimeout) {
711 // this.defaultTimeout = defaultTimeout;
714 // public boolean isExcludeSvn() {
715 // return excludeSvn;
718 // public void setExcludeSvn(boolean excludeSvn) {
719 // this.excludeSvn = excludeSvn;