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 2019/12/16 16:57:15 UTC
[sling-whiteboard] branch master updated: Merging of Features
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-whiteboard.git
The following commit(s) were added to refs/heads/master by this push:
new 5d71e62 Merging of Features
5d71e62 is described below
commit 5d71e628db66fe71a12628189f47b94bb2709e6e
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Mon Dec 16 16:56:50 2019 +0000
Merging of Features
---
.../src/main/java/org/osgi/feature/Artifact.java | 2 +-
.../src/main/java/org/osgi/feature/ArtifactID.java | 10 +++++
.../src/main/java/org/osgi/feature/Bundle.java | 7 ++-
.../main/java/org/osgi/feature/FeatureService.java | 3 +-
.../feature/{Artifact.java => MergeContext.java} | 29 ++----------
.../osgi/feature/builder/MergeContextBuilder.java | 41 +++++++++++++++++
.../org/osgi/feature/impl/FeatureServiceImpl.java | 51 ++++++++++++++++++++--
.../feature/impl}/FeatureServiceImplTest.java | 36 ++++++++++++++-
.../src/test/resources/features/test-feature2.json | 15 +++++++
9 files changed, 162 insertions(+), 32 deletions(-)
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java b/osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java
index 2841726..3a9085f 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java
@@ -25,7 +25,7 @@ public class Artifact {
this.id = id;
}
- public ArtifactID getId() {
+ public ArtifactID getID() {
return id;
}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/ArtifactID.java b/osgi-featuremodel/src/main/java/org/osgi/feature/ArtifactID.java
index bad55a5..3a2a8c3 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/ArtifactID.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/ArtifactID.java
@@ -40,6 +40,10 @@ public class ArtifactID {
return new ArtifactID(gid, aid, ver, t, c);
}
+ public ArtifactID(String groupId, String artifactId, String version) {
+ this(groupId, artifactId, version, null, null);
+ }
+
public ArtifactID(String groupId, String artifactId, String version, String type, String classifier) {
this.groupId = groupId;
this.artifactId = artifactId;
@@ -84,4 +88,10 @@ public class ArtifactID {
&& Objects.equals(groupId, other.groupId) && Objects.equals(type, other.type)
&& Objects.equals(version, other.version);
}
+
+ @Override
+ public String toString() {
+ return "ArtifactID [groupId=" + groupId + ", artifactId=" + artifactId + ", version=" + version + ", type=" + type
+ + ", classifier=" + classifier + "]";
+ }
}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/Bundle.java b/osgi-featuremodel/src/main/java/org/osgi/feature/Bundle.java
index f80acee..735f27d 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/Bundle.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/Bundle.java
@@ -54,6 +54,11 @@ public class Bundle extends Artifact {
return Objects.equals(metadata, other.metadata);
}
+ @Override
+ public String toString() {
+ return "Bundle [metadata=" + metadata + ", getID()=" + getID() + "]";
+ }
+
public static class Builder {
private final ArtifactID id;
@@ -64,7 +69,7 @@ public class Bundle extends Artifact {
}
public Builder(String groupId, String artifactId, String version) {
- this(new ArtifactID(groupId, artifactId, version, null, null));
+ this(new ArtifactID(groupId, artifactId, version));
}
public Builder addMetadata(String key, Object value) {
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/FeatureService.java b/osgi-featuremodel/src/main/java/org/osgi/feature/FeatureService.java
index d1102cf..01e9862 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/FeatureService.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/FeatureService.java
@@ -37,5 +37,6 @@ public interface FeatureService {
*/
void writeFeature(Feature feature, Writer jsonWriter) throws IOException;
- Feature mergeFeatures(Feature f1, Feature f2);
+
+ Feature mergeFeatures(ArtifactID targetID, Feature f1, Feature f2, MergeContext ctx);
}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java b/osgi-featuremodel/src/main/java/org/osgi/feature/MergeContext.java
similarity index 59%
copy from osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java
copy to osgi-featuremodel/src/main/java/org/osgi/feature/MergeContext.java
index 2841726..f45fbb5 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/Artifact.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/MergeContext.java
@@ -16,31 +16,10 @@
*/
package org.osgi.feature;
-import java.util.Objects;
+import java.util.List;
-public class Artifact {
- private final ArtifactID id;
+public interface MergeContext {
+ List<Bundle> resolveBundles(Bundle b1, Bundle b2);
- protected Artifact(ArtifactID id) {
- this.id = id;
- }
-
- public ArtifactID getId() {
- return id;
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(id);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!(obj instanceof Artifact))
- return false;
- Artifact other = (Artifact) obj;
- return Objects.equals(id, other.id);
- }
+ Configuration resolveConfigurations(Configuration c1, Configuration c2);
}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilder.java
new file mode 100644
index 0000000..b0b2472
--- /dev/null
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilder.java
@@ -0,0 +1,41 @@
+package org.osgi.feature.builder;
+
+import org.osgi.feature.Bundle;
+import org.osgi.feature.Configuration;
+import org.osgi.feature.MergeContext;
+
+import java.util.List;
+import java.util.function.BiFunction;
+
+public class MergeContextBuilder {
+ private BiFunction<Bundle, Bundle, List<Bundle>> bundleResolver;
+
+ public MergeContextBuilder setBundleResolver(BiFunction<Bundle, Bundle, List<Bundle>> bf) {
+ bundleResolver = bf;
+ return this;
+ }
+
+ public MergeContext build() {
+ return new MergeContextImpl(bundleResolver);
+ }
+
+ private static class MergeContextImpl implements MergeContext {
+ private BiFunction<Bundle, Bundle, List<Bundle>> bundleResolver;
+
+ private MergeContextImpl(BiFunction<Bundle, Bundle, List<Bundle>> bundleResolver) {
+ this.bundleResolver = bundleResolver;
+ }
+
+ @Override
+ public List<Bundle> resolveBundles(Bundle b1, Bundle b2) {
+ return bundleResolver.apply(b1, b2);
+ }
+
+ @Override
+ public Configuration resolveConfigurations(Configuration c1, Configuration c2) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ }
+}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java b/osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java
index 2e5a61f..859fdac 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java
@@ -21,11 +21,13 @@ import org.osgi.feature.Bundle;
import org.osgi.feature.Feature;
import org.osgi.feature.Feature.Builder;
import org.osgi.feature.FeatureService;
+import org.osgi.feature.MergeContext;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
import java.util.ArrayList;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -102,9 +104,52 @@ public class FeatureServiceImpl implements FeatureService {
}
@Override
- public Feature mergeFeatures(Feature f1, Feature f2) {
- // TODO Auto-generated method stub
- return null;
+ public Feature mergeFeatures(ArtifactID targetID, Feature f1, Feature f2, MergeContext ctx) {
+
+ Builder fb = new Feature.Builder(targetID);
+
+ copyAttrs(f1, fb);
+ copyAttrs(f2, fb);
+
+ List<Bundle> bundles = resolveBundles(f1, f2, ctx);
+ fb.addBundles(bundles.toArray(new Bundle[0]));
+
+ return fb.build();
}
+ private List<Bundle> resolveBundles(Feature f1, Feature f2, MergeContext ctx) {
+ List<Bundle> bundles = new ArrayList<>(f1.getBundles());
+ List<Bundle> addedBundles = new ArrayList<>();
+
+ for (Bundle b : f2.getBundles()) {
+ ArtifactID bID = b.getID();
+ for (Iterator<Bundle> it = bundles.iterator(); it.hasNext(); ) {
+ Bundle orgb = it.next();
+ ArtifactID orgID = orgb.getID();
+
+ if (bID.getGroupId().equals(orgID.getGroupId()) &&
+ bID.getArtifactId().equals(orgID.getArtifactId())) {
+ List<Bundle> res = new ArrayList<>(ctx.resolveBundles(b, orgb));
+ if (res.contains(orgb)) {
+ res.remove(orgb);
+ } else {
+ it.remove();
+ }
+ addedBundles.addAll(res);
+ }
+ }
+ }
+ return bundles;
+ }
+
+ private void copyAttrs(Feature f, Builder fb) {
+ fb.setTitle(f.getTitle());
+ fb.setDescription(f.getDescription());
+ fb.setVendor(f.getVendor());
+ fb.setLicense(f.getLicense());
+ fb.setLocation(f.getLocation());
+
+ }
+
+
}
diff --git a/osgi-featuremodel/src/test/java/org/apache/sling/feature/osgi/FeatureServiceImplTest.java b/osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java
similarity index 64%
rename from osgi-featuremodel/src/test/java/org/apache/sling/feature/osgi/FeatureServiceImplTest.java
rename to osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java
index b5e4b4f..f416a05 100644
--- a/osgi-featuremodel/src/test/java/org/apache/sling/feature/osgi/FeatureServiceImplTest.java
+++ b/osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java
@@ -14,18 +14,22 @@
* License for the specific language governing permissions and limitations under
* the License.
*/
-package org.apache.sling.feature.osgi;
+package org.osgi.feature.impl;
import org.junit.Test;
+import org.osgi.feature.ArtifactID;
import org.osgi.feature.Bundle;
import org.osgi.feature.Feature;
import org.osgi.feature.FeatureService;
+import org.osgi.feature.MergeContext;
+import org.osgi.feature.builder.MergeContextBuilder;
import org.osgi.feature.impl.FeatureServiceImpl;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
+import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
@@ -60,4 +64,34 @@ public class FeatureServiceImplTest {
assertTrue(bundles.contains(new Bundle.Builder("org.slf4j", "slf4j-simple", "1.7.29").build()));
}
}
+
+ @Test
+ public void testMergeFeatures() throws IOException {
+ FeatureService fs = new FeatureServiceImpl();
+
+ URL res1 = getClass().getResource("/features/test-feature.json");
+ Feature f1;
+ try (Reader r = new InputStreamReader(res1.openStream())) {
+ f1 = fs.readFeature(r);
+ }
+
+ URL res2 = getClass().getResource("/features/test-feature.json");
+ Feature f2;
+ try (Reader r = new InputStreamReader(res2.openStream())) {
+ f2 = fs.readFeature(r);
+ }
+
+ MergeContext ctx = new MergeContextBuilder()
+ .setBundleResolver((b1, b2) -> Arrays.asList(b1, b2))
+ .build();
+ ArtifactID tid = new ArtifactID("foo", "bar", "1.2.3");
+ Feature f3 = fs.mergeFeatures(tid, f1, f2, ctx);
+ assertEquals(tid, f3.getID());
+
+ List<Bundle> bundles = f3.getBundles();
+ assertEquals(4, bundles.size());
+
+ assertTrue(bundles.contains(new Bundle.Builder("org.slf4j", "slf4j-api", "1.7.29").build()));
+ assertTrue(bundles.contains(new Bundle.Builder("org.slf4j", "slf4j-api", "1.7.30").build()));
+ }
}
diff --git a/osgi-featuremodel/src/test/resources/features/test-feature2.json b/osgi-featuremodel/src/test/resources/features/test-feature2.json
new file mode 100644
index 0000000..3c3400c
--- /dev/null
+++ b/osgi-featuremodel/src/test/resources/features/test-feature2.json
@@ -0,0 +1,15 @@
+{
+ "id" : "org.apache.sling:test-feature2:1.1",
+ "description": "The feature description",
+
+ "bundles" :[
+ {
+ "id" : "org.slf4j:slf4j-api:1.7.30"
+ }
+ ],
+ "configurations" : {
+ "my.pid" : {
+ "bar" : "toast"
+ }
+ }
+}
\ No newline at end of file