You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by da...@apache.org on 2021/08/25 15:22:56 UTC

[felix-dev] branch master updated: Add support for variables

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/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 5e30c21  Add support for variables
     new 1743e11  Merge pull request #89 from bosschaert/features_impl_1
5e30c21 is described below

commit 5e30c214b8283eb0436896f9db8b95d59102d864
Author: David Bosschaert <da...@apache.org>
AuthorDate: Tue Aug 24 14:56:37 2021 +0100

    Add support for variables
---
 .../feature/impl/ConfigurationBuilderImpl.java     | 13 -----
 .../felix/feature/impl/FeatureBuilderImpl.java     | 12 ++---
 .../felix/feature/impl/FeatureServiceImpl.java     | 62 +++++++++++++++++++---
 .../felix/feature/impl/FeatureServiceImplTest.java | 18 ++++++-
 .../src/test/resources/features/test-feature.json  | 10 ++++
 5 files changed, 88 insertions(+), 27 deletions(-)

diff --git a/features/src/main/java/org/apache/felix/feature/impl/ConfigurationBuilderImpl.java b/features/src/main/java/org/apache/felix/feature/impl/ConfigurationBuilderImpl.java
index 62da552..b9922f1 100644
--- a/features/src/main/java/org/apache/felix/feature/impl/ConfigurationBuilderImpl.java
+++ b/features/src/main/java/org/apache/felix/feature/impl/ConfigurationBuilderImpl.java
@@ -41,19 +41,6 @@ class ConfigurationBuilderImpl implements FeatureConfigurationBuilder {
         this.name = name;
     }
 
-    ConfigurationBuilderImpl(FeatureConfiguration c) {
-        if (c.getFactoryPid() == null) {
-            p = c.getPid();
-            name = null;
-        } else {
-            // TODO
-            p = null;
-            name = null;
-        }
-
-        addValues(c.getValues());
-    }
-
     @Override
     public FeatureConfigurationBuilder addValue(String key, Object value) {
         // TODO can do some validation on the configuration
diff --git a/features/src/main/java/org/apache/felix/feature/impl/FeatureBuilderImpl.java b/features/src/main/java/org/apache/felix/feature/impl/FeatureBuilderImpl.java
index 2f86860..f155822 100644
--- a/features/src/main/java/org/apache/felix/feature/impl/FeatureBuilderImpl.java
+++ b/features/src/main/java/org/apache/felix/feature/impl/FeatureBuilderImpl.java
@@ -47,7 +47,7 @@ class FeatureBuilderImpl implements FeatureBuilder {
     private final List<String> categories = new ArrayList<>();
     private final Map<String,FeatureConfiguration> configurations = new LinkedHashMap<>();
     private final Map<String,FeatureExtension> extensions = new LinkedHashMap<>();
-    private final Map<String,String> variables = new LinkedHashMap<>();
+    private final Map<String,Object> variables = new LinkedHashMap<>();
 
     FeatureBuilderImpl(ID id) {
         this.id = id;
@@ -125,13 +125,13 @@ class FeatureBuilderImpl implements FeatureBuilder {
     }
 
     @Override
-    public FeatureBuilder addVariable(String key, String value) {
+    public FeatureBuilder addVariable(String key, Object value) {
         this.variables.put(key, value);
         return this;
     }
 
     @Override
-    public FeatureBuilder addVariables(Map<String,String> variables) {
+    public FeatureBuilder addVariables(Map<String,Object> variables) {
         this.variables.putAll(variables);
         return this;
     }
@@ -157,11 +157,11 @@ class FeatureBuilderImpl implements FeatureBuilder {
         private final List<String> categories;
         private final Map<String,FeatureConfiguration> configurations;
         private final Map<String,FeatureExtension> extensions;
-        private final Map<String,String> variables;
+        private final Map<String,Object> variables;
 
         private FeatureImpl(ID id, String aName, String desc, String docs, String lic, String sc, String vnd,
                 boolean comp, List<FeatureBundle> bs, List<String> cats, Map<String,FeatureConfiguration> cs,
-                Map<String,FeatureExtension> es, Map<String,String> vars) {
+                Map<String,FeatureExtension> es, Map<String,Object> vars) {
             this.id = id;
             name = Optional.ofNullable(aName);
             description = Optional.ofNullable(desc);
@@ -239,7 +239,7 @@ class FeatureBuilderImpl implements FeatureBuilder {
         }
 
         @Override
-        public Map<String,String> getVariables() {
+        public Map<String,Object> getVariables() {
             return variables;
         }
 
diff --git a/features/src/main/java/org/apache/felix/feature/impl/FeatureServiceImpl.java b/features/src/main/java/org/apache/felix/feature/impl/FeatureServiceImpl.java
index 10dc999..e34b2ef 100644
--- a/features/src/main/java/org/apache/felix/feature/impl/FeatureServiceImpl.java
+++ b/features/src/main/java/org/apache/felix/feature/impl/FeatureServiceImpl.java
@@ -37,6 +37,7 @@ import javax.json.JsonString;
 import javax.json.JsonValue;
 import javax.json.stream.JsonGenerator;
 import javax.json.stream.JsonGeneratorFactory;
+import javax.print.DocFlavor.STRING;
 
 import org.apache.felix.cm.json.impl.JsonSupport;
 import org.apache.felix.cm.json.impl.TypeConverter;
@@ -94,9 +95,9 @@ public class FeatureServiceImpl implements FeatureService {
         builder.setLicense(json.getString("license", null));
         builder.setSCM(json.getString("scm", null));
         builder.setVendor(json.getString("vendor", null));
-
         builder.setComplete(json.getBoolean("complete", false));
 
+        builder.addVariables(getVariables(json));
         builder.addBundles(getBundles(json));
         builder.addCategories(getCategories(json));
         builder.addConfigurations(getConfigurations(json));
@@ -105,7 +106,43 @@ public class FeatureServiceImpl implements FeatureService {
         return builder.build();
     }
 
-    private FeatureBundle[] getBundles(JsonObject json) {
+    private Map<String, Object> getVariables(JsonObject json) {
+		Map<String, Object> variables = new LinkedHashMap<>();
+		
+    	JsonObject jo = json.getJsonObject("variables");
+    	if (jo == null)
+    		return Collections.emptyMap();
+    	
+    	for (Map.Entry<String, JsonValue> entry : jo.entrySet()) {
+    		Object value;
+    		
+    		JsonValue val = entry.getValue();
+			switch (val.getValueType()) {
+			case STRING:
+				value = ((JsonString) val).getString();
+				break;
+			case NUMBER:
+				value = ((JsonNumber) val).bigDecimalValue();
+				break;
+			case TRUE:
+				value = true;
+				break;
+			case FALSE:
+				value = false;
+				break;
+			case NULL:
+				value = null;
+				break;
+			default:
+				throw new IllegalArgumentException("Variables can only contain singular values, not objects or arrays.");
+    		}
+			
+			variables.put(entry.getKey(), value);
+    	}
+		return variables;
+	}
+
+	private FeatureBundle[] getBundles(JsonObject json) {
         JsonArray ja = json.getJsonArray("bundles");
         if (ja == null)
             return new FeatureBundle[] {};
@@ -297,6 +334,11 @@ public class FeatureServiceImpl implements FeatureService {
     	
 		JsonObjectBuilder json = Json.createObjectBuilder(attrs);
 
+		JsonObject variables = getVariables(feature);
+		if (variables != null) {
+			json.add("variables", variables);
+		}
+
 		JsonArray bundles = getBundles(feature);
 		if (bundles != null) {
 			json.add("bundles", bundles);
@@ -311,10 +353,7 @@ public class FeatureServiceImpl implements FeatureService {
 		if (extensions != null) {
 			json.add("extensions", extensions);
 		}
-		
-		// TODO add variables
-		// TODO add frameworkproperties
-		
+
 		JsonObject fo = json.build();
 		
 		JsonGeneratorFactory gf = Json.createGeneratorFactory(Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, true));
@@ -323,6 +362,17 @@ public class FeatureServiceImpl implements FeatureService {
 		}
     }
 
+	private JsonObject getVariables(Feature feature) {
+		Map<String,Object> vars = feature.getVariables();
+		
+		if (vars == null || vars.size() == 0) {
+			return null;
+		}
+		
+		JsonObjectBuilder jo = Json.createObjectBuilder(vars);
+		return jo.build();
+	}
+
 	private JsonArray getBundles(Feature feature) {
 		List<FeatureBundle> bundles = feature.getBundles();
 		if (bundles == null || bundles.size() == 0)
diff --git a/features/src/test/java/org/apache/felix/feature/impl/FeatureServiceImplTest.java b/features/src/test/java/org/apache/felix/feature/impl/FeatureServiceImplTest.java
index 9b2334b..e2e2927 100644
--- a/features/src/test/java/org/apache/felix/feature/impl/FeatureServiceImplTest.java
+++ b/features/src/test/java/org/apache/felix/feature/impl/FeatureServiceImplTest.java
@@ -19,6 +19,7 @@ package org.apache.felix.feature.impl;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
@@ -26,6 +27,7 @@ import java.io.InputStreamReader;
 import java.io.Reader;
 import java.io.StringReader;
 import java.io.StringWriter;
+import java.math.BigDecimal;
 import java.net.URL;
 import java.util.List;
 import java.util.Map;
@@ -34,7 +36,6 @@ import javax.json.Json;
 import javax.json.JsonObject;
 import javax.json.JsonReader;
 
-import org.apache.felix.feature.impl.FeatureServiceImpl;
 import org.junit.Before;
 import org.junit.Test;
 import org.osgi.service.feature.BuilderFactory;
@@ -71,6 +72,13 @@ public class FeatureServiceImplTest {
             assertFalse(f.getSCM().isPresent());
             assertFalse(f.getVendor().isPresent());
 
+            Map<String, Object> variables = f.getVariables();
+            assertEquals(3, variables.size());
+            assertEquals("jack", variables.get("user.name"));
+            assertTrue(variables.containsKey("user.pwd"));
+            assertNull(variables.get("user.pwd"));
+            assertEquals(BigDecimal.valueOf(999), variables.get("threads"));
+            
             List<FeatureBundle> bundles = f.getBundles();
             assertEquals(3, bundles.size());
 
@@ -87,7 +95,7 @@ public class FeatureServiceImplTest {
             assertTrue(bundles.contains(bf.newBundleBuilder(features.getID("org.slf4j", "slf4j-simple", "1.7.29")).build()));
             
             Map<String, FeatureConfiguration> configs = f.getConfigurations();
-            assertEquals(2, configs.size());
+            assertEquals(3, configs.size());
             
             FeatureConfiguration cfg1 = configs.get("my.pid");
             assertEquals("my.pid", cfg1.getPid());
@@ -104,6 +112,12 @@ public class FeatureServiceImplTest {
             Map<String, Object> values2 = cfg2.getValues();
             assertEquals(1, values2.size());
             assertArrayEquals(new String[] {"yeah", "yeah", "yeah"}, (String[]) values2.get("a.value"));
+            
+            FeatureConfiguration cfg3 = configs.get("my.db.cfg");
+            assertEquals("No variable substitution should yet be taking place", 
+            		"${user.name}", cfg3.getValues().get("user-name"));
+            assertEquals("No variable substitution should yet be taking place", 
+            		"${user.pwd}", cfg3.getValues().get("user-pwd"));
         }
 
         testWriteFeature(f, res);
diff --git a/features/src/test/resources/features/test-feature.json b/features/src/test/resources/features/test-feature.json
index 323fb79..b650d8b 100644
--- a/features/src/test/resources/features/test-feature.json
+++ b/features/src/test/resources/features/test-feature.json
@@ -1,6 +1,12 @@
 {
     "id" : "org.apache.sling:test-feature:1.1",
     "description": "The feature description",
+    
+    "variables": {
+      "user.name": "jack",
+      "user.pwd": null,
+      "threads": 999
+    },
 
     "bundles" :[
             {
@@ -23,6 +29,10 @@
         },
         "my.factory.pid~name" : {
            "a.value" : ["yeah", "yeah", "yeah"]
+        },
+        "my.db.cfg": {
+          "user-name": "${user.name}",
+          "user-pwd": "${user.pwd}"
         }
     }
 }
\ No newline at end of file