protected void findBundlesWithFramentsToRefresh(Set<Bundle> toRefresh) { for (Bundle b : toRefresh) { if (b.getState() != Bundle.UNINSTALLED) { String hostHeader = (String) b.getHeaders().get(Constants.FRAGMENT_HOST); if (hostHeader != null) { Clause[] clauses = Parser.parseHeader(hostHeader); if (clauses != null && clauses.length > 0) { Clause path = clauses[0]; for (Bundle hostBundle : bundleContext.getBundles()) { if (hostBundle.getSymbolicName().equals(path.getName())) { String ver = path.getAttribute(Constants.BUNDLE_VERSION_ATTRIBUTE); if (ver != null) { VersionRange v = VersionRange.parseVersionRange(ver); if (v.contains(hostBundle.getVersion())) { toRefresh.add(hostBundle); } } else { toRefresh.add(hostBundle); } } } } } } } }
private boolean checkBundle(String bundleName, String version) { VersionRange vr = VersionRange.parseVersionRange(version); Bundle[] bundles = bundleContext.getBundles(); for (int i = 0; (bundles != null) && (i < bundles.length); i++) { String sym = bundles[i].getSymbolicName(); if ((sym != null) && sym.equals(bundleName)) { if (vr.contains(bundles[i].getVersion())) { return true; } } } return false; }
private boolean checkPackage(String packageName, String version) { VersionRange range = VersionRange.parseVersionRange(version); Bundle[] bundles = bundleContext.getBundles(); for (int i = 0; (bundles != null) && (i < bundles.length); i++) { BundleWiring wiring = bundles[i].adapt(BundleWiring.class); List<BundleCapability> caps = wiring != null ? wiring.getCapabilities(BundleRevision.PACKAGE_NAMESPACE) : null; if (caps != null) { for (BundleCapability cap : caps) { String n = getAttribute(cap, BundleRevision.PACKAGE_NAMESPACE); String v = getAttribute(cap, Constants.VERSION_ATTRIBUTE); if (packageName.equals(n) && range.contains(VersionTable.getVersion(v))) { return true; } } } } return false; }
protected void findBundlesWithOptionalPackagesToRefresh(Set<Bundle> toRefresh) { // First pass: include all bundles contained in these features Set<Bundle> bundles = new HashSet<Bundle>(Arrays.asList(bundleContext.getBundles())); bundles.removeAll(toRefresh); if (bundles.isEmpty()) { return; } // Second pass: for each bundle, check if there is any unresolved optional package that could be // resolved Map<Bundle, List<Clause>> imports = new HashMap<Bundle, List<Clause>>(); for (Iterator<Bundle> it = bundles.iterator(); it.hasNext(); ) { Bundle b = it.next(); String importsStr = (String) b.getHeaders().get(Constants.IMPORT_PACKAGE); List<Clause> importsList = getOptionalImports(importsStr); if (importsList.isEmpty()) { it.remove(); } else { imports.put(b, importsList); } } if (bundles.isEmpty()) { return; } // Third pass: compute a list of packages that are exported by our bundles and see if // some exported packages can be wired to the optional imports List<Clause> exports = new ArrayList<Clause>(); for (Bundle b : toRefresh) { if (b.getState() != Bundle.UNINSTALLED) { String exportsStr = (String) b.getHeaders().get(Constants.EXPORT_PACKAGE); if (exportsStr != null) { Clause[] exportsList = Parser.parseHeader(exportsStr); exports.addAll(Arrays.asList(exportsList)); } } } for (Iterator<Bundle> it = bundles.iterator(); it.hasNext(); ) { Bundle b = it.next(); List<Clause> importsList = imports.get(b); for (Iterator<Clause> itpi = importsList.iterator(); itpi.hasNext(); ) { Clause pi = itpi.next(); boolean matching = false; for (Clause pe : exports) { if (pi.getName().equals(pe.getName())) { String evStr = pe.getAttribute(Constants.VERSION_ATTRIBUTE); String ivStr = pi.getAttribute(Constants.VERSION_ATTRIBUTE); Version exported = evStr != null ? Version.parseVersion(evStr) : Version.emptyVersion; VersionRange imported = ivStr != null ? VersionRange.parseVersionRange(ivStr) : VersionRange.ANY_VERSION; if (imported.contains(exported)) { matching = true; break; } } } if (!matching) { itpi.remove(); } } if (importsList.isEmpty()) { it.remove(); } } toRefresh.addAll(bundles); }
Map<String, Result> install( final Collection<Patch> patches, boolean simulate, boolean synchronous) { try { // Compute individual patch results final Map<String, Result> results = new LinkedHashMap<String, Result>(); final Map<Bundle, String> toUpdate = new HashMap<Bundle, String>(); Map<String, BundleUpdate> allUpdates = new HashMap<String, BundleUpdate>(); for (Patch patch : patches) { String startup = readFully(new File(System.getProperty("karaf.base"), "etc/startup.properties")); String overrides = readFully(new File(System.getProperty("karaf.base"), "etc/overrides.properties")); List<BundleUpdate> updates = new ArrayList<BundleUpdate>(); Bundle[] allBundles = bundleContext.getBundles(); for (String url : patch.getBundles()) { JarInputStream jis = new JarInputStream(new URL(url).openStream()); jis.close(); Manifest manifest = jis.getManifest(); Attributes att = manifest != null ? manifest.getMainAttributes() : null; String sn = att != null ? att.getValue(Constants.BUNDLE_SYMBOLICNAME) : null; String vr = att != null ? att.getValue(Constants.BUNDLE_VERSION) : null; if (sn == null || vr == null) { continue; } Version v = VersionTable.getVersion(vr); VersionRange range = null; if (patch.getVersionRange(url) == null) { // default version range starts with x.y.0 as the lower bound Version lower = new Version(v.getMajor(), v.getMinor(), 0); // We can't really upgrade with versions such as 2.1.0 if (v.compareTo(lower) > 0) { range = new VersionRange(false, lower, v, true); } } else { range = new VersionRange(patch.getVersionRange(url)); } if (range != null) { for (Bundle bundle : allBundles) { Version oldV = bundle.getVersion(); if (bundle.getBundleId() != 0 && stripSymbolicName(sn).equals(stripSymbolicName(bundle.getSymbolicName())) && range.contains(oldV)) { String location = bundle.getLocation(); BundleUpdate update = new BundleUpdateImpl(sn, v.toString(), url, oldV.toString(), location); updates.add(update); // Merge result BundleUpdate oldUpdate = allUpdates.get(sn); if (oldUpdate != null) { Version upv = VersionTable.getVersion(oldUpdate.getNewVersion()); if (upv.compareTo(v) < 0) { allUpdates.put(sn, update); toUpdate.put(bundle, url); } } else { toUpdate.put(bundle, url); } } } } else { System.err.printf( "Skipping bundle %s - unable to process bundle without a version range configuration%n", url); } } if (!simulate) { new Offline(new File(System.getProperty("karaf.base"))) .applyConfigChanges(((PatchImpl) patch).getPatch()); } Result result = new ResultImpl( patch, simulate, System.currentTimeMillis(), updates, startup, overrides); results.put(patch.getId(), result); } // Apply results System.out.println("Bundles to update:"); for (Map.Entry<Bundle, String> e : toUpdate.entrySet()) { System.out.println( " " + e.getKey().getSymbolicName() + "/" + e.getKey().getVersion().toString() + " with " + e.getValue()); } if (simulate) { System.out.println("Running simulation only - no bundles are being updated at this time"); } else { System.out.println( "Installation will begin. The connection may be lost or the console restarted."); } System.out.flush(); if (!simulate) { Thread thread = new Thread() { public void run() { try { applyChanges(toUpdate); for (Patch patch : patches) { Result result = results.get(patch.getId()); ((PatchImpl) patch).setResult(result); saveResult(result); } } catch (Exception e) { e.printStackTrace(System.err); System.err.flush(); } } }; if (synchronous) { thread.run(); } else { thread.start(); } } return results; } catch (Exception e) { throw new PatchException(e); } }