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/18 16:50:38 UTC
[sling-whiteboard] branch master updated: Initial Extension
Handling, WIP
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 19aa12a Initial Extension Handling, WIP
19aa12a is described below
commit 19aa12ae184ed646877b560355fa07ad48dacdd5
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Wed Dec 18 16:49:34 2019 +0000
Initial Extension Handling, WIP
---
.../src/main/java/org/osgi/feature/Extension.java | 3 ++
.../src/main/java/org/osgi/feature/Feature.java | 2 +
.../org/osgi/feature/builder/ExtensionBuilder.java | 15 ++++--
.../org/osgi/feature/builder/FeatureBuilder.java | 21 +++++++-
.../org/osgi/feature/impl/FeatureServiceImpl.java | 62 +++++++++++++++++++++-
.../osgi/feature/impl/FeatureServiceImplTest.java | 27 ++++++++++
.../src/test/resources/features/test-exfeat1.json | 18 +++++++
.../src/test/resources/features/test-exfeat2.json | 10 ++++
8 files changed, 151 insertions(+), 7 deletions(-)
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/Extension.java b/osgi-featuremodel/src/main/java/org/osgi/feature/Extension.java
index 9309c46..ab2ca1d 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/Extension.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/Extension.java
@@ -19,12 +19,15 @@ package org.osgi.feature;
import java.util.List;
public interface Extension {
+ enum Kind { MANDATORY, OPTIONAL, TRANSIENT };
enum Type { JSON, TEXT, ARTIFACTS };
String getName();
Type getType();
+ Kind getKind();
+
String getJSON();
String getText();
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/Feature.java b/osgi-featuremodel/src/main/java/org/osgi/feature/Feature.java
index f041817..8c8a1ad 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/Feature.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/Feature.java
@@ -38,6 +38,8 @@ public interface Feature extends Artifact {
Map<String, Configuration> getConfigurations();
+ Map<String, Extension> getExtensions();
+
Map<String, String> getVariables();
// add prototype
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java
index a2ef848..e93fb3e 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java
@@ -18,6 +18,7 @@ package org.osgi.feature.builder;
import org.osgi.feature.ArtifactID;
import org.osgi.feature.Extension;
+import org.osgi.feature.Extension.Kind;
import org.osgi.feature.Extension.Type;
import java.io.BufferedReader;
@@ -30,12 +31,14 @@ import java.util.Objects;
public class ExtensionBuilder {
private final String name;
private final Type type;
+ private final Kind kind;
private final StringBuilder content = new StringBuilder();
- public ExtensionBuilder(String name, Type type) {
+ public ExtensionBuilder(String name, Type type, Kind kind) {
this.name = name;
this.type = type;
+ this.kind = kind;
}
public ExtensionBuilder addText(String text) {
@@ -90,17 +93,19 @@ public class ExtensionBuilder {
}
public Extension build() {
- return new ExtensionImpl(name, type, content.toString());
+ return new ExtensionImpl(name, type, kind, content.toString());
}
private static class ExtensionImpl implements Extension {
private final String name;
private final Type type;
+ private final Kind kind;
private final String content;
- private ExtensionImpl(String name, Type type, String content) {
+ private ExtensionImpl(String name, Type type, Kind kind, String content) {
this.name = name;
this.type = type;
+ this.kind = kind;
this.content = content;
}
@@ -112,6 +117,10 @@ public class ExtensionBuilder {
return type;
}
+ public Kind getKind() {
+ return kind;
+ }
+
public String getJSON() {
if (type != Type.JSON)
throw new IllegalStateException("Extension is not of type JSON " + type);
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilder.java
index f2b0e77..56f3b4c 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilder.java
@@ -19,6 +19,7 @@ package org.osgi.feature.builder;
import org.osgi.feature.ArtifactID;
import org.osgi.feature.Bundle;
import org.osgi.feature.Configuration;
+import org.osgi.feature.Extension;
import org.osgi.feature.Feature;
import java.util.ArrayList;
@@ -42,6 +43,7 @@ public class FeatureBuilder {
private final List<Bundle> bundles = new ArrayList<>();
private final Map<String,Configuration> configurations = new HashMap<>();
+ private final Map<String,Extension> extensions = new HashMap<>();
private final Map<String,String> variables = new HashMap<>();
public FeatureBuilder(ArtifactID id) {
@@ -95,6 +97,13 @@ public class FeatureBuilder {
return this;
}
+ public FeatureBuilder addExtensions(Extension ... extensions) {
+ for (Extension ex : extensions) {
+ this.extensions.put(ex.getName(), ex);
+ }
+ return this;
+ }
+
public FeatureBuilder addVariable(String key, String value) {
this.variables.put(key, value);
return this;
@@ -108,7 +117,7 @@ public class FeatureBuilder {
public Feature build() {
return new FeatureImpl(id, title,
description, vendor, license, location, complete, isFinal,
- bundles, configurations, variables);
+ bundles, configurations, extensions, variables);
}
private static class FeatureImpl extends ArtifactImpl implements Feature {
@@ -122,10 +131,12 @@ public class FeatureBuilder {
private final List<Bundle> bundles;
private final Map<String,Configuration> configurations;
+ private final Map<String,Extension> extensions;
private final Map<String,String> variables;
private FeatureImpl(ArtifactID id, String aTitle, String desc, String vnd, String lic, String loc,
- boolean comp, boolean fin, List<Bundle> bs, Map<String,Configuration> cs, Map<String,String> vars) {
+ boolean comp, boolean fin, List<Bundle> bs, Map<String,Configuration> cs,
+ Map<String,Extension> es, Map<String,String> vars) {
super(id);
title = aTitle;
@@ -138,6 +149,7 @@ public class FeatureBuilder {
bundles = Collections.unmodifiableList(bs);
configurations = Collections.unmodifiableMap(cs);
+ extensions = Collections.unmodifiableMap(es);
variables = Collections.unmodifiableMap(vars);
}
@@ -187,6 +199,11 @@ public class FeatureBuilder {
}
@Override
+ public Map<String,Extension> getExtensions() {
+ return extensions;
+ }
+
+ @Override
public Map<String,String> getVariables() {
return variables;
}
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 cbd4645..b2d23d2 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
@@ -19,11 +19,13 @@ package org.osgi.feature.impl;
import org.osgi.feature.ArtifactID;
import org.osgi.feature.Bundle;
import org.osgi.feature.Configuration;
+import org.osgi.feature.Extension;
import org.osgi.feature.Feature;
import org.osgi.feature.FeatureService;
import org.osgi.feature.MergeContext;
import org.osgi.feature.builder.BundleBuilder;
import org.osgi.feature.builder.ConfigurationBuilder;
+import org.osgi.feature.builder.ExtensionBuilder;
import org.osgi.feature.builder.FeatureBuilder;
import java.io.IOException;
@@ -62,14 +64,18 @@ public class FeatureServiceImpl implements FeatureService {
builder.addBundles(getBundles(json));
builder.addConfigurations(getConfigurations(json));
+ builder.addExtensions(getExtensions(json));
return builder.build();
}
private Bundle[] getBundles(JsonObject json) {
+ JsonArray ja = json.getJsonArray("bundles");
+ if (ja == null)
+ return new Bundle[] {};
+
List<Bundle> bundles = new ArrayList<>();
- JsonArray ja = json.getJsonArray("bundles");
for (JsonValue val : ja) {
if (val.getValueType() == JsonValue.ValueType.OBJECT) {
JsonObject jo = val.asJsonObject();
@@ -103,9 +109,12 @@ public class FeatureServiceImpl implements FeatureService {
}
private Configuration[] getConfigurations(JsonObject json) {
+ JsonObject jo = json.getJsonObject("configurations");
+ if (jo == null)
+ return new Configuration[] {};
+
List<Configuration> configs = new ArrayList<>();
- JsonObject jo = json.getJsonObject("configurations");
for (Map.Entry<String, JsonValue> entry : jo.entrySet()) {
String p = entry.getKey();
@@ -154,6 +163,55 @@ public class FeatureServiceImpl implements FeatureService {
return configs.toArray(new Configuration[] {});
}
+ private Extension[] getExtensions(JsonObject json) {
+ JsonArray ja = json.getJsonArray("extensions");
+ if (ja == null)
+ return new Extension[] {};
+
+ List<Extension> extensions = new ArrayList<>();
+
+ for (JsonValue ex : ja) {
+ for (Map.Entry<String,JsonValue> entry : ex.asJsonObject().entrySet()) {
+ JsonObject exData = entry.getValue().asJsonObject();
+ Extension.Type type;
+ if (exData.containsKey("text")) {
+ type = Extension.Type.TEXT;
+ } else if (exData.containsKey("artifacts")) {
+ type = Extension.Type.ARTIFACTS;
+ } else if (exData.containsKey("json")) {
+ type = Extension.Type.JSON;
+ } else {
+ throw new IllegalStateException("Invalid extension: " + entry);
+ }
+ String k = exData.getString("kind", "optional");
+ Extension.Kind kind = Extension.Kind.valueOf(k.toUpperCase());
+
+ ExtensionBuilder builder = new ExtensionBuilder(entry.getKey(), type, kind);
+
+ switch (type) {
+ case TEXT:
+ builder.addText(exData.getString("text"));
+ break;
+ case ARTIFACTS:
+ JsonArray ja2 = exData.getJsonArray("artifacts");
+ for (JsonValue jv : ja2) {
+ if (jv.getValueType() == JsonValue.ValueType.STRING) {
+ String id = ((JsonString) jv).getString();
+ builder.addArtifact(ArtifactID.fromMavenID(id));
+ }
+ }
+ break;
+ case JSON:
+ exData.getJsonObject("json").toString();
+ break;
+ }
+ extensions.add(builder.build());
+ }
+ }
+
+ return extensions.toArray(new Extension[] {});
+ }
+
@Override
public void writeFeature(Feature feature, Writer jsonWriter) throws IOException {
// TODO Auto-generated method stub
diff --git a/osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java b/osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java
index 79c922d..bce29e3 100644
--- a/osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java
+++ b/osgi-featuremodel/src/test/java/org/osgi/feature/impl/FeatureServiceImplTest.java
@@ -20,6 +20,7 @@ import org.junit.Test;
import org.osgi.feature.ArtifactID;
import org.osgi.feature.Bundle;
import org.osgi.feature.Configuration;
+import org.osgi.feature.Extension;
import org.osgi.feature.Feature;
import org.osgi.feature.FeatureService;
import org.osgi.feature.MergeContext;
@@ -121,4 +122,30 @@ public class FeatureServiceImplTest {
expected.put("number:Integer", 7L); // this is wrong TODO
assertEquals(expected, cfg2.getValues());
}
+
+ @Test
+ public void testMergeExtensions() throws IOException {
+ FeatureService fs = new FeatureServiceImpl();
+
+ URL res1 = getClass().getResource("/features/test-exfeat1.json");
+ Feature f1;
+ try (Reader r = new InputStreamReader(res1.openStream())) {
+ f1 = fs.readFeature(r);
+ }
+
+ URL res2 = getClass().getResource("/features/test-exfeat2.json");
+ Feature f2;
+ try (Reader r = new InputStreamReader(res2.openStream())) {
+ f2 = fs.readFeature(r);
+ }
+
+ MergeContext ctx = new MergeContextBuilder().build();
+
+ ArtifactID tid = new ArtifactID("g", "a", "1.2.3");
+ Feature f3 = fs.mergeFeatures(tid, f1, f2, ctx);
+
+ Map<String, Extension> extensions = f3.getExtensions();
+ assertEquals(3, extensions.size());
+ assertEquals("ABCDEF", extensions.get("my-text-ex").getText());
+ }
}
diff --git a/osgi-featuremodel/src/test/resources/features/test-exfeat1.json b/osgi-featuremodel/src/test/resources/features/test-exfeat1.json
new file mode 100644
index 0000000..4d22abd
--- /dev/null
+++ b/osgi-featuremodel/src/test/resources/features/test-exfeat1.json
@@ -0,0 +1,18 @@
+{
+ "id" : "org.apache.sling:test-extension-feature:1.0.0",
+ "extensions" : [
+ { "my-text-ex": {
+ "kind": "optional",
+ "text": "ABC" }
+ },
+ { "my-art-ex": {
+ "artifacts": ["g:a:1", "g:a:2"],
+ "kind": "mandatory"
+ }
+ },
+ { "my-json-ex": {
+ "kind": "transient",
+ "json": {"foo": [1, 2, 3] }}
+ }
+ ]
+}
\ No newline at end of file
diff --git a/osgi-featuremodel/src/test/resources/features/test-exfeat2.json b/osgi-featuremodel/src/test/resources/features/test-exfeat2.json
new file mode 100644
index 0000000..7db40bb
--- /dev/null
+++ b/osgi-featuremodel/src/test/resources/features/test-exfeat2.json
@@ -0,0 +1,10 @@
+{
+ "id" : "org.apache.sling:test-extension-feature2:1.0.0",
+ "extensions" : [
+ { "my-text-ex":
+ {
+ "text": "DEF"
+ }
+ }
+ ]
+}
\ No newline at end of file