Fix for pax-web / webconsole problem Project: http://git-wip-us.apache.org/repos/asf/karaf/repo Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/014e3505 Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/014e3505 Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/014e3505
Branch: refs/heads/master Commit: 014e35055e2a3339b3542b82b75192d170343543 Parents: 23f6473 Author: Guillaume Nodet <[email protected]> Authored: Mon Jun 22 22:19:06 2015 +0200 Committer: Guillaume Nodet <[email protected]> Committed: Mon Jun 22 22:19:06 2015 +0200 ---------------------------------------------------------------------- .../features/internal/region/Subsystem.java | 19 +++--- .../region/SubsystemResolveContext.java | 61 +++++++++++++++++--- 2 files changed, 65 insertions(+), 15 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/karaf/blob/014e3505/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java index 71a22d3..75e497a 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/Subsystem.java @@ -32,6 +32,7 @@ import java.util.jar.Manifest; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; +import org.apache.felix.resolver.Util; import org.apache.felix.utils.manifest.Clause; import org.apache.felix.utils.manifest.Parser; import org.apache.felix.utils.version.VersionRange; @@ -95,6 +96,7 @@ public class Subsystem extends ResourceImpl { private final boolean acceptDependencies; private final Subsystem parent; private final Feature feature; + private final boolean mandatory; private final List<Subsystem> children = new ArrayList<>(); private final Map<String, Set<String>> importPolicy; private final Map<String, Set<String>> exportPolicy; @@ -112,14 +114,16 @@ public class Subsystem extends ResourceImpl { this.feature = null; this.importPolicy = SHARE_NONE_POLICY; this.exportPolicy = SHARE_NONE_POLICY; + this.mandatory = true; } - public Subsystem(String name, Feature feature, Subsystem parent) { + public Subsystem(String name, Feature feature, Subsystem parent, boolean mandatory) { super(name, TYPE_SUBSYSTEM, Version.emptyVersion); this.name = name; this.parent = parent; this.acceptDependencies = feature.getScoping() != null && feature.getScoping().acceptDependencies(); this.feature = feature; + this.mandatory = mandatory; if (feature.getScoping() != null) { this.importPolicy = createPolicy(feature.getScoping().getImports()); this.importPolicy.put(IDENTITY_NAMESPACE, Collections.singleton(SUBSYSTEM_OR_FEATURE_FILTER)); @@ -136,12 +140,13 @@ public class Subsystem extends ResourceImpl { new VersionRange(VersionTable.getVersion(feature.getVersion()), true)); } - public Subsystem(String name, Subsystem parent, boolean acceptDependencies) { + public Subsystem(String name, Subsystem parent, boolean acceptDependencies, boolean mandatory) { super(name, TYPE_SUBSYSTEM, Version.emptyVersion); this.name = name; this.parent = parent; this.acceptDependencies = acceptDependencies; this.feature = null; + this.mandatory = mandatory; this.importPolicy = SHARE_ALL_POLICY; this.exportPolicy = SHARE_NONE_POLICY; } @@ -193,7 +198,7 @@ public class Subsystem extends ResourceImpl { } // Create subsystem String childName = getName() + "/" + name; - Subsystem as = new Subsystem(childName, this, acceptDependencies); + Subsystem as = new Subsystem(childName, this, acceptDependencies, true); children.add(as); // Add a requirement to force its resolution ResourceUtils.addIdentityRequirement(this, childName, TYPE_SUBSYSTEM, (VersionRange) null); @@ -211,7 +216,7 @@ public class Subsystem extends ResourceImpl { ResourceUtils.addIdentityRequirement(this, name, TYPE_FEATURE, range); } else { ResourceImpl res = new ResourceImpl(); - ResourceUtils.addIdentityRequirement(res, name, TYPE_FEATURE, range); + ResourceUtils.addIdentityRequirement(res, name, TYPE_FEATURE, range, false); dependentFeatures.addAll(res.getRequirements(null)); } } @@ -272,14 +277,14 @@ public class Subsystem extends ResourceImpl { while (!ss.isAcceptDependencies()) { ss = ss.getParent(); } - ss.requireFeature(dep.getName(), dep.getVersion(), mandatory && !dep.isDependency()); + ss.requireFeature(dep.getName(), dep.getVersion(), this.mandatory && (mandatory && !dep.isDependency())); } for (Conditional cond : feature.getConditional()) { Feature fcond = cond.asFeature(); String ssName = this.name + "#" + (fcond.hasVersion() ? fcond.getName() + "-" + fcond.getVersion() : fcond.getName()); Subsystem fs = getChild(ssName); if (fs == null) { - fs = new Subsystem(ssName, fcond, this); + fs = new Subsystem(ssName, fcond, this, true); fs.doBuild(features, false); installable.add(fs); children.add(fs); @@ -306,7 +311,7 @@ public class Subsystem extends ResourceImpl { String ssName = this.name + "#" + (feature.hasVersion() ? feature.getName() + "-" + feature.getVersion() : feature.getName()); Subsystem fs = getChild(ssName); if (fs == null) { - fs = new Subsystem(ssName, feature, this); + fs = new Subsystem(ssName, feature, this, mandatory && !SubsystemResolveContext.isOptional(requirement)); fs.build(features); installable.add(fs); children.add(fs); http://git-wip-us.apache.org/repos/asf/karaf/blob/014e3505/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java ---------------------------------------------------------------------- diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java index 104fb24..1ed9ef5 100644 --- a/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java +++ b/features/core/src/main/java/org/apache/karaf/features/internal/region/SubsystemResolveContext.java @@ -86,7 +86,7 @@ public class SubsystemResolveContext extends ResolveContext { // Add a heuristic to sort capabilities : // if a capability comes from a resource which needs to be installed, // prefer that one over any capabilities from other resources - findMandatory(root); + findMandatory(); } public static void setIgnoreServiceReqs(boolean ignoreServiceReqs) { @@ -101,18 +101,63 @@ public class SubsystemResolveContext extends ResolveContext { return globalRepository; } - void findMandatory(Resource res) { - if (mandatory.add(res)) { - for (Requirement req : res.getRequirements(null)) { - String resolution = req.getDirectives().get(REQUIREMENT_RESOLUTION_DIRECTIVE); - if (!RESOLUTION_OPTIONAL.equals(resolution)) { + void findMandatory() { + mandatory.add(root); + int nbMandatory; + // Iterate while we find more mandatory resources + do { + nbMandatory = mandatory.size(); + for (Resource res : new ArrayList<>(mandatory)) { + // Check mandatory requirements of mandatory resources + for (Requirement req : res.getRequirements(null)) { + if (isOptional(req)) { + continue; + } List<Capability> caps = findProviders(req); + // If there's a single provider for any kind of mandatory requirement, + // this means the resource is also mandatory if (caps.size() == 1) { - findMandatory(caps.get(0).getResource()); + mandatory.add(caps.get(0).getResource()); + } else { + // In case there are multiple providers + // check if there is a single provider which has + // a mandatory identity requirement on a mandatory + // resource, in which case we also assume this one + // is mandatory + Set<Resource> mand = new HashSet<>(); + for (Capability cap : caps) { + Resource r = cap.getResource(); + if (mandatory.contains(r)) { + mand.add(r); + } else { + for (Requirement req2 : r.getRequirements(null)) { + if (!IDENTITY_NAMESPACE.equals(req2.getNamespace()) || !isOptional(req2)) { + continue; + } + List<Capability> caps2 = findProviders(req2); + if (caps2.size() == 1) { + Resource r2 = caps2.get(0).getResource(); + if (mandatory.contains(r2)) { + mand.add(r); + } + } + } + } + } + if (mand.size() == 1) { + mandatory.add(mand.iterator().next()); + } else { + mand.clear(); + } } } } - } + } while (mandatory.size() != nbMandatory); + } + + static boolean isOptional(Requirement req) { + String resolution = req.getDirectives().get(REQUIREMENT_RESOLUTION_DIRECTIVE); + return RESOLUTION_OPTIONAL.equalsIgnoreCase(resolution); } void prepare(Subsystem subsystem) {
