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

rmannibucau pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/openwebbeans.git


The following commit(s) were added to refs/heads/master by this push:
     new 05b1d84  [OWB-1370] ensure CdiSeInitializer can be forced to one of 
the impls
05b1d84 is described below

commit 05b1d845ed5200dcecdc1b6052ca364bd58cb435
Author: Romain Manni-Bucau <rmannibu...@gmail.com>
AuthorDate: Sat Feb 20 18:27:59 2021 +0100

    [OWB-1370] ensure CdiSeInitializer can be forced to one of the impls
---
 .../openwebbeans/se/SeInitializerFacade.java       | 184 ++++++++++++++++-----
 1 file changed, 143 insertions(+), 41 deletions(-)

diff --git 
a/webbeans-se/src/main/java/org/apache/openwebbeans/se/SeInitializerFacade.java 
b/webbeans-se/src/main/java/org/apache/openwebbeans/se/SeInitializerFacade.java
index 0d44726..59ec6a3 100644
--- 
a/webbeans-se/src/main/java/org/apache/openwebbeans/se/SeInitializerFacade.java
+++ 
b/webbeans-se/src/main/java/org/apache/openwebbeans/se/SeInitializerFacade.java
@@ -18,122 +18,224 @@
  */
 package org.apache.openwebbeans.se;
 
+import org.apache.webbeans.conversation.DefaultConversationService;
+import org.apache.webbeans.corespi.se.StandaloneContextsService;
+import org.apache.webbeans.lifecycle.StandaloneLifeCycle;
+import org.apache.webbeans.spi.ContainerLifecycle;
+import org.apache.webbeans.spi.ContextsService;
+import org.apache.webbeans.spi.ConversationService;
+
+import javax.annotation.Priority;
 import javax.enterprise.inject.se.SeContainer;
 import javax.enterprise.inject.se.SeContainerInitializer;
 import javax.enterprise.inject.spi.Extension;
 import java.lang.annotation.Annotation;
-import java.util.Iterator;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Map;
-import java.util.Optional;
 import java.util.ServiceLoader;
+import java.util.function.Consumer;
+import java.util.stream.StreamSupport;
+
+import static java.util.Comparator.comparing;
+import static java.util.Optional.ofNullable;
 
 // will allow to plug other impl but reusing most of our logic
 public class SeInitializerFacade extends SeContainerInitializer
 {
-    private final SeContainerInitializer delegate;
+    public final static String PROVIDER = 
SeContainerInitializer.class.getName() + ".provider";
 
-    public SeInitializerFacade()
-    {
-        delegate = 
Optional.of(ServiceLoader.load(SeContainerSelector.class).iterator())
-                .filter(Iterator::hasNext)
-                .map(Iterator::next)
-                .map(SeContainerSelector::find)
-                .orElseGet(OWBInitializer::new);
-    }
+    private final Collection<Consumer<SeContainerInitializer>> initializers = 
new ArrayList<>();
+    private SeContainerInitializer delegate;
 
     @Override
-    public SeContainerInitializer addBeanClasses(Class<?>... classes)
+    public SeContainerInitializer addBeanClasses(final Class<?>... classes)
     {
-        return delegate.addBeanClasses(classes);
+        initializers.add(i -> i.addBeanClasses(classes));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addPackages(Class<?>... packageClasses)
+    public SeContainerInitializer addPackages(final Class<?>... packageClasses)
     {
-        return delegate.addPackages(packageClasses);
+        initializers.add(i -> i.addPackages(packageClasses));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addPackages(boolean scanRecursively, 
Class<?>... packageClasses)
+    public SeContainerInitializer addPackages(final boolean scanRecursively, 
final Class<?>... packageClasses)
     {
-        return delegate.addPackages(scanRecursively, packageClasses);
+        initializers.add(i -> i.addPackages(scanRecursively, packageClasses));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addPackages(Package... packages)
+    public SeContainerInitializer addPackages(final Package... packages)
     {
-        return delegate.addPackages(packages);
+        initializers.add(i -> i.addPackages(packages));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addPackages(boolean scanRecursively, 
Package... packages)
+    public SeContainerInitializer addPackages(final boolean scanRecursively, 
final Package... packages)
     {
-        return delegate.addPackages(scanRecursively, packages);
+        initializers.add(i -> i.addPackages(scanRecursively, packages));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addExtensions(Extension... extensions)
+    public SeContainerInitializer addExtensions(final Extension... extensions)
     {
-        return delegate.addExtensions(extensions);
+        initializers.add(i -> i.addExtensions(extensions));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addExtensions(Class<? extends Extension>... 
extensions)
+    public SeContainerInitializer addExtensions(final Class<? extends 
Extension>... extensions)
     {
-        return delegate.addExtensions(extensions);
+        initializers.add(i -> i.addExtensions(extensions));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer enableInterceptors(Class<?>... 
interceptorClasses)
+    public SeContainerInitializer enableInterceptors(final Class<?>... 
interceptorClasses)
     {
-        return delegate.enableInterceptors(interceptorClasses);
+        initializers.add(i -> i.enableInterceptors(interceptorClasses));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer enableDecorators(Class<?>... 
decoratorClasses)
+    public SeContainerInitializer enableDecorators(final Class<?>... 
decoratorClasses)
     {
-        return delegate.enableDecorators(decoratorClasses);
+        initializers.add(i -> i.enableDecorators(decoratorClasses));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer selectAlternatives(Class<?>... 
alternativeClasses)
+    public SeContainerInitializer selectAlternatives(final Class<?>... 
alternativeClasses)
     {
-        return delegate.selectAlternatives(alternativeClasses);
+        initializers.add(i -> i.selectAlternatives(alternativeClasses));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer selectAlternativeStereotypes(Class<? extends 
Annotation>... alternativeStereotypeClasses)
+    public SeContainerInitializer selectAlternativeStereotypes(final Class<? 
extends Annotation>... alternativeStereotypeClasses)
     {
-        return 
delegate.selectAlternativeStereotypes(alternativeStereotypeClasses);
+        initializers.add(i -> 
i.selectAlternativeStereotypes(alternativeStereotypeClasses));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer addProperty(String key, Object value)
+    public SeContainerInitializer addProperty(final String key, final Object 
value)
     {
-        return delegate.addProperty(key, value);
+        if (PROVIDER.endsWith(key))
+        {
+            delegate = loadProvider(value);
+        }
+        initializers.add(i -> i.addProperty(key, value));
+        return this;
     }
 
     @Override
-    public SeContainerInitializer setProperties(Map<String, Object> properties)
+    public SeContainerInitializer setProperties(final Map<String, Object> 
properties)
     {
-        return delegate.setProperties(properties);
+        if (properties != null && properties.containsKey(PROVIDER))
+        {
+            addProperty(PROVIDER, properties.get(PROVIDER));
+        }
+        initializers.add(i -> i.setProperties(properties));
+        return this;
     }
 
     @Override
     public SeContainerInitializer disableDiscovery()
     {
-        return delegate.disableDiscovery();
+        initializers.add(SeContainerInitializer::disableDiscovery);
+        return this;
     }
 
     @Override
-    public SeContainerInitializer setClassLoader(ClassLoader classLoader)
+    public SeContainerInitializer setClassLoader(final ClassLoader classLoader)
     {
-        return delegate.setClassLoader(classLoader);
+        initializers.add(i -> i.setClassLoader(classLoader));
+        return this;
     }
 
     @Override
     public SeContainer initialize()
     {
-        return delegate.initialize();
+        final SeContainerInitializer initializer = delegate != null ?
+                delegate :
+                
StreamSupport.stream(ServiceLoader.load(SeContainerSelector.class).spliterator(),
 false)
+                        .min(comparing(it -> 
ofNullable(it.getClass().getAnnotation(Priority.class))
+                                .map(Priority::value)
+                                .orElse(0)))
+                        .map(SeContainerSelector::find)
+                        .orElseGet(OWBInitializer::new);
+        initializers.forEach(i -> i.accept(initializer));
+        return initializer.initialize();
+    }
+
+    private SeContainerInitializer loadProvider(final Object value)
+    {
+        if (SeContainerInitializer.class.isInstance(value))
+        {
+            return SeContainerInitializer.class.cast(value);
+        }
+        if (Class.class.isInstance(value))
+        {
+            return 
newInitializerInstance(Class.class.cast(value).asSubclass(SeContainerInitializer.class));
+        }
+        return newInitializerInstance(findClass(String.valueOf(value)));
+    }
+
+    private Class<? extends SeContainerInitializer> findClass(final String 
name)
+    {
+        switch (name)
+        {
+            case "owb":
+            case "openwebbeans":
+            case "org.apache.openwebbeans.se.OWBInitializer":
+                return OWBInitializer.class;
+            default:
+                try
+                {
+                    return 
ofNullable(SeInitializerFacade.class.getClassLoader())
+                            .orElseGet(ClassLoader::getSystemClassLoader)
+                            .loadClass(name.trim())
+                            .asSubclass(SeContainerInitializer.class);
+                }
+                catch (final ClassNotFoundException e)
+                {
+                    throw new IllegalArgumentException(e);
+                }
+        }
+    }
+
+    private SeContainerInitializer newInitializerInstance(final Class<? 
extends SeContainerInitializer> type)
+    {
+        if (type == OWBInitializer.class)
+        {
+            final OWBInitializer initializer = new OWBInitializer();
+            // in this mode force some SPI impl since when you force a 
provider you want to fix some ambiguity
+            // and these services can easily conflict with meecrowave for 
example
+            initializer.addProperty(ContainerLifecycle.class.getName(), 
StandaloneLifeCycle.class.getName());
+            initializer.addProperty(ContextsService.class.getName(), 
StandaloneContextsService.class.getName());
+            initializer.addProperty(ConversationService.class.getName(), 
DefaultConversationService.class.getName());
+            return initializer;
+        }
+        try
+        {
+            return type.getDeclaredConstructor().newInstance();
+        }
+        catch (final NoSuchMethodException | InstantiationException | 
IllegalAccessException e)
+        {
+            throw new IllegalArgumentException(e);
+        }
+        catch (final InvocationTargetException e)
+        {
+            throw new IllegalArgumentException(e.getTargetException());
+        }
     }
 }

Reply via email to