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

commit 7934b9fe2b398c98543f66afb6ec644677b83948
Author: David Bosschaert <[email protected]>
AuthorDate: Mon Oct 1 21:45:41 2018 +0100

    Transformation for features service
---
 .../feature/launcher/impl/FeatureProcessor.java    | 44 ++++++++++++++--------
 .../sling/feature/launcher/impl/Installation.java  | 14 +++++++
 .../launcher/impl/launchers/AbstractRunner.java    | 14 ++++++-
 .../launcher/impl/launchers/FrameworkLauncher.java | 19 +++++-----
 .../launcher/impl/launchers/FrameworkRunner.java   |  9 ++++-
 .../feature/launcher/spi/LauncherRunContext.java   |  6 +++
 6 files changed, 79 insertions(+), 27 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 2e77570..0a3a437 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
@@ -16,19 +16,6 @@
  */
 package org.apache.sling.feature.launcher.impl;
 
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.ServiceLoader;
-import java.util.Spliterator;
-import java.util.Spliterators;
-import java.util.stream.StreamSupport;
-
 import org.apache.sling.feature.Artifact;
 import org.apache.sling.feature.ArtifactId;
 import org.apache.sling.feature.Configuration;
@@ -43,9 +30,21 @@ import org.apache.sling.feature.io.ArtifactHandler;
 import org.apache.sling.feature.io.ArtifactManager;
 import org.apache.sling.feature.io.IOUtils;
 import org.apache.sling.feature.io.json.FeatureJSONReader;
+import org.apache.sling.feature.io.json.FeatureJSONWriter;
 import org.apache.sling.feature.launcher.spi.LauncherPrepareContext;
 import org.apache.sling.feature.launcher.spi.extensions.ExtensionHandler;
 
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+
 public class FeatureProcessor {
 
     /**
@@ -57,6 +56,17 @@ public class FeatureProcessor {
     public static Feature createApplication(final LauncherConfig config,
             final ArtifactManager artifactManager) throws IOException
     {
+        List<FeatureExtensionHandler> extensionHandlers = new ArrayList<>();
+        for (FeatureExtensionHandler feh : 
ServiceLoader.load(FeatureExtensionHandler.class)) {
+            feh.initialize(a -> {
+                try {
+                    return 
artifactManager.getArtifactHandler(a.getId().toMvnUrl()).getFile();
+                } catch (IOException ioe) {
+                    throw new RuntimeException(ioe);
+                }
+            });
+            extensionHandlers.add(feh);
+        }
 
         final BuilderContext builderContext = new BuilderContext(
             id -> {
@@ -71,8 +81,8 @@ public class FeatureProcessor {
                     // ignore
                 }
                 return null;
-            }, config.getVariables(), 
config.getInstallation().getFrameworkProperties()).add(StreamSupport.stream(Spliterators.spliteratorUnknownSize(
-            ServiceLoader.load(FeatureExtensionHandler.class).iterator(), 
Spliterator.ORDERED), false).toArray(FeatureExtensionHandler[]::new));
+            }, config.getVariables(), 
config.getInstallation().getFrameworkProperties())
+                .add(extensionHandlers.toArray(new FeatureExtensionHandler[] 
{}));
 
         List<Feature> features = new ArrayList<>();
 
@@ -141,6 +151,10 @@ public class FeatureProcessor {
             }
         }
 
+        StringWriter featureStringWriter = new StringWriter();
+        FeatureJSONWriter.write(featureStringWriter, app);
+        
config.getInstallation().setEffectiveFeature(featureStringWriter.toString());
+
         extensions: for(final Extension ext : app.getExtensions()) {
             for (ExtensionHandler handler : 
ServiceLoader.load(ExtensionHandler.class,  
FeatureProcessor.class.getClassLoader()))
             {
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 3f08856..560b6e2 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
@@ -46,6 +46,9 @@ public class Installation implements LauncherRunContext, 
ExtensionInstallationCo
     /** The list of app jars. */
     private final List<File> appJars = new ArrayList<>();
 
+    /** The effective, merged feature used to launch. */
+    private String effectiveFeature;
+
     /**
      * Add an application jar.
      * @param jar The application jar
@@ -132,6 +135,16 @@ public class Installation implements LauncherRunContext, 
ExtensionInstallationCo
         return this.installables;
     }
 
+    @Override
+    public String getEffectiveFeature() {
+        return effectiveFeature;
+    }
+
+    public void setEffectiveFeature(String featureJsonText) {
+        effectiveFeature = featureJsonText;
+    }
+
+
     /**
      * Clear all in-memory objects
      */
@@ -140,5 +153,6 @@ public class Installation implements LauncherRunContext, 
ExtensionInstallationCo
         this.fwkProperties.clear();
         this.bundleMap.clear();
         this.installables.clear();
+        this.effectiveFeature = null;
     }
 }
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 f532a2c..0530919 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
@@ -16,7 +16,9 @@
  */
 package org.apache.sling.feature.launcher.impl.launchers;
 
+import org.apache.sling.feature.launcher.impl.FeaturesServiceImpl;
 import org.apache.sling.feature.launcher.impl.Main;
+import org.apache.sling.feature.service.Features;
 import org.apache.sling.launchpad.api.LaunchpadContentProvider;
 import org.apache.sling.launchpad.api.StartupHandler;
 import org.apache.sling.launchpad.api.StartupMode;
@@ -100,7 +102,8 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
         }
     }
 
-    protected void setupFramework(final Framework framework, final 
Map<Integer, List<File>> bundlesMap)
+    protected void setupFramework(final Framework framework, final 
Map<Integer, List<File>> bundlesMap,
+            String effectiveFeature)
     throws BundleException {
         if ( !configurations.isEmpty() ) {
             this.configAdminTracker = new 
ServiceTracker<>(framework.getBundleContext(),
@@ -274,6 +277,15 @@ public abstract class AbstractRunner implements 
Callable<Integer> {
         } catch (NoClassDefFoundError ex) {
             // Ignore, we don't have the launchpad.api
         }
+
+        // Register the feature service asynchronously
+        new Thread(() -> registerFeaturesService(effectiveFeature, 
framework)).start();
+    }
+
+    // This method is run asynchronously
+    private void registerFeaturesService(String effectiveFeature, Framework 
framework) {
+        Features featuresService = new FeaturesServiceImpl(effectiveFeature);
+        framework.getBundleContext().registerService(Features.class, 
featuresService, null);
     }
 
     protected boolean startFramework(final Framework framework, long timeout, 
TimeUnit unit) throws BundleException, InterruptedException
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 fb2dac2..f6d9d72 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
@@ -16,13 +16,6 @@
  */
 package org.apache.sling.feature.launcher.impl.launchers;
 
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Callable;
-
 import org.apache.commons.lang.text.StrLookup;
 import org.apache.commons.lang.text.StrSubstitutor;
 import org.apache.sling.feature.Artifact;
@@ -34,6 +27,13 @@ import 
org.apache.sling.feature.launcher.spi.LauncherPrepareContext;
 import org.apache.sling.feature.launcher.spi.LauncherRunContext;
 import org.osgi.framework.Constants;
 
+import java.io.File;
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Callable;
+
 /**
  * Launcher directly using the OSGi launcher API.
  */
@@ -111,12 +111,13 @@ 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, String.class);
         constructor.setAccessible(true);
         Callable<Integer> restart = (Callable<Integer>) 
constructor.newInstance(properties,
                 context.getBundleMap(),
                 context.getConfigurations(),
-                context.getInstallableArtifacts());
+                context.getInstallableArtifacts(),
+                context.getEffectiveFeature());
 
         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..55c750c 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,9 +39,14 @@ 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 {
+            final List<File> installables,
+            final String effectiveFeature) throws Exception {
         super(frameworkProperties, configurations, installables);
 
+        /* */
+        System.out.println("*** Effective Feature ***" + effectiveFeature);
+        /* */
+
         final ServiceLoader<FrameworkFactory> loader = 
ServiceLoader.load(FrameworkFactory.class);
         FrameworkFactory factory = null;
         for(FrameworkFactory f : loader) {
@@ -78,7 +83,7 @@ public class FrameworkRunner extends AbstractRunner {
             }
         });
 
-        this.setupFramework(framework, bundlesMap);
+        this.setupFramework(framework, bundlesMap, effectiveFeature);
 
 
         long time = System.currentTimeMillis();
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..061355a 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();
+
+    /**
+     * Obtain the effective Feature JSON
+     * @return The effective Feature JSON as a String.
+     */
+    String getEffectiveFeature();
 }

Reply via email to