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 2020/01/06 12:49:42 UTC

[sling-whiteboard] branch master updated: Refactor the builders to be obtainable from the Feature Service

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 2b0b1cd  Refactor the builders to be obtainable from the Feature Service
2b0b1cd is described below

commit 2b0b1cdb7103d6591ee812cc4c29697a7b075cae
Author: David Bosschaert <da...@gmail.com>
AuthorDate: Mon Jan 6 12:48:02 2020 +0000

    Refactor the builders to be obtainable from the Feature Service
    
    Initial approach for the Bundle Builder
---
 .../main/java/org/osgi/feature/BuilderFactory.java | 21 +++++++++++++++
 .../main/java/org/osgi/feature/BundleBuilder.java  | 30 +++++++++++++++++++++
 .../main/java/org/osgi/feature/FeatureService.java |  6 +++++
 .../osgi/feature/builder/BuilderFactoryImpl.java   | 30 +++++++++++++++++++++
 .../{BundleBuilder.java => BundleBuilderImpl.java} | 10 ++++---
 ...nBuilder.java => ConfigurationBuilderImpl.java} | 12 ++++-----
 ...nsionBuilder.java => ExtensionBuilderImpl.java} | 14 +++++-----
 ...FeatureBuilder.java => FeatureBuilderImpl.java} | 28 +++++++++----------
 .../{impl => builder}/FeatureServiceImpl.java      | 27 ++++++++++---------
 ...xtBuilder.java => MergeContextBuilderImpl.java} |  8 +++---
 .../osgi/feature/impl/FeatureServiceImplTest.java  | 31 ++++++++++++----------
 11 files changed, 156 insertions(+), 61 deletions(-)

diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/BuilderFactory.java b/osgi-featuremodel/src/main/java/org/osgi/feature/BuilderFactory.java
new file mode 100644
index 0000000..2618e97
--- /dev/null
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/BuilderFactory.java
@@ -0,0 +1,21 @@
+/*
+ * 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.osgi.feature;
+
+public interface BuilderFactory {
+    BundleBuilder newBundleBuilder(ArtifactID id);
+}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/BundleBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/BundleBuilder.java
new file mode 100644
index 0000000..0e2185e
--- /dev/null
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/BundleBuilder.java
@@ -0,0 +1,30 @@
+/*
+ * 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.osgi.feature;
+
+
+import java.util.Map;
+
+public interface BundleBuilder {
+
+    BundleBuilder addMetadata(String key, Object value);
+
+    BundleBuilder addMetadata(Map<String, Object> md);
+
+    Bundle build();
+
+}
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 3051e3c..16439bf 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/FeatureService.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/FeatureService.java
@@ -22,6 +22,12 @@ import java.io.Writer;
 
 public interface FeatureService {
     /**
+     *
+     * @return
+     */
+    BuilderFactory getBuilderFactory();
+
+    /**
      * Read a Feature from JSON
      * @param jsonReader A Reader to the JSON input
      * @return The Feature represented by the JSON
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BuilderFactoryImpl.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BuilderFactoryImpl.java
new file mode 100644
index 0000000..f1f7bfa
--- /dev/null
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BuilderFactoryImpl.java
@@ -0,0 +1,30 @@
+/*
+ * 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.osgi.feature.builder;
+
+import org.osgi.feature.ArtifactID;
+import org.osgi.feature.BuilderFactory;
+import org.osgi.feature.BundleBuilder;
+
+class BuilderFactoryImpl implements BuilderFactory {
+
+    @Override
+    public BundleBuilder newBundleBuilder(ArtifactID id) {
+        return new BundleBuilderImpl(id);
+    }
+
+}
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BundleBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BundleBuilderImpl.java
similarity index 91%
rename from osgi-featuremodel/src/main/java/org/osgi/feature/builder/BundleBuilder.java
rename to osgi-featuremodel/src/main/java/org/osgi/feature/builder/BundleBuilderImpl.java
index 0466f14..a61e224 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BundleBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/BundleBuilderImpl.java
@@ -18,31 +18,35 @@ package org.osgi.feature.builder;
 
 import org.osgi.feature.ArtifactID;
 import org.osgi.feature.Bundle;
+import org.osgi.feature.BundleBuilder;
 
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-public class BundleBuilder {
+class BundleBuilderImpl implements BundleBuilder {
     private final ArtifactID id;
 
     private final Map<String,Object> metadata = new HashMap<>();
 
-    public BundleBuilder(ArtifactID id) {
+    BundleBuilderImpl(ArtifactID id) {
         this.id = id;
     }
 
+    @Override
     public BundleBuilder addMetadata(String key, Object value) {
         this.metadata.put(key, value);
         return this;
     }
 
+    @Override
     public BundleBuilder addMetadata(Map<String,Object> md) {
         this.metadata.putAll(md);
         return this;
     }
 
+    @Override
     public Bundle build() {
         return new BundleImpl(id, metadata);
     }
@@ -50,7 +54,7 @@ public class BundleBuilder {
     private static class BundleImpl extends ArtifactImpl implements Bundle {
         private final Map<String, Object> metadata;
 
-        public BundleImpl(ArtifactID id, Map<String, Object> metadata) {
+        private BundleImpl(ArtifactID id, Map<String, Object> metadata) {
             super(id);
 
             this.metadata = Collections.unmodifiableMap(metadata);
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ConfigurationBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ConfigurationBuilderImpl.java
similarity index 90%
rename from osgi-featuremodel/src/main/java/org/osgi/feature/builder/ConfigurationBuilder.java
rename to osgi-featuremodel/src/main/java/org/osgi/feature/builder/ConfigurationBuilderImpl.java
index dd8aebe..b34f3b2 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ConfigurationBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ConfigurationBuilderImpl.java
@@ -23,23 +23,23 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
 
-public class ConfigurationBuilder {
+public class ConfigurationBuilderImpl {
     private final String p;
     private final String name;
 
     private final Map<String,Object> values = new HashMap<>();
 
-    public ConfigurationBuilder(String pid) {
+    public ConfigurationBuilderImpl(String pid) {
         this.p = pid;
         this.name = null;
     }
 
-    public ConfigurationBuilder(String factoryPid, String name) {
+    public ConfigurationBuilderImpl(String factoryPid, String name) {
         this.p = factoryPid;
         this.name = name;
     }
 
-    public ConfigurationBuilder(Configuration c) {
+    public ConfigurationBuilderImpl(Configuration c) {
         if (c.getFactoryPid() == null) {
             p = c.getPid();
             name = null;
@@ -52,13 +52,13 @@ public class ConfigurationBuilder {
         addValues(c.getValues());
     }
 
-    public ConfigurationBuilder addValue(String key, Object value) {
+    public ConfigurationBuilderImpl addValue(String key, Object value) {
         // TODO can do some validation on the configuration
         this.values.put(key, value);
         return this;
     }
 
-    public ConfigurationBuilder addValues(Map<String, Object> cfg) {
+    public ConfigurationBuilderImpl addValues(Map<String, Object> cfg) {
         // TODO can do some validation on the configuration
         this.values.putAll(cfg);
         return this;
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilderImpl.java
similarity index 90%
rename from osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java
rename to osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilderImpl.java
index 7864ad5..479ee71 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/ExtensionBuilderImpl.java
@@ -28,20 +28,20 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
 
-public class ExtensionBuilder {
+public class ExtensionBuilderImpl {
     private final String name;
     private final Type type;
     private final Kind kind;
 
     private final StringBuilder content = new StringBuilder();
 
-    public ExtensionBuilder(String name, Type type, Kind kind) {
+    public ExtensionBuilderImpl(String name, Type type, Kind kind) {
         this.name = name;
         this.type = type;
         this.kind = kind;
     }
 
-    public ExtensionBuilder addText(String text) {
+    public ExtensionBuilderImpl addText(String text) {
         if (type != Type.TEXT)
             throw new IllegalStateException("Cannot add text to extension of type " + type);
 
@@ -49,7 +49,7 @@ public class ExtensionBuilder {
         return this;
     }
 
-    public ExtensionBuilder setJSON(String json) {
+    public ExtensionBuilderImpl setJSON(String json) {
         if (type != Type.JSON)
             throw new IllegalStateException("Cannot add text to extension of type " + type);
 
@@ -58,16 +58,16 @@ public class ExtensionBuilder {
         return this;
     }
 
-    public ExtensionBuilder addArtifact(ArtifactID aid) {
+    public ExtensionBuilderImpl addArtifact(ArtifactID aid) {
         addArtifact(aid.getGroupId(), aid.getArtifactId(), aid.getVersion(), aid.getType(), aid.getClassifier());
         return this;
     }
 
-    public ExtensionBuilder addArtifact(String groupId, String artifactId, String version) {
+    public ExtensionBuilderImpl addArtifact(String groupId, String artifactId, String version) {
         return addArtifact(groupId, artifactId, version, null, null);
     }
 
-    public ExtensionBuilder addArtifact(String groupId, String artifactId, String version, String at, String classifier) {
+    public ExtensionBuilderImpl addArtifact(String groupId, String artifactId, String version, String at, String classifier) {
         if (type != Type.ARTIFACTS)
             throw new IllegalStateException("Cannot add artifacts to extension of type " + 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/FeatureBuilderImpl.java
similarity index 88%
rename from osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilder.java
rename to osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilderImpl.java
index 56f3b4c..10de8a1 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureBuilderImpl.java
@@ -30,7 +30,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 
-public class FeatureBuilder {
+public class FeatureBuilderImpl {
     private final ArtifactID id;
 
     private String title;
@@ -46,70 +46,70 @@ public class FeatureBuilder {
     private final Map<String,Extension> extensions = new HashMap<>();
     private final Map<String,String> variables = new HashMap<>();
 
-    public FeatureBuilder(ArtifactID id) {
+    public FeatureBuilderImpl(ArtifactID id) {
         this.id = id;
     }
 
-    public FeatureBuilder setTitle(String title) {
+    public FeatureBuilderImpl setTitle(String title) {
         this.title = title;
         return this;
     }
 
-    public FeatureBuilder setVendor(String vendor) {
+    public FeatureBuilderImpl setVendor(String vendor) {
         this.vendor = vendor;
         return this;
     }
 
-    public FeatureBuilder setLicense(String license) {
+    public FeatureBuilderImpl setLicense(String license) {
         this.license = license;
         return this;
     }
 
-    public FeatureBuilder setLocation(String location) {
+    public FeatureBuilderImpl setLocation(String location) {
         this.location = location;
         return this;
     }
 
-    public FeatureBuilder setComplete(boolean complete) {
+    public FeatureBuilderImpl setComplete(boolean complete) {
         this.complete = complete;
         return this;
     }
 
-    public FeatureBuilder setFinal(boolean isFinal) {
+    public FeatureBuilderImpl setFinal(boolean isFinal) {
         this.isFinal = isFinal;
         return this;
     }
 
-    public FeatureBuilder setDescription(String description) {
+    public FeatureBuilderImpl setDescription(String description) {
         this.description = description;
         return this;
     }
 
-    public FeatureBuilder addBundles(Bundle ... bundles) {
+    public FeatureBuilderImpl addBundles(Bundle ... bundles) {
         this.bundles.addAll(Arrays.asList(bundles));
         return this;
     }
 
-    public FeatureBuilder addConfigurations(Configuration ... configs) {
+    public FeatureBuilderImpl addConfigurations(Configuration ... configs) {
         for (Configuration cfg : configs) {
             this.configurations.put(cfg.getPid(), cfg);
         }
         return this;
     }
 
-    public FeatureBuilder addExtensions(Extension ... extensions) {
+    public FeatureBuilderImpl addExtensions(Extension ... extensions) {
         for (Extension ex : extensions) {
             this.extensions.put(ex.getName(), ex);
         }
         return this;
     }
 
-    public FeatureBuilder addVariable(String key, String value) {
+    public FeatureBuilderImpl addVariable(String key, String value) {
         this.variables.put(key, value);
         return this;
     }
 
-    public FeatureBuilder addVariables(Map<String,String> variables) {
+    public FeatureBuilderImpl addVariables(Map<String,String> variables) {
         this.variables.putAll(variables);
         return this;
     }
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureServiceImpl.java
similarity index 93%
rename from osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java
rename to osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureServiceImpl.java
index e0aebf0..0462f9e 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/impl/FeatureServiceImpl.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/FeatureServiceImpl.java
@@ -14,19 +14,16 @@
  * License for the specific language governing permissions and limitations under
  * the License.
  */
-package org.osgi.feature.impl;
+package org.osgi.feature.builder;
 
 import org.osgi.feature.ArtifactID;
+import org.osgi.feature.BuilderFactory;
 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;
 import java.io.Reader;
@@ -45,13 +42,17 @@ import javax.json.JsonString;
 import javax.json.JsonValue;
 
 public class FeatureServiceImpl implements FeatureService {
+    @Override
+    public BuilderFactory getBuilderFactory() {
+        return new BuilderFactoryImpl();
+    }
 
     @Override
     public Feature readFeature(Reader jsonReader) throws IOException {
         JsonObject json = Json.createReader(jsonReader).readObject();
 
         String id = json.getString("id");
-        FeatureBuilder builder = new FeatureBuilder(ArtifactID.fromMavenID(id));
+        FeatureBuilderImpl builder = new FeatureBuilderImpl(ArtifactID.fromMavenID(id));
 
         builder.setTitle(json.getString("title", null));
         builder.setDescription(json.getString("description", null));
@@ -80,7 +81,7 @@ public class FeatureServiceImpl implements FeatureService {
             if (val.getValueType() == JsonValue.ValueType.OBJECT) {
                 JsonObject jo = val.asJsonObject();
                 String bid = jo.getString("id");
-                BundleBuilder builder = new BundleBuilder(ArtifactID.fromMavenID(bid));
+                BundleBuilderImpl builder = new BundleBuilderImpl(ArtifactID.fromMavenID(bid));
 
                 for (Map.Entry<String, JsonValue> entry : jo.entrySet()) {
                     if (entry.getKey().equals("id"))
@@ -125,11 +126,11 @@ public class FeatureServiceImpl implements FeatureService {
                 p = p.substring(idx + 1);
             }
 
-            ConfigurationBuilder builder;
+            ConfigurationBuilderImpl builder;
             if (factoryPid == null) {
-                builder = new ConfigurationBuilder(p);
+                builder = new ConfigurationBuilderImpl(p);
             } else {
-                builder = new ConfigurationBuilder(factoryPid, p);
+                builder = new ConfigurationBuilderImpl(factoryPid, p);
             }
 
             JsonObject values = entry.getValue().asJsonObject();
@@ -185,7 +186,7 @@ public class FeatureServiceImpl implements FeatureService {
             String k = exData.getString("kind", "optional");
             Extension.Kind kind = Extension.Kind.valueOf(k.toUpperCase());
 
-            ExtensionBuilder builder = new ExtensionBuilder(entry.getKey(), type, kind);
+            ExtensionBuilderImpl builder = new ExtensionBuilderImpl(entry.getKey(), type, kind);
 
             switch (type) {
             case TEXT:
@@ -219,7 +220,7 @@ public class FeatureServiceImpl implements FeatureService {
     @Override
     public Feature mergeFeatures(ArtifactID targetID, Feature f1, Feature f2, MergeContext ctx) {
 
-        FeatureBuilder fb = new FeatureBuilder(targetID);
+        FeatureBuilderImpl fb = new FeatureBuilderImpl(targetID);
 
         copyAttrs(f1, fb);
         copyAttrs(f2, fb);
@@ -308,7 +309,7 @@ public class FeatureServiceImpl implements FeatureService {
         return extensions.values().toArray(new Extension[] {});
     }
 
-    private void copyAttrs(Feature f, FeatureBuilder fb) {
+    private void copyAttrs(Feature f, FeatureBuilderImpl fb) {
         if (f.getTitle() != null)
             fb.setTitle(f.getTitle());
 
diff --git a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilder.java b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilderImpl.java
similarity index 89%
rename from osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilder.java
rename to osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilderImpl.java
index 31dac73..f8b9807 100644
--- a/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilder.java
+++ b/osgi-featuremodel/src/main/java/org/osgi/feature/builder/MergeContextBuilderImpl.java
@@ -25,22 +25,22 @@ import org.osgi.feature.MergeContext;
 
 import java.util.List;
 
-public class MergeContextBuilder {
+public class MergeContextBuilderImpl {
     private ConflictResolver<Bundle, List<Bundle>> bundleHandler;
     private ConflictResolver<Configuration, Configuration> configHandler;
     private ConflictResolver<Extension, Extension> extensionHandler;
 
-    public MergeContextBuilder bundleConflictHandler(ConflictResolver<Bundle, List<Bundle>> bh) {
+    public MergeContextBuilderImpl bundleConflictHandler(ConflictResolver<Bundle, List<Bundle>> bh) {
         bundleHandler = bh;
         return this;
     }
 
-    public MergeContextBuilder configConflictHandler(ConflictResolver<Configuration, Configuration> ch) {
+    public MergeContextBuilderImpl configConflictHandler(ConflictResolver<Configuration, Configuration> ch) {
         configHandler = ch;
         return this;
     }
 
-    public MergeContextBuilder extensionConflictHandler(ConflictResolver<Extension, Extension> eh) {
+    public MergeContextBuilderImpl extensionConflictHandler(ConflictResolver<Extension, Extension> eh) {
         extensionHandler = eh;
         return this;
     }
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 91e819a..0598c5a 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
@@ -18,16 +18,17 @@ package org.osgi.feature.impl;
 
 import org.junit.Test;
 import org.osgi.feature.ArtifactID;
+import org.osgi.feature.BuilderFactory;
 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.MergeContextBuilder;
+import org.osgi.feature.builder.ConfigurationBuilderImpl;
+import org.osgi.feature.builder.ExtensionBuilderImpl;
+import org.osgi.feature.builder.FeatureServiceImpl;
+import org.osgi.feature.builder.MergeContextBuilderImpl;
 
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -47,6 +48,7 @@ public class FeatureServiceImplTest {
     @Test
     public void testReadFeature() throws IOException {
         FeatureService fs = new FeatureServiceImpl();
+        BuilderFactory bf = fs.getBuilderFactory();
 
         URL res = getClass().getResource("/features/test-feature.json");
         try (Reader r = new InputStreamReader(res.openStream())) {
@@ -58,7 +60,7 @@ public class FeatureServiceImplTest {
             List<Bundle> bundles = f.getBundles();
             assertEquals(3, bundles.size());
 
-            Bundle bundle = new BundleBuilder(new ArtifactID("org.osgi", "osgi.promise", "7.0.1"))
+            Bundle bundle = bf.newBundleBuilder(new ArtifactID("org.osgi", "osgi.promise", "7.0.1"))
                     .addMetadata("hash", "4632463464363646436")
                     .addMetadata("start-order", 1L)
                     .build();
@@ -67,14 +69,15 @@ public class FeatureServiceImplTest {
             ba.equals(bundle);
 
             assertTrue(bundles.contains(bundle));
-            assertTrue(bundles.contains(new BundleBuilder(new ArtifactID("org.slf4j", "slf4j-api", "1.7.29")).build()));
-            assertTrue(bundles.contains(new BundleBuilder(new ArtifactID("org.slf4j", "slf4j-simple", "1.7.29")).build()));
+            assertTrue(bundles.contains(bf.newBundleBuilder(new ArtifactID("org.slf4j", "slf4j-api", "1.7.29")).build()));
+            assertTrue(bundles.contains(bf.newBundleBuilder(new ArtifactID("org.slf4j", "slf4j-simple", "1.7.29")).build()));
         }
     }
 
     @Test
     public void testMergeFeatures() throws IOException {
         FeatureService fs = new FeatureServiceImpl();
+        BuilderFactory bf = fs.getBuilderFactory();
 
         URL res1 = getClass().getResource("/features/test-feature.json");
         Feature f1;
@@ -88,9 +91,9 @@ public class FeatureServiceImplTest {
             f2 = fs.readFeature(r);
         }
 
-        MergeContext ctx = new MergeContextBuilder()
+        MergeContext ctx = new MergeContextBuilderImpl()
                 .bundleConflictHandler((cf1, b1, cf2, b2) -> Arrays.asList(b1, b2))
-                .configConflictHandler((cf1, c1, cf2, c2) -> new ConfigurationBuilder(c1)
+                .configConflictHandler((cf1, c1, cf2, c2) -> new ConfigurationBuilderImpl(c1)
                         .addValues(c2.getValues()).build())
                 .build();
 
@@ -102,9 +105,9 @@ public class FeatureServiceImplTest {
         List<Bundle> bundles = f3.getBundles();
         assertEquals(5, bundles.size());
 
-        assertTrue(bundles.contains(new BundleBuilder(new ArtifactID("org.slf4j", "slf4j-api", "1.7.29")).build()));
-        assertTrue(bundles.contains(new BundleBuilder(new ArtifactID("org.slf4j", "slf4j-api", "1.7.30")).build()));
-        assertTrue(bundles.contains(new BundleBuilder(new ArtifactID("org.slf4j", "slf4j-nop", "1.7.30")).build()));
+        assertTrue(bundles.contains(bf.newBundleBuilder(new ArtifactID("org.slf4j", "slf4j-api", "1.7.29")).build()));
+        assertTrue(bundles.contains(bf.newBundleBuilder(new ArtifactID("org.slf4j", "slf4j-api", "1.7.30")).build()));
+        assertTrue(bundles.contains(bf.newBundleBuilder(new ArtifactID("org.slf4j", "slf4j-nop", "1.7.30")).build()));
 
         Map<String, Configuration> configs = f3.getConfigurations();
         assertEquals(2, configs.size());
@@ -140,9 +143,9 @@ public class FeatureServiceImplTest {
             f2 = fs.readFeature(r);
         }
 
-        MergeContext ctx = new MergeContextBuilder()
+        MergeContext ctx = new MergeContextBuilderImpl()
                 .extensionConflictHandler((cf1, e1, cf2, e2) ->
-                    new ExtensionBuilder(e1.getName(), e1.getType(), e1.getKind())
+                    new ExtensionBuilderImpl(e1.getName(), e1.getType(), e1.getKind())
                         .addText(e1.getText())
                         .addText(e2.getText())
                         .build())