You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by gn...@apache.org on 2015/06/22 22:22:33 UTC
[1/4] karaf git commit: Fix problem with the same bundle being
available in 2 unrelated features
Repository: karaf
Updated Branches:
refs/heads/master 571c46e4e -> 6574c0de0
Fix problem with the same bundle being available in 2 unrelated features
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/4c3370c9
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/4c3370c9
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/4c3370c9
Branch: refs/heads/master
Commit: 4c3370c93ea3e624905538fa29a0a86a721590ea
Parents: 571c46e
Author: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Authored: Mon Jun 22 20:13:02 2015 +0200
Committer: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Committed: Mon Jun 22 20:13:02 2015 +0200
----------------------------------------------------------------------
.../region/SubsystemResolveContext.java | 46 +++++++++++++++-----
.../features/internal/region/SubsystemTest.java | 22 ++++++++++
.../karaf/features/internal/region/data6/a.mf | 5 +++
.../karaf/features/internal/region/data6/b.mf | 5 +++
.../karaf/features/internal/region/data6/c.mf | 5 +++
.../features/internal/region/data6/features.xml | 42 ++++++++++++++++++
6 files changed, 113 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/4c3370c9/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 c25d9f4..104fb24 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
@@ -161,26 +161,48 @@ public class SubsystemResolveContext extends ResolveContext {
// need to remove the one from the child if it can view
// the parent one
if (caps.size() > 1) {
- Map<String, Resource> providers = new HashMap<String, Resource>();
+ Set<Resource> providers = new HashSet<>();
for (Capability cap : caps) {
Resource resource = cap.getResource();
String id = ResolverUtil.getSymbolicName(resource) + "|" + ResolverUtil.getVersion(resource);
- Resource prev = providers.get(id);
- if (prev != null && prev != resource) {
- String r1 = getRegion(prev).getName();
- String r2 = getRegion(resource).getName();
- int c = r1.compareTo(r2);
- if (c == 0) {
- // One of the resource has to be a bundle, use that one
- c = (prev instanceof BundleRevision) ? -1 : +1;
+ if (!providers.contains(resource)) {
+ Set<Resource> newRes = new HashSet<>();
+ String r1 = getRegion(resource).getName();
+ boolean superceded = false;
+ for (Resource r : providers) {
+ String id2 = ResolverUtil.getSymbolicName(r) + "|" + ResolverUtil.getVersion(r);
+ if (id.equals(id2)) {
+ String r2 = getRegion(r).getName();
+ if (r1.equals(r2)) {
+ if (r instanceof BundleRevision) {
+ newRes.add(r);
+ superceded = true;
+ } else if (resource instanceof BundleRevision) {
+ newRes.add(resource);
+ } else {
+ throw new InternalError();
+ }
+ } else if (r1.startsWith(r2)) {
+ newRes.add(r);
+ superceded = true;
+ } else if (r2.startsWith(r1)) {
+ newRes.add(resource);
+ } else {
+ newRes.add(r);
+ }
+ } else {
+ newRes.add(r);
+ }
}
- resource = c < 0 ? prev : resource;
+ if (!superceded) {
+ newRes.add(resource);
+ }
+ providers = newRes;
}
- providers.put(id, resource);
}
for (Iterator<Capability> it = caps.iterator(); it.hasNext();) {
Capability cap = it.next();
- if (!providers.values().contains(cap.getResource())) {
+ if (!providers.contains(cap.getResource())) {
it.remove();
}
}
http://git-wip-us.apache.org/repos/asf/karaf/blob/4c3370c9/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
----------------------------------------------------------------------
diff --git a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
index 846a2c9..d957ae6 100644
--- a/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
+++ b/features/core/src/test/java/org/apache/karaf/features/internal/region/SubsystemTest.java
@@ -231,6 +231,28 @@ public class SubsystemTest {
verify(resolver, expected);
}
+ @Test
+ public void testFeatureOptionalAlreadyProvided2() throws Exception {
+ RepositoryImpl repo = new RepositoryImpl(getClass().getResource("data6/features.xml").toURI());
+
+ Map<String, Set<String>> features = new HashMap<String, Set<String>>();
+ addToMapSet(features, "root", "pax-http");
+ addToMapSet(features, "root", "pax-http-tomcat");
+ Map<String, Set<String>> expected = new HashMap<String, Set<String>>();
+ addToMapSet(expected, "root", "a/1.0.0");
+ addToMapSet(expected, "root", "c/1.0.0");
+
+ SubsystemResolver resolver = new SubsystemResolver(this.resolver, new TestDownloadManager(getClass(), "data6"));
+ resolver.prepare(Arrays.asList(repo.getFeatures()),
+ features,
+ Collections.<String, Set<BundleRevision>>emptyMap());
+ resolver.resolve(Collections.<String>emptySet(),
+ FeaturesService.DEFAULT_FEATURE_RESOLUTION_RANGE,
+ null, null);
+
+ verify(resolver, expected);
+ }
+
private void verify(SubsystemResolver resolver, Map<String, Set<String>> expected) {
Map<String, Set<String>> mapping = getBundleNamesPerRegions(resolver);
if (!expected.equals(mapping)) {
http://git-wip-us.apache.org/repos/asf/karaf/blob/4c3370c9/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf
new file mode 100644
index 0000000..20a7811
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/a.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: a
+Bundle-Version: 1.0.0
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/4c3370c9/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf
new file mode 100644
index 0000000..dc96158
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/b.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: b
+Bundle-Version: 1.0.0
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/4c3370c9/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf
new file mode 100644
index 0000000..8535efa
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/c.mf
@@ -0,0 +1,5 @@
+Manifest-Version: 1
+Bundle-ManifestVersion: 2
+Bundle-SymbolicName: c
+Bundle-Version: 1.0.0
+
http://git-wip-us.apache.org/repos/asf/karaf/blob/4c3370c9/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml
----------------------------------------------------------------------
diff --git a/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml
new file mode 100644
index 0000000..08982f7
--- /dev/null
+++ b/features/core/src/test/resources/org/apache/karaf/features/internal/region/data6/features.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<features name="test" xmlns="http://karaf.apache.org/xmlns/features/v1.3.0">
+
+ <feature name="pax-http">
+ <feature dependency="true">pax-http-jetty</feature>
+ <requirement>pax-http-provider</requirement>
+ </feature>
+
+ <feature name="pax-jetty">
+ <bundle>b</bundle>
+ </feature>
+
+ <feature name="pax-http-jetty">
+ <capability>pax-http-provider;provider:=jetty</capability>
+ <feature>pax-jetty</feature>
+ <bundle>a</bundle>
+ </feature>
+
+ <feature name="pax-http-tomcat">
+ <capability>pax-http-provider;provider:=tomcat</capability>
+ <bundle>c</bundle>
+ <bundle>a</bundle>
+ </feature>
+
+</features>
\ No newline at end of file
[4/4] karaf git commit: Disable ignoreServiceReqs flag by default
Posted by gn...@apache.org.
Disable ignoreServiceReqs flag by default
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/6574c0de
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/6574c0de
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/6574c0de
Branch: refs/heads/master
Commit: 6574c0de0e8879bfa9a4f3de159e322e6416a014
Parents: 4250c4b
Author: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Authored: Mon Jun 22 22:20:10 2015 +0200
Committer: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Committed: Mon Jun 22 22:20:10 2015 +0200
----------------------------------------------------------------------
.../java/org/apache/karaf/features/internal/osgi/Activator.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/6574c0de/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
index 954ebce..b4f088d 100644
--- a/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
+++ b/features/core/src/main/java/org/apache/karaf/features/internal/osgi/Activator.java
@@ -179,7 +179,7 @@ public class Activator extends BaseActivator {
long scheduleDelay = getLong("scheduleDelay", FeaturesService.DEFAULT_SCHEDULE_DELAY);
int scheduleMaxRun = getInt("scheduleMaxRun", FeaturesService.DEFAULT_SCHEDULE_MAX_RUN);
String blacklisted = getString("blacklisted", new File(System.getProperty("karaf.etc"), "blacklisted.properties").toURI().toString());
- boolean ignoreServiceReqs = getBoolean("ignoreServiceReqs", true);
+ boolean ignoreServiceReqs = getBoolean("ignoreServiceReqs", false);
SubsystemResolveContext.setIgnoreServiceReqs(ignoreServiceReqs);
StateStorage stateStorage = new StateStorage() {
@Override
[3/4] karaf git commit: Upgrade to pax-web 4.1.4-SNAPSHOT
Posted by gn...@apache.org.
Upgrade to pax-web 4.1.4-SNAPSHOT
Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/4250c4b5
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/4250c4b5
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/4250c4b5
Branch: refs/heads/master
Commit: 4250c4b5252ed44b47ab2686c4ed643dc3087ca4
Parents: 944bad9
Author: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Authored: Mon Jun 22 22:19:29 2015 +0200
Committer: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Committed: Mon Jun 22 22:19:29 2015 +0200
----------------------------------------------------------------------
pom.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/karaf/blob/4250c4b5/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 61374c7..a5408ef 100644
--- a/pom.xml
+++ b/pom.xml
@@ -238,7 +238,7 @@
<pax.logging.version>1.8.3</pax.logging.version>
<pax.base.version>1.5.0</pax.base.version>
<pax.url.version>2.4.1</pax.url.version>
- <pax.web.version>4.1.3</pax.web.version>
+ <pax.web.version>4.1.4-SNAPSHOT</pax.web.version>
<pax.tinybundle.version>2.1.0</pax.tinybundle.version>
<portlet-api.version>2.0</portlet-api.version>
<slf4j.version>1.7.12</slf4j.version>
[2/4] karaf git commit: Fix for pax-web / webconsole problem
Posted by gn...@apache.org.
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/944bad9e
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/944bad9e
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/944bad9e
Branch: refs/heads/master
Commit: 944bad9ec4dc01b8f254b508617dc452d35fea23
Parents: 4c3370c
Author: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
Authored: Mon Jun 22 22:19:06 2015 +0200
Committer: Guillaume Nodet <gn...@Guillaumes-MacBook-Pro.local>
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/944bad9e/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/944bad9e/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) {