This is an automated email from the ASF dual-hosted git repository.

davidb pushed a commit to branch features-service
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-feature-launcher.git


The following commit(s) were added to refs/heads/features-service by this push:
     new 734180e  Make the launcher capable of configuring additional services
734180e is described below

commit 734180e2d7e137cf34e66dc5bcfc495a7d5ee994
Author: David Bosschaert <[email protected]>
AuthorDate: Thu Jul 12 22:18:59 2018 +0200

    Make the launcher capable of configuring additional services
---
 .../feature/launcher/impl/FeatureProcessor.java    | 100 ++-------------------
 .../sling/feature/launcher/impl/Installation.java  |   9 ++
 .../apache/sling/feature/launcher/impl/Main.java   |   1 +
 .../launcher/impl/launchers/AbstractRunner.java    |  28 +++++-
 .../launcher/impl/launchers/FrameworkLauncher.java |   6 +-
 .../launcher/impl/launchers/FrameworkRunner.java   |   5 +-
 .../feature/launcher/spi/LauncherRunContext.java   |   6 ++
 7 files changed, 55 insertions(+), 100 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java 
b/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
index 123f957..053f7d0 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/FeatureProcessor.java
@@ -27,33 +27,22 @@ import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.json.ApplicationJSONReader;
 import org.apache.sling.feature.io.json.ApplicationJSONWriter;
 import org.apache.sling.feature.launcher.impl.LauncherConfig.StartupMode;
-import org.osgi.framework.Constants;
-import org.osgi.util.converter.Converter;
-import org.osgi.util.converter.Converters;
 
 import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.Dictionary;
-import java.util.Hashtable;
 import java.util.List;
 import java.util.Map;
-import java.util.jar.Attributes;
-import java.util.jar.JarFile;
-import java.util.stream.Collectors;
 
 import javax.json.Json;
 import javax.json.JsonArray;
 import javax.json.JsonObject;
 import javax.json.JsonReader;
-import javax.json.JsonValue;
-import javax.json.JsonValue.ValueType;
 
 public class FeatureProcessor {
-    private static final String FEATURES_SERVICE_PID = 
"org.apache.sling.feature.service.impl.FeaturesServiceImpl";
+    private static final String FEATURES_SERVICE_FACTORY = 
"org.apache.sling.feature.service.FeaturesFactory";
     private static final String WHITELIST_ENFORCER_PID = 
"org.apache.sling.feature.whitelist.impl.WhitelistEnforcer";
 
     /**
@@ -107,44 +96,14 @@ public class FeatureProcessor {
     public static void prepareLauncher(final LauncherConfig config,
             final ArtifactManager artifactManager,
             final Application app) throws Exception {
-        Dictionary<String, Object> bundleFeatureMap = new Hashtable<>();
-        Converter converter = Converters.standardConverter();
-
-        List<String> featureIDs =
-                app.getFeatureIds().stream().map(i -> 
i.toMvnId()).collect(Collectors.toList());
-
         for(final Map.Entry<Integer, List<Artifact>> entry : 
app.getBundles().getBundlesByStartOrder().entrySet()) {
             for(final Artifact a : entry.getValue()) {
                 final ArtifactHandler handler = 
artifactManager.getArtifactHandler(":" + a.getId().toMvnPath());
                 final File artifactFile = handler.getFile();
 
-                String bsn = getBsn(artifactFile);
                 config.getInstallation().addBundle(entry.getKey(), 
artifactFile);
-
-                String ff = a.getMetadata().get("from-feature");
-                if (ff != null) {
-                    String[] fl = ff.split(",");
-                    Object cfg = null;
-                    if (fl.length != 1) {
-                        List<String> fids = new ArrayList<>();
-                        for(String foid : fl) {
-                            int fidx = converter.convert(foid).to(int.class);
-                            if (featureIDs.size() > fidx) {
-                                fids.add(featureIDs.get(fidx));
-                            }
-                        }
-                        cfg = fids;
-                    } else {
-                        int fidx = converter.convert(fl[0]).to(int.class);
-                        if (featureIDs.size() > fidx) {
-                            cfg = featureIDs.get(fidx);
-                        }
-                    }
-                    bundleFeatureMap.put(bsn, cfg);
-                }
             }
         }
-        config.getInstallation().addConfiguration(FEATURES_SERVICE_PID, null, 
bundleFeatureMap);
 
         int index = 1;
         for(final Extension ext : app.getExtensions()) {
@@ -182,51 +141,13 @@ public class FeatureProcessor {
                     index++;
                     cfg.getProperties().put("scripts", text);
                     config.getInstallation().addConfiguration(cfg.getName(), 
cfg.getFactoryPid(), cfg.getProperties());
-            } else if ( 
ext.getName().equals(FeatureConstants.EXTENSION_NAME_API_REGION) ) {
-                Dictionary<String, List<String>> whitelistConfiguration = new 
Hashtable<>();
+            } else if ( ext.getName().equals("bundle-feature-mapping") ) {
                 try (JsonReader reader = Json.createReader(new 
StringReader(ext.getJSON()))) {
-                    JsonArray array = reader.readArray();
-                    for (JsonValue jv : array) {
-                        if (jv instanceof JsonObject) {
-                            JsonObject jo = (JsonObject) jv;
-                            String name = jo.getString("name");
-                            String featureIdx = jo.getString("from-feature");
-                            JsonArray exports = jo.getJsonArray("exports");
 
-                            int fidx = 
converter.convert(featureIdx).to(int.class);
-                            if (featureIDs.size() > fidx) {
-                                String featureID = featureIDs.get(fidx);
-                                if (featureID != null) {
-                                    String featureKey = "whitelist.feature." + 
featureID;
-                                    List<String> regions = 
whitelistConfiguration.get(featureKey);
-                                    if (regions == null) {
-                                        regions = new ArrayList<>();
-                                        whitelistConfiguration.put(featureKey, 
regions);
-                                    }
-                                    if (!regions.contains(name)) {
-                                        regions.add(name);
-                                    }
-                                }
-                            }
-
-                            String packagesKey = "whitelist.region." + name;
-                            List<String> packages = 
whitelistConfiguration.get(packagesKey);
-                            if (packages == null) {
-                                packages = new ArrayList<>();
-                                whitelistConfiguration.put(packagesKey, 
packages);
-                            }
-                            for (JsonValue pkg : exports) {
-                                if (pkg.getValueType() == ValueType.STRING) {
-                                    String p = pkg.toString();
-                                    if (!packages.contains(p)) {
-                                        packages.add(p);
-                                    }
-                                }
-                            }
-                        }
-                    }
+                    JsonArray array = reader.readArray();
+                    JsonObject jo = array.getJsonObject(0);
+                    
config.getInstallation().getAdditionalOptions().put(FEATURES_SERVICE_FACTORY, 
jo);
                 }
-                
config.getInstallation().addConfiguration(WHITELIST_ENFORCER_PID, null, 
whitelistConfiguration);
             } else {
                 if ( ext.isRequired() ) {
                     throw new Exception("Unknown required extension " + 
ext.getName());
@@ -248,15 +169,4 @@ public class FeatureProcessor {
             }
         }
     }
-
-    private static String getBsn(File artifactFile) throws IOException {
-        try (JarFile jf = new JarFile(artifactFile)) {
-            Attributes attrs = jf.getManifest().getMainAttributes();
-            String bsn = attrs.getValue(Constants.BUNDLE_SYMBOLICNAME);
-            String version = attrs.getValue(Constants.BUNDLE_VERSION);
-            if (version == null)
-                version = "0.0.0";
-            return bsn + ":" + version;
-        }
-    }
 }
diff --git 
a/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java 
b/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
index 1f9eafc..54a124f 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Installation.java
@@ -45,6 +45,9 @@ public class Installation implements LauncherRunContext {
     /** The list of app jars. */
     private final List<File> appJars = new ArrayList<>();
 
+    /** Additional options. */
+    private final Map<String, Object> additionalOptions = new HashMap<>();
+
     /**
      * Add an application jar.
      * @param jar The application jar
@@ -125,6 +128,11 @@ public class Installation implements LauncherRunContext {
         return this.installables;
     }
 
+    @Override
+    public Map<String, Object> getAdditionalOptions() {
+        return this.additionalOptions;
+    }
+
     /**
      * Clear all in-memory objects
      */
@@ -133,5 +141,6 @@ public class Installation implements LauncherRunContext {
         this.fwkProperties.clear();
         this.bundleMap.clear();
         this.installables.clear();
+        this.additionalOptions.clear();
     }
 }
diff --git a/src/main/java/org/apache/sling/feature/launcher/impl/Main.java 
b/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
index 7b2c7ca..6c52e8d 100644
--- a/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
+++ b/src/main/java/org/apache/sling/feature/launcher/impl/Main.java
@@ -216,6 +216,7 @@ public class Main {
             launcherConfig.getInstallation().getBundleMap().clear();
             launcherConfig.getInstallation().getConfigurations().clear();
             launcherConfig.getInstallation().getInstallableArtifacts().clear();
+            launcherConfig.getInstallation().getAdditionalOptions().clear();
         }
         try {
             run(launcherConfig);
diff --git 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
index 33781ab..9a3433c 100644
--- 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
+++ 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/AbstractRunner.java
@@ -75,6 +75,8 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
 
     private final List<File> installables;
 
+    private final Map<String, ?> options;
+
     private final int targetStartlevel;
 
     private final AtomicInteger waitRequested = new AtomicInteger(0);
@@ -82,9 +84,10 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
     private volatile boolean install;
 
     public AbstractRunner(final Map<String, String> frameworkProperties, final 
List<Object[]> configurations,
-            final List<File> installables) {
+            final List<File> installables, final Map<String, ?> options) {
         this.configurations = new ArrayList<>(configurations);
         this.installables = installables;
+        this.options = options;
 
         String target = 
frameworkProperties.get(Constants.FRAMEWORK_BEGINNING_STARTLEVEL);
         if (target != null) {
@@ -165,6 +168,29 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
             });
             this.installerTracker.open();
         }
+        for (Map.Entry<String, ?> entry : options.entrySet()) {
+            @SuppressWarnings({ "rawtypes", "unchecked" })
+            ServiceTracker tracker = new 
ServiceTracker(framework.getBundleContext(), entry.getKey(), null) {
+                @Override
+                public Object addingService(ServiceReference reference) {
+                    close(); // Stop tracking additional services
+
+                    Object svc = super.addingService(reference);
+                    for (Method m : svc.getClass().getMethods()) {
+                        if ("initialize".equals(m.getName())) {
+                            try {
+                                m.setAccessible(true);
+                                m.invoke(svc, entry.getValue());
+                            } catch (Exception e) {
+                                throw new RuntimeException("Cannot initialize 
service " + entry.getKey(), e);
+                            }
+                        }
+                    }
+                    return svc;
+                }
+            };
+            tracker.open();
+        }
 
         try {
             this.install(framework, bundlesMap);
diff --git 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
index d5790ee..6db8626 100644
--- 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
+++ 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkLauncher.java
@@ -109,12 +109,14 @@ public class FrameworkLauncher implements Launcher {
         }
 
         final Class<?> runnerClass = 
cl.loadClass(FrameworkRunner.class.getName());
-        final Constructor<?> constructor = 
runnerClass.getDeclaredConstructor(Map.class, Map.class, List.class, 
List.class);
+        final Constructor<?> constructor = runnerClass.getDeclaredConstructor(
+                Map.class, Map.class, List.class, List.class, Map.class);
         constructor.setAccessible(true);
         Callable<Integer> restart = (Callable<Integer>) 
constructor.newInstance(properties,
                 context.getBundleMap(),
                 context.getConfigurations(),
-                context.getInstallableArtifacts());
+                context.getInstallableArtifacts(),
+                context.getAdditionalOptions());
 
         return restart.call();
         // nothing else to do, constructor starts everything
diff --git 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
index 25ce117..7877c7c 100644
--- 
a/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
+++ 
b/src/main/java/org/apache/sling/feature/launcher/impl/launchers/FrameworkRunner.java
@@ -39,8 +39,9 @@ public class FrameworkRunner extends AbstractRunner {
     public FrameworkRunner(final Map<String, String> frameworkProperties,
             final Map<Integer, List<File>> bundlesMap,
             final List<Object[]> configurations,
-            final List<File> installables) throws Exception {
-        super(frameworkProperties, configurations, installables);
+            final List<File> installables,
+            final Map<String, ?> options) throws Exception {
+        super(frameworkProperties, configurations, installables, options);
 
         final ServiceLoader<FrameworkFactory> loader = 
ServiceLoader.load(FrameworkFactory.class);
         FrameworkFactory factory = null;
diff --git 
a/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java 
b/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
index 20c95a9..e2169a0 100644
--- 
a/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
+++ 
b/src/main/java/org/apache/sling/feature/launcher/spi/LauncherRunContext.java
@@ -55,4 +55,10 @@ public interface LauncherRunContext {
      * @return The list of files. The list might be empty.
      */
     List<File> getInstallableArtifacts();
+
+    /**
+     * Additional data used by the launcher
+     * @return The map of additional data
+     */
+    Map<String, Object> getAdditionalOptions();
 }

Reply via email to