You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by da...@apache.org on 2018/04/27 09:51:30 UTC
[sling-org-apache-sling-feature] 10/22: SLING-7512 Order features
based on their dependencies.
This is an automated email from the ASF dual-hosted git repository.
davidb pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature.git
commit 1587e849822ffb784f459a0a8439e6ccd2dd932a
Author: David Bosschaert <bo...@adobe.com>
AuthorDate: Fri Feb 23 13:42:28 2018 +0000
SLING-7512 Order features based on their dependencies.
Very initial implementation which contains the refactoring of
Requirements and Capabilities to use the OSGi ones.
---
.../feature/AbstractCapabilityRequirement.java | 96 +++++++++++++++++
.../java/org/apache/sling/feature/Capability.java | 104 -------------------
.../java/org/apache/sling/feature/Feature.java | 11 +-
.../org/apache/sling/feature/OSGiCapability.java | 59 +++++++++++
.../org/apache/sling/feature/OSGiRequirement.java | 59 +++++++++++
.../java/org/apache/sling/feature/Requirement.java | 113 ---------------------
.../sling/feature/process/ApplicationBuilder.java | 14 +--
.../apache/sling/feature/process/BuilderUtil.java | 4 +-
.../sling/feature/process/FeatureResolver.java | 38 +++++++
.../sling/feature/CapabilityRequirementTest.java | 68 +++++++++++++
.../sling/feature/process/FeatureBuilderTest.java | 39 +++----
11 files changed, 357 insertions(+), 248 deletions(-)
diff --git a/src/main/java/org/apache/sling/feature/AbstractCapabilityRequirement.java b/src/main/java/org/apache/sling/feature/AbstractCapabilityRequirement.java
new file mode 100644
index 0000000..200cb92
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/AbstractCapabilityRequirement.java
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+package org.apache.sling.feature;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.osgi.resource.Resource;
+
+abstract class AbstractCapabilityRequirement {
+ private final Resource resource;
+ private final String namespace;
+ private final Map<String, Object> attributes;
+ private final Map<String, String> directives;
+
+ AbstractCapabilityRequirement(Resource res, String ns, Map<String, Object> attrs, Map<String, String> dirs) {
+ resource = res;
+ namespace = ns;
+ attributes = Collections.unmodifiableMap(new HashMap<>(attrs));
+ directives = Collections.unmodifiableMap(new HashMap<>(dirs));
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public Map<String, Object> getAttributes() {
+ return attributes;
+ }
+
+ public Map<String, String> getDirectives() {
+ return directives;
+ }
+
+ public Resource getResource() {
+ return resource;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
+ result = prime * result + ((directives == null) ? 0 : directives.hashCode());
+ result = prime * result + ((namespace == null) ? 0 : namespace.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ AbstractCapabilityRequirement other = (AbstractCapabilityRequirement) obj;
+ if (attributes == null) {
+ if (other.attributes != null)
+ return false;
+ } else if (!attributes.equals(other.attributes))
+ return false;
+ if (directives == null) {
+ if (other.directives != null)
+ return false;
+ } else if (!directives.equals(other.directives))
+ return false;
+ if (namespace == null) {
+ if (other.namespace != null)
+ return false;
+ } else if (!namespace.equals(other.namespace))
+ return false;
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + " [resource=" + resource + ", namespace=" + namespace + ", attributes=" + attributes
+ + ", directives=" + directives + "]";
+ }
+}
diff --git a/src/main/java/org/apache/sling/feature/Capability.java b/src/main/java/org/apache/sling/feature/Capability.java
deleted file mode 100644
index 53c9c3b..0000000
--- a/src/main/java/org/apache/sling/feature/Capability.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * 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.
- */
-package org.apache.sling.feature;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A capability of a feature.
- * The capability is modeled after an OSGi capability: it
- * belongs to a namespace and might have attributes and / or
- * directives.
- */
-public class Capability {
-
- /** The namspace. */
- private final String namespace;
-
- /** Map of attributes. */
- private final Map<String, Object> attributes = new ConcurrentHashMap<>();
-
- /** Map of directives. */
- private final Map<String, Object> directives = new ConcurrentHashMap<>();
-
- /**
- * Create a new Capability.
- * @param namespace The namespace
- * @throws IllegalArgumentException If namespace is {@code null}.
- */
- public Capability(final String namespace) {
- if ( namespace == null ) {
- throw new IllegalArgumentException("namespace must not be null.");
- }
- this.namespace = namespace;
- }
-
- /**
- * The namespace
- * @return The namespace
- */
- public String getNamespace() {
- return namespace;
- }
-
- /**
- * Get the map of attributes.
- * The map is modifiable.
- * @return The map of attributes.
- */
- public Map<String, Object> getAttributes() {
- return attributes;
- }
-
- /**
- * Get the map of directives.
- * The map is modifiable.
- * @return The map of directives.
- */
- public Map<String, Object> getDirectives() {
- return directives;
- }
-
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + attributes.hashCode();
- result = prime * result + directives.hashCode();
- result = prime * result + namespace.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Capability other = (Capability) obj;
- if (!attributes.equals(other.attributes)
- || !directives.equals(other.directives)
- || !namespace.equals(other.namespace)) {
- return false;
- }
- return true;
- }
-}
diff --git a/src/main/java/org/apache/sling/feature/Feature.java b/src/main/java/org/apache/sling/feature/Feature.java
index 64c2488..874790d 100644
--- a/src/main/java/org/apache/sling/feature/Feature.java
+++ b/src/main/java/org/apache/sling/feature/Feature.java
@@ -20,6 +20,9 @@ import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+
/**
* A feature consists of
* <ul>
@@ -296,17 +299,13 @@ public class Feature implements Comparable<Feature> {
// requirements
for(final Requirement r : this.getRequirements()) {
- final Requirement c = new Requirement(r.getNamespace());
- c.getAttributes().putAll(r.getAttributes());
- c.getDirectives().putAll(r.getDirectives());
+ final Requirement c = new OSGiRequirement(r.getNamespace(), r.getAttributes(), r.getDirectives());
result.getRequirements().add(c);
}
// capabilities
for(final Capability r : this.getCapabilities()) {
- final Capability c = new Capability(r.getNamespace());
- c.getAttributes().putAll(r.getAttributes());
- c.getDirectives().putAll(r.getDirectives());
+ final Capability c = new OSGiCapability(r.getNamespace(), r.getAttributes(), r.getDirectives());
result.getCapabilities().add(c);
}
diff --git a/src/main/java/org/apache/sling/feature/OSGiCapability.java b/src/main/java/org/apache/sling/feature/OSGiCapability.java
new file mode 100644
index 0000000..5c2000d
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/OSGiCapability.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+package org.apache.sling.feature;
+
+import java.util.Map;
+
+import org.osgi.resource.Capability;
+import org.osgi.resource.Resource;
+
+/**
+ * Implementation of the OSGi Capability interface.
+ */
+public class OSGiCapability extends AbstractCapabilityRequirement implements Capability {
+ /**
+ * Create a capability that is not associated with a resource.
+ * @param res The resource associated with the capability. May be null.
+ * @param ns The namespace of the capability.
+ * @param attrs The attributes of the capability.
+ * @param dirs The directives of the capability.
+ */
+ public OSGiCapability(String ns, Map<String, Object> attrs, Map<String, String> dirs) {
+ this(null, ns, attrs, dirs);
+ }
+
+ /**
+ * Create a capability.
+ * @param res The resource associated with the capability. May be null.
+ * @param ns The namespace of the capability.
+ * @param attrs The attributes of the capability.
+ * @param dirs The directives of the capability.
+ */
+ public OSGiCapability(Resource res, String ns, Map<String, Object> attrs, Map<String, String> dirs) {
+ super(res, ns, attrs, dirs);
+ }
+
+ /**
+ * Create a capability based on an existing capability, providing the resource.
+ * The namespace, attributes and directives are copied from the provided capability.
+ * @param resource The resource to be associated with the capability
+ * @param capability The capability to base the new requirement on.
+ */
+ public OSGiCapability(Resource resource, Capability capability) {
+ this(resource, capability.getNamespace(), capability.getAttributes(), capability.getDirectives());
+ }
+}
diff --git a/src/main/java/org/apache/sling/feature/OSGiRequirement.java b/src/main/java/org/apache/sling/feature/OSGiRequirement.java
new file mode 100644
index 0000000..2727379
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/OSGiRequirement.java
@@ -0,0 +1,59 @@
+/*
+ * 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.
+ */
+package org.apache.sling.feature;
+
+import java.util.Map;
+
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+/**
+ * Implementation of the OSGi Requirement interface.
+ */
+public class OSGiRequirement extends AbstractCapabilityRequirement implements Requirement {
+ /**
+ * Create a requirement that is not associated with a resource.
+ * @param res The resource associated with the requirement.
+ * @param ns The namespace of the requirement.
+ * @param attrs The attributes of the requirement.
+ * @param dirs The directives of the requirement.
+ */
+ public OSGiRequirement(String ns, Map<String, Object> attrs, Map<String, String> dirs) {
+ this(null, ns, attrs, dirs);
+ }
+
+ /**
+ * Create a requirement.
+ * @param res The resource associated with the requirement.
+ * @param ns The namespace of the requirement.
+ * @param attrs The attributes of the requirement.
+ * @param dirs The directives of the requirement.
+ */
+ public OSGiRequirement(Resource res, String ns, Map<String, Object> attrs, Map<String, String> dirs) {
+ super(res, ns, attrs, dirs);
+ }
+
+ /**
+ * Create a requirement based on an existing requirement, providing the resource.
+ * The namespace, attributes and directives are copied from the provided requirement.
+ * @param resource The resource to be associated with the requirement
+ * @param requirement The requirement to base the new requirement on.
+ */
+ public OSGiRequirement(Resource resource, Requirement requirement) {
+ this(resource, requirement.getNamespace(), requirement.getAttributes(), requirement.getDirectives());
+ }
+}
diff --git a/src/main/java/org/apache/sling/feature/Requirement.java b/src/main/java/org/apache/sling/feature/Requirement.java
deleted file mode 100644
index 3409e51..0000000
--- a/src/main/java/org/apache/sling/feature/Requirement.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * 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.
- */
-package org.apache.sling.feature;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * A requirement for a feature.
- * The requirement is modeled after an OSGi requirement: it
- * belongs to a namespace and might have attributes and / or
- * directives.
- */
-public class Requirement {
-
- /*public static final String RESOLUTION_OPTIONAL = "optional";
-
- public static final String RESOLUTION_DIRECTIVE = "resolution";*/
-
- /** The namspace. */
- private final String namespace;
-
- /** Map of attributes. */
- private final Map<String, Object> attributes = new ConcurrentHashMap<>();
-
- /** Map of directives. */
- private final Map<String, Object> directives = new ConcurrentHashMap<>();
-
- /**
- * Create a new Requirement.
- * @param namespace The namespace
- * @throws IllegalArgumentException If namespace is {@code null}.
- */
- public Requirement(final String namespace) {
- if ( namespace == null ) {
- throw new IllegalArgumentException("namespace must not be null.");
- }
- this.namespace = namespace;
- }
-
- /**
- * The namespace
- * @return The namespace
- */
- public String getNamespace() {
- return namespace;
- }
-
- /**
- * Get the map of attributes.
- * The map is modifiable.
- * @return The map of attributes.
- */
- public Map<String,Object> getAttributes() {
- return attributes;
- }
-
- /**
- * Get the map of directives.
- * The map is modifiable.
- * @return The map of directives.
- */
- public Map<String,Object> getDirectives() {
- return directives;
- }
-
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + attributes.hashCode();
- result = prime * result + directives.hashCode();
- result = prime * result + namespace.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(final Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final Requirement other = (Requirement) obj;
- if (!attributes.equals(other.attributes)
- || !directives.equals(other.directives)
- || !namespace.equals(other.namespace)) {
- return false;
- }
- return true;
- }
-
- @Override
- public String toString() {
- return "[Requirement namespace='" + namespace + "' attributes=" + attributes + " directives=" + directives + "]";
- }
-}
diff --git a/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java b/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
index 1a555e1..49c17b8 100644
--- a/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
+++ b/src/main/java/org/apache/sling/feature/process/ApplicationBuilder.java
@@ -17,7 +17,6 @@
package org.apache.sling.feature.process;
import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
import org.apache.sling.feature.Application;
@@ -38,6 +37,7 @@ public class ApplicationBuilder {
*
* @param app The optional application to use as a base.
* @param context The builder context
+ * @param resolver The Feature Resolver to use
* @param featureIds The feature ids
* @return The application
* throws IllegalArgumentException If context or featureIds is {@code null}
@@ -45,6 +45,7 @@ public class ApplicationBuilder {
*/
public static Application assemble(final Application app,
final BuilderContext context,
+ final FeatureResolver resolver,
final String... featureIds) {
if ( featureIds == null || context == null ) {
throw new IllegalArgumentException("Features and/or context must not be null");
@@ -59,7 +60,7 @@ public class ApplicationBuilder {
}
index++;
}
- return assemble(app, context, features);
+ return assemble(app, context, resolver, features);
}
/**
@@ -70,6 +71,7 @@ public class ApplicationBuilder {
*
* @param app The optional application to use as a base.
* @param context The builder context
+ * @param resolver The Feature Resolver to use
* @param features The features
* @return The application
* throws IllegalArgumentException If context or featureIds is {@code null}
@@ -78,7 +80,7 @@ public class ApplicationBuilder {
public static Application assemble(
Application app,
final BuilderContext context,
- final Feature... features) {
+ final FeatureResolver resolver, final Feature... features) {
if ( features == null || context == null ) {
throw new IllegalArgumentException("Features and/or context must not be null");
}
@@ -89,7 +91,7 @@ public class ApplicationBuilder {
// Created sorted feature list
// Remove duplicate features by selecting the one with the highest version
- final List<Feature> sortedFeatureList = new ArrayList<>();
+ List<Feature> sortedFeatureList = new ArrayList<>();
for(final Feature f : features) {
Feature found = null;
for(final Feature s : sortedFeatureList) {
@@ -116,8 +118,8 @@ public class ApplicationBuilder {
}
}
- // sort
- Collections.sort(sortedFeatureList);
+ // order by dependency chain
+ sortedFeatureList = resolver.orderFeatures(sortedFeatureList);
// assemble
for(final Feature f : sortedFeatureList) {
diff --git a/src/main/java/org/apache/sling/feature/process/BuilderUtil.java b/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
index 377a5be..90da88e 100644
--- a/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
+++ b/src/main/java/org/apache/sling/feature/process/BuilderUtil.java
@@ -31,13 +31,13 @@ import javax.json.JsonValue.ValueType;
import org.apache.sling.feature.Application;
import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.Bundles;
-import org.apache.sling.feature.Capability;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Configurations;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.KeyValueMap;
-import org.apache.sling.feature.Requirement;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
/**
* Utility methods for the builders
diff --git a/src/main/java/org/apache/sling/feature/process/FeatureResolver.java b/src/main/java/org/apache/sling/feature/process/FeatureResolver.java
new file mode 100644
index 0000000..b3eaa35
--- /dev/null
+++ b/src/main/java/org/apache/sling/feature/process/FeatureResolver.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+package org.apache.sling.feature.process;
+
+import java.util.List;
+
+import org.apache.sling.feature.Feature;
+
+/**
+ * A resolver that can perform operations on the feature model.
+ */
+public interface FeatureResolver extends AutoCloseable {
+ /**
+ * Order the features by their dependency chain. Each feature and its
+ * components are resolved and each other feature providing the capabilities
+ * needed by the feature is placed before the requiring feature in the
+ * result.
+ *
+ * @param features
+ * The features to order.
+ * @return The ordered features.
+ */
+ List<Feature> orderFeatures(List<Feature> features);
+}
diff --git a/src/test/java/org/apache/sling/feature/CapabilityRequirementTest.java b/src/test/java/org/apache/sling/feature/CapabilityRequirementTest.java
new file mode 100644
index 0000000..e834bad
--- /dev/null
+++ b/src/test/java/org/apache/sling/feature/CapabilityRequirementTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ */
+package org.apache.sling.feature;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Test;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
+import org.osgi.resource.Resource;
+
+public class CapabilityRequirementTest {
+ @Test
+ public void testCapability() {
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put("org.foo", "1234");
+ attrs.put("bar", 456);
+ Map<String, String> dirs = new HashMap<>();
+ dirs.put("my_dir", "my_value");
+ Capability c = new OSGiCapability("org.foo", attrs, dirs);
+ assertEquals("org.foo", c.getNamespace());
+ assertEquals(attrs, c.getAttributes());
+ assertEquals(dirs, c.getDirectives());
+ assertNull(c.getResource());
+ }
+
+ @Test
+ public void testRequirement() {
+ Resource tr = new TestResource();
+ Requirement r = new OSGiRequirement(tr, "testing",
+ Collections.emptyMap(), Collections.emptyMap());
+ assertEquals(tr, r.getResource());
+ assertEquals(0, r.getAttributes().size());
+ assertEquals(0, r.getDirectives().size());
+ }
+
+ private static class TestResource implements Resource {
+ @Override
+ public List<Capability> getCapabilities(String namespace) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Requirement> getRequirements(String namespace) {
+ return Collections.emptyList();
+ }
+ }
+}
diff --git a/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java b/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java
index f990aec..ca27cf5 100644
--- a/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java
+++ b/src/test/java/org/apache/sling/feature/process/FeatureBuilderTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,13 +30,15 @@ import java.util.Map;
import org.apache.sling.feature.Artifact;
import org.apache.sling.feature.ArtifactId;
import org.apache.sling.feature.BundlesTest;
-import org.apache.sling.feature.Capability;
import org.apache.sling.feature.Configuration;
import org.apache.sling.feature.Extension;
import org.apache.sling.feature.Feature;
import org.apache.sling.feature.Include;
-import org.apache.sling.feature.Requirement;
+import org.apache.sling.feature.OSGiCapability;
+import org.apache.sling.feature.OSGiRequirement;
import org.junit.Test;
+import org.osgi.resource.Capability;
+import org.osgi.resource.Requirement;
public class FeatureBuilderTest {
@@ -193,18 +196,19 @@ public class FeatureBuilderTest {
@Test public void testNoIncludesNoUpgrade() throws Exception {
final Feature base = new Feature(ArtifactId.parse("org.apache.sling/test-feature/1.1"));
- final Requirement r1 = new Requirement("osgi.contract");
- r1.getDirectives().put("filter", "(&(osgi.contract=JavaServlet)(version=3.1))");
+ final Requirement r1 = new OSGiRequirement("osgi.contract",
+ Collections.emptyMap(), Collections.singletonMap("filter", "(&(osgi.contract=JavaServlet)(version=3.1))"));
base.getRequirements().add(r1);
- final Capability c1 = new Capability("osgi.implementation");
- c1.getAttributes().put("osgi.implementation", "osgi.http");
- c1.getAttributes().put("version:Version", "1.1");
- c1.getDirectives().put("uses", "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard");
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put("osgi.implementation", "osgi.http");
+ attrs.put("version:Version", "1.1");
+ final Capability c1 = new OSGiCapability("osgi.implementation", attrs,
+ Collections.singletonMap("uses", "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"));
base.getCapabilities().add(c1);
- final Capability c2 = new Capability("osgi.service");
- c2.getAttributes().put("objectClass:List<String>", "org.osgi.service.http.runtime.HttpServiceRuntime");
- c2.getDirectives().put("uses", "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto");
+ final Capability c2 = new OSGiCapability("osgi.service",
+ Collections.singletonMap("objectClass:List<String>", "org.osgi.service.http.runtime.HttpServiceRuntime"),
+ Collections.singletonMap("uses", "org.osgi.service.http.runtime,org.osgi.service.http.runtime.dto"));
base.getCapabilities().add(c2);
base.getFrameworkProperties().put("foo", "1");
@@ -241,14 +245,15 @@ public class FeatureBuilderTest {
final Include i1 = new Include(ArtifactId.parse("g/a/1"));
base.getIncludes().add(i1);
- final Requirement r1 = new Requirement("osgi.contract");
- r1.getDirectives().put("filter", "(&(osgi.contract=JavaServlet)(version=3.1))");
+ final Requirement r1 = new OSGiRequirement("osgi.contract",
+ Collections.emptyMap(), Collections.singletonMap("filter", "(&(osgi.contract=JavaServlet)(version=3.1))"));
base.getRequirements().add(r1);
- final Capability c1 = new Capability("osgi.implementation");
- c1.getAttributes().put("osgi.implementation", "osgi.http");
- c1.getAttributes().put("version:Version", "1.1");
- c1.getDirectives().put("uses", "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard");
+ Map<String, Object> attrs = new HashMap<>();
+ attrs.put("osgi.implementation", "osgi.http");
+ attrs.put("version:Version", "1.1");
+ final Capability c1 = new OSGiCapability("osgi.implementation", attrs,
+ Collections.singletonMap("uses", "javax.servlet,javax.servlet.http,org.osgi.service.http.context,org.osgi.service.http.whiteboard"));
base.getCapabilities().add(c1);
base.getFrameworkProperties().put("foo", "1");
--
To stop receiving notification emails like this one, please contact
davidb@apache.org.