migrated API rework
diff --git a/README.md b/README.md
index 76fc50b..bb95ecf 100644
--- a/README.md
+++ b/README.md
@@ -233,19 +233,68 @@
#### Adapting Annotated Types as Services
A common scenario with OSGi CDI Portable Extensions is for extensions to adapt annotated types originating in the CDI Bundle as OSGi services (or with more service types).
+Common examples are the use cases relying on a whiteboard patterns. In such a case, services are deployed in the whiteboard at registration time.
+Using OSGi-CDI, you can fully use another programming model and hide OSGi service in a lot of cases.
+For instance, Aries-CDI uses that for servlet components where `@WebServlet` - and other servlet annotations - are translated to an OSGi service registration with the HTTP whiteboard properties on the fly through a CDI extension.
-Aries CDI's Extension SPI provides a convenience mechanism in the form of a carrier annotation `@AdaptedService` and a helper utility `Adapted.withServiceTypes(AnnotatedTypeConfigurator<X>, Class<?>...)`.
+Aries CDI's Extension SPI provides a convenience mechanism in the form of a carrier annotation `@AdaptedService` and a helper extensions utilities.
+It is composed of mainly two points:
-The following will make the annotated type produce a service of type `javax.servlet.Servlet`:
+1. `ProcessPotentialService` which is equivalent to `ProcessAnnotatedType` but it guarantees the underlying annotated type does not have `@Service` so that you can process the bean. If you do yourself the `@Service` presence check, you can ignore that event type. Note that you can use `org.apache.aries.cdi.extension.spi.adapt.FiltersOn` as the CDI `@WithAnnotations` to filter this event by annotations or type.
+2. `MergeServiceTypes` event which can be sent from the `BeanManager` to add service types to a bean.
+
+For `ProcessPotentialService` to be enabled, you must register the extension firing `RegisterExtension` event in `BeforeBeanDiscovery` event:
```java
-if (!Adapted.withServiceTypes(configurator, javax.servlet.Servlet.class)) {
- // was not adapted because it was already marked with @Service
- return;
+void register(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager manager) {
+ manager.fireEvent(new RegisterExtension(this));
}
```
+Assuming you have the following bean:
+```java
+@MyAutoRegistration
+public class MyService implements MyApi {
+ // ... MyApi impl
+}
+```
+
+You can write an extension grabbing all `@MyAutoRegistration` types to add them as services and register it in OSGi registry:
+
+```java
+public class MyComponentTypeExtension implements Extension {
+ void register(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager manager) {
+ manager.fireEvent(new RegisterExtension(this));
+ }
+
+ void forceMyComponentTypeToBeAService(
+ @Observes @FilterOn(annotations = MyAutoRegistration.class, types = MyApi.class) ProcessPotentialService pps,
+ BeanManager beanManager) {
+ beanManager.fireEvent(MergeServiceTypes.forEvent(pat).withTypes(MyApi.class).build());
+ }
+}
+```
+
+Alternatively you can use the funcitonal style for that extension:
+
+```java
+public class MyComponentTypeExtension implements Extension {
+ void register(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager manager) {
+ manager.fireEvent(new RegisterExtension(this)
+ .registerObserver()
+ .forTypes(MyApi.class)
+ .forAnnotations(MyAutoRegistration.class)
+ .execute((beanManager, processPotentialService) ->
+ beanManager.fireEvent(MergeServiceTypes.forEvent(pat).withTypes(MyApi.class).build()))
+ .done());
+ }
+}
+```
+
+This is enough to let Aries-CDI registers the annotated type as a service (as if you would have `@Service(MyApi.class)`).
+
+IMPORTANT: only `BeanManager` injection is supported for this kind of lifecycle methods.
The dependency for the Extension SPI is:
diff --git a/cdi-executable/owb-executable.bndrun b/cdi-executable/owb-executable.bndrun
index b2af497..69530e0 100644
--- a/cdi-executable/owb-executable.bndrun
+++ b/cdi-executable/owb-executable.bndrun
@@ -25,7 +25,6 @@
openwebbeans-spi;version='[2.0.13,2.0.14)',\
org.apache.aries.cdi.extender;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extension.spi;version='[1.1.0,1.1.1)',\
- org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.3,1.2.4)',\
org.apache.felix.configadmin;version='[1.9.10,1.9.11)',\
@@ -43,4 +42,5 @@
org.apache.xbean.finder-shaded;version='[4.13.0,4.13.1)',\
org.osgi.service.cdi;version='[1.0.0,1.0.1)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
- org.osgi.util.promise;version='[1.1.0,1.1.1)'
+ org.osgi.util.promise;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)'
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java
index f412d48..6d8975c 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/BundleContextExtension.java
@@ -26,6 +26,10 @@
public class BundleContextExtension implements Extension {
+ protected BundleContextExtension() { // for proxy
+ this(null);
+ }
+
public BundleContextExtension(BundleContext bundleContext) {
_bundleContext = bundleContext;
}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java
index c006aa5..0558cbe 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ConfigurationExtension.java
@@ -37,6 +37,11 @@
public class ConfigurationExtension extends AbstractMap<String, Object> implements Configuration, Extension {
+ protected ConfigurationExtension() { // proxy
+ _containerState = null;
+ _configuration = null;
+ }
+
public ConfigurationExtension(ContainerState containerState) {
_containerState = containerState;
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java
index 5e6dab6..d110de3 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/LoggerExtension.java
@@ -26,6 +26,10 @@
public class LoggerExtension implements Extension {
+ protected LoggerExtension() { // for proxy
+ this(null);
+ }
+
public LoggerExtension(ContainerState containerState) {
_containerState = containerState;
}
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java
index 777ac6a..0842a0e 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/RuntimeExtension.java
@@ -92,6 +92,15 @@
public class RuntimeExtension implements Extension {
+ protected RuntimeExtension() { // for extension proxy
+ _containerState = null;
+ _log = null;
+ _configurationBuilder = null;
+ _singleBuilder = null;
+ _factoryBuilder = null;
+ _containerTemplate = null;
+ }
+
public RuntimeExtension(
ContainerState containerState,
ConfigurationListener.Builder configurationBuilder,
diff --git a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceAdapterExtension.java b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceAdapterExtension.java
index 8a5669f..c867a6f 100644
--- a/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceAdapterExtension.java
+++ b/cdi-extender/src/main/java/org/apache/aries/cdi/container/internal/container/ServiceAdapterExtension.java
@@ -2,9 +2,9 @@
* Licensed 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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.
@@ -14,42 +14,191 @@
package org.apache.aries.cdi.container.internal.container;
+import static java.util.Arrays.asList;
+import static java.util.function.Function.identity;
+import static java.util.stream.Collectors.toList;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.AbstractMap.SimpleImmutableEntry;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map.Entry;
+import java.util.Optional;
+import java.util.function.BiConsumer;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
import java.util.stream.Stream;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Annotated;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
+import org.apache.aries.cdi.extension.spi.adapt.FiltersOn;
import org.apache.aries.cdi.extension.spi.adapt.MergeServiceTypes;
+import org.apache.aries.cdi.extension.spi.adapt.ProcessPotentialService;
+import org.apache.aries.cdi.extension.spi.adapt.RegisterExtension;
import org.apache.aries.cdi.extension.spi.annotation.AdaptedService;
+import org.osgi.service.cdi.annotations.Service;
public class ServiceAdapterExtension implements Extension {
- private boolean started;
+ private static final Predicate<AnnotatedType<?>> ANNOTATED_TYPE_TRUE_PREDICATE = at -> true;
- <T> void onMergeServiceTypes(@Observes final MergeServiceTypes<T> mergeServiceTypes) {
- if (started) {
- throw new IllegalStateException("Container already started");
- }
+ private boolean started;
- final AdaptedService adaptedService = mergeServiceTypes.getProcessAnnotatedType()
- .getAnnotatedType().getAnnotation(AdaptedService.class);
- final AnnotatedTypeConfigurator<T> configurator = mergeServiceTypes.getProcessAnnotatedType().configureAnnotatedType();
+ private Collection<Entry<Predicate<AnnotatedType<?>>, BiConsumer<BeanManager, ProcessAnnotatedType<?>>>> forwardingObservers = new ArrayList<>();
- final Class<?>[] services;
- if (adaptedService != null) {
- configurator.remove(a -> a.annotationType() == AdaptedService.class);
- services = Stream.concat(
- Stream.of(mergeServiceTypes.getTypes()),
- Stream.of(adaptedService.value()))
- .toArray(Class[]::new);
- } else {
- services = mergeServiceTypes.getTypes();
- }
- configurator.add(AdaptedService.Literal.of(services));
- }
+ void capturePotentialServiceObservers(@Observes final RegisterExtension registerExtension) {
+ if (started) {
+ throw new IllegalStateException("Container already started");
+ }
- void started(@Observes final AfterDeploymentValidation afterDeploymentValidation) {
- started = true;
- }
+ // declarative mode
+ forwardingObservers.addAll(forMethods(registerExtension.getExtension().getClass())
+ .map(method -> new SimpleImmutableEntry<>(registerExtension.getExtension(), method))
+ .filter(method -> Stream.of(method.getValue().getParameters())
+ .anyMatch(p -> p.isAnnotationPresent(Observes.class) && p.getType() == ProcessPotentialService.class))
+ .map(e -> new SimpleImmutableEntry<>(toPredicate(e.getValue()), toConsumer(e.getValue(), e.getKey())))
+ .collect(toList()));
+
+ // functional mode
+ forwardingObservers.addAll(registerExtension.getBuilders().stream()
+ .map(builder -> new SimpleImmutableEntry<>(
+ toPredicate(builder.getAnnotations(), builder.getTypes()),
+ (BiConsumer<BeanManager, ProcessAnnotatedType<?>>) (bm, pat) ->
+ builder.getConsumer().accept(bm, new ProcessPotentialService(pat))))
+ .collect(toList()));
+ }
+
+ <T> void forwardToObservers(@Observes final ProcessAnnotatedType<T> pat, final BeanManager beanManager) {
+ AnnotatedType<T> annotatedType;
+ if (!forwardingObservers.isEmpty() && !(annotatedType = pat.getAnnotatedType()).isAnnotationPresent(Service.class)) {
+ // simulate that but avoid a tons of events for all possible combinations of qualifiers which would be too slow
+ // beanManager.fireEvent(new ProcessPotentialService(pat), createAllPotentialQualifiers(pat));
+
+ forwardingObservers.stream()
+ .filter(predicateWithObserver -> predicateWithObserver.getKey().test(annotatedType))
+ .map(Entry::getValue)
+ .forEach(observer -> observer.accept(beanManager, pat));
+ }
+ }
+
+ void mergeAdaptedServiceTypes(@Observes final MergeServiceTypes mergeServiceTypes) {
+ if (started) {
+ throw new IllegalStateException("Container already started");
+ }
+
+ final AdaptedService adaptedService = mergeServiceTypes.getProcessAnnotatedType()
+ .getAnnotatedType().getAnnotation(AdaptedService.class);
+ final AnnotatedTypeConfigurator<?> configurator = mergeServiceTypes.getProcessAnnotatedType().configureAnnotatedType();
+
+ final Class<?>[] services;
+ if (adaptedService != null) {
+ configurator.remove(a -> a.annotationType() == AdaptedService.class);
+ services = Stream.concat(
+ Stream.of(mergeServiceTypes.getTypes()),
+ Stream.of(adaptedService.value()))
+ .distinct()
+ .toArray(Class[]::new);
+ } else {
+ services = mergeServiceTypes.getTypes();
+ }
+ configurator.add(AdaptedService.Literal.of(services));
+ }
+
+ void setStarted(@Observes final AfterDeploymentValidation afterDeploymentValidation) {
+ started = true;
+ }
+
+ // using reflection since we are too early in CDI lifecycle to use CDI model
+ private Predicate<AnnotatedType<?>> toPredicate(final Method method) {
+ return Stream.of(method.getParameters())
+ .filter(parameter -> parameter.isAnnotationPresent(Observes.class))
+ .findFirst()
+ .map(parameter -> parameter.getAnnotation(FiltersOn.class))
+ .map(filters -> toPredicate(asList(filters.annotations()), asList(filters.types())))
+ .orElse(ANNOTATED_TYPE_TRUE_PREDICATE);
+ }
+
+ private Predicate<AnnotatedType<?>> toPredicate(final Collection<Class<?>> annotations, final Collection<Class<?>> types) {
+ return filterWithAnnotations(annotations).and(filterWithTypes(types));
+ }
+
+ private BiConsumer<BeanManager, ProcessAnnotatedType<?>> toConsumer(final Method method, final Extension instance) {
+ final BiFunction<BeanManager, ProcessAnnotatedType<?>, Object>[] argsFactory = Stream.of(method.getParameters())
+ .map(parameter -> lookupMethod(method, parameter))
+ .toArray(BiFunction[]::new);
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ }
+ return (bm, pat) -> {
+ try {
+ method.invoke(
+ instance,
+ Stream.of(argsFactory).map(fn -> fn.apply(bm, pat)).toArray(Object[]::new));
+ } catch (final IllegalAccessException e) {
+ throw new IllegalStateException(e);
+ } catch (final InvocationTargetException e) {
+ throw new IllegalStateException(e.getTargetException());
+ }
+ };
+ }
+
+ private BiFunction<BeanManager, ProcessAnnotatedType<?>, Object> lookupMethod(
+ final Method method, final Parameter parameter) {
+ if (BeanManager.class == parameter.getType()) {
+ return (bm, pat) -> bm;
+ }
+ if (ProcessPotentialService.class == parameter.getType()) {
+ return (bm, pat) -> new ProcessPotentialService(pat);
+ }
+ throw new IllegalArgumentException(
+ "Unsupported type: " + parameter.getType() + " on " + method);
+ }
+
+ private Predicate<AnnotatedType<?>> filterWithTypes(final Collection<Class<?>> filterOnTypes) {
+ return Optional.of(filterOnTypes)
+ .filter(this::shouldNotIgnore)
+ .map(types -> (Predicate<AnnotatedType<?>>) annotatedType -> types.stream()
+ .anyMatch(t -> annotatedType.getJavaClass().isAssignableFrom(t)))
+ .orElse(ANNOTATED_TYPE_TRUE_PREDICATE);
+ }
+
+ private Predicate<AnnotatedType<?>> filterWithAnnotations(final Collection<Class<?>> filterOnAnnotations) {
+ return Optional.of(filterOnAnnotations)
+ .filter(this::shouldNotIgnore)
+ .map(withAnnotations -> (Predicate<AnnotatedType<?>>) annotatedType -> Stream.of(
+ Stream.of(annotatedType.getAnnotations()), // class
+ annotatedType.getFields().stream().map(Annotated::getAnnotations), // fields
+ Stream.concat( // (constructors + methods) x (self + parameters)
+ annotatedType.getMethods().stream(),
+ annotatedType.getConstructors().stream())
+ .flatMap(m -> Stream.concat(
+ Stream.of(m.getAnnotations()),
+ m.getParameters().stream().map(Annotated::getAnnotations))))
+ .flatMap(identity())
+ .anyMatch(annotations -> annotations.stream().anyMatch(annotation ->
+ withAnnotations.stream().anyMatch(withAnnotation -> Stream.concat(
+ Stream.of(annotation.annotationType()),
+ Stream.of(annotation.annotationType().getAnnotations()).map(Annotation::annotationType))
+ .anyMatch(withAnnotation::isAssignableFrom)))))
+ .orElse(ANNOTATED_TYPE_TRUE_PREDICATE);
+ }
+
+ private boolean shouldNotIgnore(final Collection<Class<?>> annotations) {
+ return annotations.size() != 1 || FiltersOn.class != annotations.iterator().next();
+ }
+
+ private Stream<Method> forMethods(final Class<?> clazz) {
+ return clazz == Object.class || clazz == null ?
+ Stream.empty() :
+ Stream.concat(Stream.of(clazz.getDeclaredMethods()), forMethods(clazz.getSuperclass()));
+ }
}
diff --git a/cdi-extension-el-jsp/src/main/java/org/apache/aries/cdi/extension/el/jsp/ELJSPExtension.java b/cdi-extension-el-jsp/src/main/java/org/apache/aries/cdi/extension/el/jsp/ELJSPExtension.java
index 3e3b89f..581c71c 100644
--- a/cdi-extension-el-jsp/src/main/java/org/apache/aries/cdi/extension/el/jsp/ELJSPExtension.java
+++ b/cdi-extension-el-jsp/src/main/java/org/apache/aries/cdi/extension/el/jsp/ELJSPExtension.java
@@ -51,6 +51,10 @@
public class ELJSPExtension implements Extension {
+ protected ELJSPExtension() { // proxy
+ _bundle = null;
+ }
+
public ELJSPExtension(Bundle bundle) {
_bundle = bundle;
}
diff --git a/cdi-extension-jaxrs/src/main/java/org/apache/aries/cdi/extension/jaxrs/JaxrsCDIExtension.java b/cdi-extension-jaxrs/src/main/java/org/apache/aries/cdi/extension/jaxrs/JaxrsCDIExtension.java
index b63748d..3a3603f 100644
--- a/cdi-extension-jaxrs/src/main/java/org/apache/aries/cdi/extension/jaxrs/JaxrsCDIExtension.java
+++ b/cdi-extension-jaxrs/src/main/java/org/apache/aries/cdi/extension/jaxrs/JaxrsCDIExtension.java
@@ -2,9 +2,9 @@
* Licensed 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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.
@@ -14,13 +14,10 @@
package org.apache.aries.cdi.extension.jaxrs;
-import static java.util.Optional.empty;
-import static java.util.Optional.of;
import static java.util.Optional.ofNullable;
import java.lang.annotation.Annotation;
import java.util.List;
-import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.enterprise.context.Dependent;
@@ -28,10 +25,9 @@
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.DeploymentException;
import javax.enterprise.inject.spi.Extension;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.WithAnnotations;
import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.DELETE;
@@ -55,7 +51,10 @@
import javax.ws.rs.ext.ReaderInterceptor;
import javax.ws.rs.ext.WriterInterceptor;
+import org.apache.aries.cdi.extension.spi.adapt.FiltersOn;
import org.apache.aries.cdi.extension.spi.adapt.MergeServiceTypes;
+import org.apache.aries.cdi.extension.spi.adapt.ProcessPotentialService;
+import org.apache.aries.cdi.extension.spi.adapt.RegisterExtension;
import org.apache.aries.cdi.extra.propertytypes.JaxrsApplicationBase;
import org.apache.aries.cdi.extra.propertytypes.JaxrsApplicationSelect;
import org.apache.aries.cdi.extra.propertytypes.JaxrsExtension;
@@ -65,249 +64,192 @@
import org.apache.aries.cdi.extra.propertytypes.JaxrsWhiteboardTarget;
import org.apache.aries.cdi.spi.configuration.Configuration;
import org.osgi.service.cdi.ServiceScope;
-import org.osgi.service.cdi.annotations.Service;
import org.osgi.service.cdi.annotations.ServiceInstance;
import org.osgi.service.jaxrs.whiteboard.JaxrsWhiteboardConstants;
public class JaxrsCDIExtension implements Extension {
- private volatile Configuration configuration;
- private final List<AnnotatedType<? extends Application>> applications = new CopyOnWriteArrayList<>();
+ private volatile Configuration configuration;
+ private final List<AnnotatedType<?>> applications = new CopyOnWriteArrayList<>();
+ void register(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager manager) {
+ manager.fireEvent(new RegisterExtension(this));
+ }
- void getConfiguration(@Observes Configuration configuration) {
- this.configuration = configuration;
- }
+ void getConfiguration(@Observes Configuration configuration) {
+ this.configuration = configuration;
+ }
- void application(
- @Observes @WithAnnotations(ApplicationPath.class)
- ProcessAnnotatedType<? extends Application> pat, BeanManager beanManager) {
+ void application(
+ @Observes @FiltersOn(annotations = ApplicationPath.class)
+ ProcessPotentialService pat, BeanManager beanManager) {
- AnnotatedType<? extends Application> annotatedType = pat.getAnnotatedType();
+ AnnotatedType<?> annotatedType = pat.getAnnotatedType();
- applications.add(annotatedType);
+ applications.add(annotatedType);
- commonProperties(pat, Application.class, true, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsApplicationBase.class)) {
- configurator.add(
- JaxrsApplicationBase.Literal.of(
- annotatedType.getAnnotation(ApplicationPath.class).value()));
- }
- });
- }
+ commonProperties(pat, Application.class, true, beanManager);
+ if (!annotatedType.isAnnotationPresent(JaxrsApplicationBase.class)) {
+ pat.configureAnnotatedType().add(
+ JaxrsApplicationBase.Literal.of(
+ annotatedType.getAnnotation(ApplicationPath.class).value()));
+ }
+ }
- <X> void resource(
- @Observes @WithAnnotations({Path.class, DELETE.class, GET.class, HEAD.class, OPTIONS.class, PATCH.class, POST.class, PUT.class})
- ProcessAnnotatedType<X> pat, BeanManager beanManager) {
+ void resource(
+ @Observes
+ @FiltersOn(annotations = {Path.class, DELETE.class, GET.class, HEAD.class, OPTIONS.class, PATCH.class, POST.class, PUT.class})
+ ProcessPotentialService pat, BeanManager beanManager) {
- AnnotatedType<X> annotatedType = pat.getAnnotatedType();
+ commonProperties(pat, Object.class, false, beanManager);
+ if (!pat.getAnnotatedType().isAnnotationPresent(JaxrsResource.class)) {
+ pat.configureAnnotatedType().add(JaxrsResource.Literal.INSTANCE);
+ }
+ }
- commonProperties(pat, Object.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsResource.class)) {
- configurator.add(JaxrsResource.Literal.INSTANCE);
- }
- });
- }
+ void containerRequestFilter(
+ @Observes @FiltersOn(types = ContainerRequestFilter.class) ProcessPotentialService pat, BeanManager beanManager) {
+ commonProperties(pat, ContainerRequestFilter.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- void containerRequestFilter(
- @Observes ProcessAnnotatedType<? extends ContainerRequestFilter> pat, BeanManager beanManager) {
+ void containerResponseFilter(
+ @Observes @FiltersOn(types = ContainerResponseFilter.class) ProcessPotentialService pat, BeanManager beanManager) {
- AnnotatedType<? extends ContainerRequestFilter> annotatedType = pat.getAnnotatedType();
+ commonProperties(pat, ContainerResponseFilter.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- commonProperties(pat, ContainerRequestFilter.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ void readerInterceptor(
+ @Observes @FiltersOn(types = ReaderInterceptor.class) ProcessPotentialService pat, BeanManager beanManager) {
- void containerResponseFilter(
- @Observes ProcessAnnotatedType<? extends ContainerResponseFilter> pat, BeanManager beanManager) {
+ commonProperties(pat, ReaderInterceptor.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- AnnotatedType<? extends ContainerResponseFilter> annotatedType = pat.getAnnotatedType();
+ void writerInterceptor(
+ @Observes @FiltersOn(types = WriterInterceptor.class) ProcessPotentialService pat, BeanManager beanManager) {
- commonProperties(pat, ContainerResponseFilter.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ commonProperties(pat, WriterInterceptor.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- void readerInterceptor(
- @Observes ProcessAnnotatedType<? extends ReaderInterceptor> pat, BeanManager beanManager) {
+ @SuppressWarnings("rawtypes")
+ void messageBodyReader(
+ @Observes @FiltersOn(types = MessageBodyReader.class) ProcessPotentialService pat, BeanManager beanManager) {
- AnnotatedType<? extends ReaderInterceptor> annotatedType = pat.getAnnotatedType();
+ commonProperties(pat, MessageBodyReader.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- commonProperties(pat, ReaderInterceptor.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ @SuppressWarnings("rawtypes")
+ void messageBodyWriter(
+ @Observes @FiltersOn(types = MessageBodyWriter.class) ProcessPotentialService pat, BeanManager beanManager) {
- void writerInterceptor(
- @Observes ProcessAnnotatedType<? extends WriterInterceptor> pat, BeanManager beanManager) {
+ commonProperties(pat, MessageBodyWriter.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- AnnotatedType<? extends WriterInterceptor> annotatedType = pat.getAnnotatedType();
+ @SuppressWarnings("rawtypes")
+ void contextResolver(
+ @Observes @FiltersOn(types = ContextResolver.class) ProcessPotentialService pat, BeanManager beanManager) {
- commonProperties(pat, WriterInterceptor.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ commonProperties(pat, ContextResolver.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- @SuppressWarnings("rawtypes")
- void messageBodyReader(
- @Observes ProcessAnnotatedType<? extends MessageBodyReader> pat, BeanManager beanManager) {
+ @SuppressWarnings("rawtypes")
+ void exceptionMapper(
+ @Observes @FiltersOn(types = ExceptionMapper.class) ProcessPotentialService pat, BeanManager beanManager) {
- AnnotatedType<? extends MessageBodyReader> annotatedType = pat.getAnnotatedType();
+ commonProperties(pat, ExceptionMapper.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- commonProperties(pat, MessageBodyReader.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ void paramConverterProvider(
+ @Observes @FiltersOn(types = ParamConverterProvider.class) ProcessPotentialService pat, BeanManager beanManager) {
- @SuppressWarnings("rawtypes")
- void messageBodyWriter(
- @Observes ProcessAnnotatedType<? extends MessageBodyWriter> pat, BeanManager beanManager) {
+ commonProperties(pat, ParamConverterProvider.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- AnnotatedType<? extends MessageBodyWriter> annotatedType = pat.getAnnotatedType();
+ void feature(
+ @Observes @FiltersOn(types = Feature.class) ProcessPotentialService pat, BeanManager beanManager) {
- commonProperties(pat, MessageBodyWriter.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
+ commonProperties(pat, Feature.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- });
- }
+ void dynamicFeature(
+ @Observes @FiltersOn(types = DynamicFeature.class) ProcessPotentialService pat, BeanManager beanManager) {
- @SuppressWarnings("rawtypes")
- void contextResolver(
- @Observes ProcessAnnotatedType<? extends ContextResolver> pat, BeanManager beanManager) {
+ commonProperties(pat, DynamicFeature.class, false, beanManager);
+ addJaxRsExtension(pat);
+ }
- AnnotatedType<? extends ContextResolver> annotatedType = pat.getAnnotatedType();
+ private void addJaxRsExtension(final ProcessPotentialService pat) {
+ if (!pat.getAnnotatedType().isAnnotationPresent(JaxrsExtension.class)) {
+ pat.configureAnnotatedType().add(JaxrsExtension.Literal.INSTANCE);
+ }
+ }
- commonProperties(pat, ContextResolver.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ /*
+ * @return true if common properties were added (i.e. if no @Service was found)
+ */
+ private void commonProperties(
+ ProcessPotentialService pat, Class<?> serviceType, boolean application, BeanManager beanManager) {
+ beanManager.fireEvent(MergeServiceTypes.forEvent(pat).withTypes(serviceType).build());
+ final AnnotatedTypeConfigurator<?> configurator = pat.configureAnnotatedType();
+ final AnnotatedType<?> annotatedType = pat.getAnnotatedType();
+ if (!annotatedType.isAnnotationPresent(JaxrsName.class)) {
+ if (application) {
+ configurator.add(
+ JaxrsName.Literal.of(
+ ofNullable((String) configuration.get(JaxrsWhiteboardConstants.JAX_RS_NAME)).orElse(
+ JaxrsWhiteboardConstants.JAX_RS_DEFAULT_APPLICATION
+ )
+ )
+ );
+ } else {
+ configurator.add(JaxrsName.Literal.of(annotatedType.getJavaClass().getSimpleName()));
+ }
+ }
- @SuppressWarnings("rawtypes")
- void exceptionMapper(
- @Observes ProcessAnnotatedType<? extends ExceptionMapper> pat, BeanManager beanManager) {
+ if (!application && !annotatedType.isAnnotationPresent(JaxrsApplicationSelect.class)) {
+ ofNullable((String) configuration.get(JaxrsWhiteboardConstants.JAX_RS_APPLICATION_SELECT)).ifPresent(
+ select -> configurator.add(JaxrsApplicationSelect.Literal.of(select))
+ );
+ }
- AnnotatedType<? extends ExceptionMapper> annotatedType = pat.getAnnotatedType();
+ if (!annotatedType.isAnnotationPresent(JaxrsExtensionSelect.class)) {
+ ofNullable((String[]) configuration.get(JaxrsWhiteboardConstants.JAX_RS_EXTENSION_SELECT)).ifPresent(selects -> {
+ if (selects.length > 0) {
+ configurator.add(JaxrsExtensionSelect.Literal.of(selects));
+ }
+ });
+ }
- commonProperties(pat, ExceptionMapper.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
+ if (!annotatedType.isAnnotationPresent(JaxrsWhiteboardTarget.class)) {
+ ofNullable((String) configuration.get(JaxrsWhiteboardConstants.JAX_RS_WHITEBOARD_TARGET)).ifPresent(
+ target -> configurator.add(JaxrsWhiteboardTarget.Literal.of(target))
+ );
+ }
- void paramConverterProvider(
- @Observes ProcessAnnotatedType<? extends ParamConverterProvider> pat, BeanManager beanManager) {
+ if (!annotatedType.isAnnotationPresent(ServiceInstance.class)) {
+ Class<? extends Annotation> beanScope = Util.beanScope(annotatedType, Dependent.class);
- AnnotatedType<? extends ParamConverterProvider> annotatedType = pat.getAnnotatedType();
+ if (Dependent.class.equals(beanScope)) {
+ configurator.add(ServiceInstance.Literal.of(ServiceScope.PROTOTYPE));
+ }
+ }
+ }
- commonProperties(pat, ParamConverterProvider.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
-
- void feature(
- @Observes ProcessAnnotatedType<? extends Feature> pat, BeanManager beanManager) {
-
- AnnotatedType<? extends Feature> annotatedType = pat.getAnnotatedType();
-
- commonProperties(pat, Feature.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
-
- void dynamicFeature(
- @Observes ProcessAnnotatedType<? extends DynamicFeature> pat, BeanManager beanManager) {
-
- AnnotatedType<? extends DynamicFeature> annotatedType = pat.getAnnotatedType();
-
- commonProperties(pat, DynamicFeature.class, false, beanManager).ifPresent(configurator -> {
- if (!annotatedType.isAnnotationPresent(JaxrsExtension.class)) {
- configurator.add(JaxrsExtension.Literal.INSTANCE);
- }
- });
- }
-
- /*
- * @return true if common properties were added (i.e. if no @Service was found)
- */
- private <X> Optional<AnnotatedTypeConfigurator<X>> commonProperties(
- ProcessAnnotatedType<X> pat, Class<?> serviceType, boolean application, BeanManager beanManager) {
- if (pat.getAnnotatedType().isAnnotationPresent(Service.class)) {
- return empty();
- }
- beanManager.fireEvent(new MergeServiceTypes<>(pat, serviceType));
- final AnnotatedTypeConfigurator<X> configurator = pat.configureAnnotatedType();
- final AnnotatedType<?> annotatedType = pat.getAnnotatedType();
- if (!annotatedType.isAnnotationPresent(JaxrsName.class)) {
- if (application) {
- configurator.add(
- JaxrsName.Literal.of(
- ofNullable((String)configuration.get(JaxrsWhiteboardConstants.JAX_RS_NAME)).orElse(
- JaxrsWhiteboardConstants.JAX_RS_DEFAULT_APPLICATION
- )
- )
- );
- }
- else {
- configurator.add(JaxrsName.Literal.of(annotatedType.getJavaClass().getSimpleName()));
- }
- }
-
- if (!application && !annotatedType.isAnnotationPresent(JaxrsApplicationSelect.class)) {
- ofNullable((String)configuration.get(JaxrsWhiteboardConstants.JAX_RS_APPLICATION_SELECT)).ifPresent(
- select -> configurator.add(JaxrsApplicationSelect.Literal.of(select))
- );
- }
-
- if (!annotatedType.isAnnotationPresent(JaxrsExtensionSelect.class)) {
- ofNullable((String[])configuration.get(JaxrsWhiteboardConstants.JAX_RS_EXTENSION_SELECT)).ifPresent(selects -> {
- if (selects.length > 0) {
- configurator.add(JaxrsExtensionSelect.Literal.of(selects));
- }
- });
- }
-
- if (!annotatedType.isAnnotationPresent(JaxrsWhiteboardTarget.class)) {
- ofNullable((String)configuration.get(JaxrsWhiteboardConstants.JAX_RS_WHITEBOARD_TARGET)).ifPresent(
- target -> configurator.add(JaxrsWhiteboardTarget.Literal.of(target))
- );
- }
-
- if (!annotatedType.isAnnotationPresent(ServiceInstance.class)) {
- Class<? extends Annotation> beanScope = Util.beanScope(annotatedType, Dependent.class);
-
- if (Dependent.class.equals(beanScope)) {
- configurator.add(ServiceInstance.Literal.of(ServiceScope.PROTOTYPE));
- }
- }
- return of(configurator);
- }
-
- void afterDeploymentValidation(@Observes AfterDeploymentValidation adv) {
- if (applications.size() > 1) {
- adv.addDeploymentProblem(
- new DeploymentException(
- "More than one javax.ws.rs.core.Application annotated types were found in the CDI bundle."));
- }
- }
+ void afterDeploymentValidation(@Observes AfterDeploymentValidation adv) {
+ if (applications.size() > 1) { // todo: revise that, it is not illegal and supported by cxf-cdi-extension
+ adv.addDeploymentProblem(
+ new DeploymentException(
+ "More than one javax.ws.rs.core.Application annotated types were found in the CDI bundle."));
+ }
+ }
}
diff --git a/cdi-extension-mp-config/owb-itest.bndrun b/cdi-extension-mp-config/owb-itest.bndrun
index 93d9975..151611e 100644
--- a/cdi-extension-mp-config/owb-itest.bndrun
+++ b/cdi-extension-mp-config/owb-itest.bndrun
@@ -26,7 +26,8 @@
org.apache.aries.cdi.extension.mp-config-tests;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extension.mp-config;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extension.spi;version='[1.1.0,1.1.1)',\
- org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb.spi;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb.core;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.3,1.2.4)',\
org.apache.felix.configadmin;version='[1.9.10,1.9.11)',\
diff --git a/cdi-extension-mp-jwt-auth/owb-itest.bndrun b/cdi-extension-mp-jwt-auth/owb-itest.bndrun
index 2b9dd4e..e3fcbf7 100644
--- a/cdi-extension-mp-jwt-auth/owb-itest.bndrun
+++ b/cdi-extension-mp-jwt-auth/owb-itest.bndrun
@@ -33,7 +33,8 @@
org.apache.aries.cdi.extension.servlet.owb;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extension.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extra;version='[1.1.0,1.1.1)',\
- org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb.spi;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb.core;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.jax.rs.whiteboard;version='[1.0.7,1.0.8)',\
org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.3,1.2.4)',\
diff --git a/cdi-extension-mp-metrics/owb-itest.bndrun b/cdi-extension-mp-metrics/owb-itest.bndrun
index e7be03c..a16b8a7 100644
--- a/cdi-extension-mp-metrics/owb-itest.bndrun
+++ b/cdi-extension-mp-metrics/owb-itest.bndrun
@@ -27,7 +27,8 @@
org.apache.aries.cdi.extension.mp-metrics;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extension.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extra;version='[1.1.0,1.1.1)',\
- org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb.spi;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb.core;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.jax.rs.whiteboard;version='[1.0.7,1.0.8)',\
org.apache.aries.spifly.dynamic.framework.extension;version='[1.2.3,1.2.4)',\
diff --git a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/BaseServletExtension.java b/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/BaseServletExtension.java
new file mode 100644
index 0000000..6ecdf2b
--- /dev/null
+++ b/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/BaseServletExtension.java
@@ -0,0 +1,215 @@
+/**
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.apache.aries.cdi.extension.servlet.common;
+
+import static java.util.Optional.ofNullable;
+import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.BeforeShutdown;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
+import javax.servlet.ServletContextAttributeListener;
+import javax.servlet.ServletContextListener;
+import javax.servlet.ServletRequestAttributeListener;
+import javax.servlet.ServletRequestListener;
+import javax.servlet.annotation.MultipartConfig;
+import javax.servlet.annotation.WebFilter;
+import javax.servlet.annotation.WebListener;
+import javax.servlet.annotation.WebServlet;
+import javax.servlet.http.HttpSessionAttributeListener;
+import javax.servlet.http.HttpSessionIdListener;
+import javax.servlet.http.HttpSessionListener;
+
+import org.apache.aries.cdi.extension.spi.adapt.MergeServiceTypes;
+import org.apache.aries.cdi.extension.spi.adapt.ProcessPotentialService;
+import org.apache.aries.cdi.extension.spi.adapt.FiltersOn;
+import org.apache.aries.cdi.extension.spi.adapt.RegisterExtension;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardContextSelect;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterAsyncSupported;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterDispatcher;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterName;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterPattern;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterServlet;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardListener;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletAsyncSupported;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletMultipart;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletName;
+import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletPattern;
+import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
+import org.apache.aries.cdi.extra.propertytypes.ServiceRanking;
+import org.apache.aries.cdi.spi.configuration.Configuration;
+import org.osgi.framework.ServiceRegistration;
+
+public class BaseServletExtension implements Extension {
+ protected Configuration configuration;
+ protected volatile ServiceRegistration<?> _listenerRegistration;
+ protected final AtomicBoolean destroyed = new AtomicBoolean(false);
+
+ void register(@Observes final BeforeBeanDiscovery beforeBeanDiscovery, final BeanManager manager) {
+ manager.fireEvent(new RegisterExtension(this));
+ }
+
+ void setConfiguration(@Observes Configuration configuration) {
+ this.configuration = configuration;
+ }
+
+ void webFilter(@Observes @FiltersOn(annotations = WebFilter.class) ProcessPotentialService pat,
+ BeanManager beanManager) {
+ beanManager.fireEvent(MergeServiceTypes.forEvent(pat).withTypes(Filter.class).build());
+ final AnnotatedTypeConfigurator<?> configurator = pat.configureAnnotatedType();
+ final AnnotatedType<?> annotatedType = pat.getAnnotatedType();
+
+ WebFilter webFilter = annotatedType.getAnnotation(WebFilter.class);
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
+ ofNullable((String) configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)).ifPresent(
+ select -> configurator.add(HttpWhiteboardContextSelect.Literal.of(select))
+ );
+ }
+
+ if (!annotatedType.isAnnotationPresent(ServiceDescription.class) && !webFilter.description().isEmpty()) {
+ configurator.add(ServiceDescription.Literal.of(webFilter.description()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterName.class) && !webFilter.filterName().isEmpty()) {
+ configurator.add(HttpWhiteboardFilterName.Literal.of(webFilter.filterName()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterServlet.class) && webFilter.servletNames().length > 0) {
+ configurator.add(HttpWhiteboardFilterServlet.Literal.of(webFilter.servletNames()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterPattern.class)) {
+ if (webFilter.value().length > 0) {
+ configurator.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.value()));
+ } else if (webFilter.urlPatterns().length > 0) {
+ configurator.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.urlPatterns()));
+ }
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterDispatcher.class) && webFilter.dispatcherTypes().length > 0) {
+ configurator.add(HttpWhiteboardFilterDispatcher.Literal.of(webFilter.dispatcherTypes()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterAsyncSupported.class)) {
+ configurator.add(HttpWhiteboardFilterAsyncSupported.Literal.of(webFilter.asyncSupported()));
+ }
+ }
+
+ void webListener(@Observes @FiltersOn(annotations = WebListener.class) ProcessPotentialService pat,
+ BeanManager beanManager) {
+ final AnnotatedType<?> annotatedType = pat.getAnnotatedType();
+ final Class<?> javaClass = annotatedType.getJavaClass();
+ final Class<?>[] serviceTypes = Stream.of(
+ ServletContextListener.class,
+ ServletContextAttributeListener.class,
+ ServletRequestListener.class,
+ ServletRequestAttributeListener.class,
+ HttpSessionListener.class,
+ HttpSessionAttributeListener.class,
+ HttpSessionIdListener.class)
+ .filter(c -> c.isAssignableFrom(javaClass))
+ .toArray(Class[]::new);
+
+ beanManager.fireEvent(MergeServiceTypes.forEvent(pat).withTypes(serviceTypes).build());
+
+ AnnotatedTypeConfigurator<?> configurator = pat.configureAnnotatedType();
+
+ WebListener webListener = annotatedType.getAnnotation(WebListener.class);
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
+ ofNullable((String) configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)).ifPresent(
+ select -> configurator.add(HttpWhiteboardContextSelect.Literal.of(select))
+ );
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardListener.class)) {
+ configurator.add(HttpWhiteboardListener.Literal.INSTANCE);
+ }
+
+ if (!annotatedType.isAnnotationPresent(ServiceDescription.class) && !webListener.value().isEmpty()) {
+ configurator.add(ServiceDescription.Literal.of(webListener.value()));
+ }
+ }
+
+ void webServlet(@Observes @FiltersOn(annotations = WebServlet.class) ProcessPotentialService pat,
+ BeanManager beanManager) {
+ beanManager.fireEvent(MergeServiceTypes.forEvent(pat).withTypes(Servlet.class).build());
+
+ final AnnotatedTypeConfigurator<?> configurator = pat.configureAnnotatedType();
+ final AnnotatedType<?> annotatedType = pat.getAnnotatedType();
+ WebServlet webServlet = annotatedType.getAnnotation(WebServlet.class);
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
+ ofNullable((String) configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)).ifPresent(
+ select -> configurator.add(HttpWhiteboardContextSelect.Literal.of(select))
+ );
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletName.class) && !webServlet.name().isEmpty()) {
+ configurator.add(HttpWhiteboardServletName.Literal.of(webServlet.name()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletPattern.class)) {
+ if (webServlet.value().length > 0) {
+ configurator.add(HttpWhiteboardServletPattern.Literal.of(webServlet.value()));
+ } else if (webServlet.urlPatterns().length > 0) {
+ configurator.add(HttpWhiteboardServletPattern.Literal.of(webServlet.urlPatterns()));
+ }
+ }
+
+ if (!annotatedType.isAnnotationPresent(ServiceRanking.class)) {
+ configurator.add(ServiceRanking.Literal.of(webServlet.loadOnStartup()));
+ }
+
+ // TODO Howto: INIT PARAMS ???
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletAsyncSupported.class)) {
+ configurator.add(HttpWhiteboardServletAsyncSupported.Literal.of(webServlet.asyncSupported()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(ServiceDescription.class) && !webServlet.description().isEmpty()) {
+ configurator.add(ServiceDescription.Literal.of(webServlet.description()));
+ }
+
+ if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletMultipart.class)) {
+ MultipartConfig multipartConfig = annotatedType.getAnnotation(MultipartConfig.class);
+
+ if (multipartConfig != null) {
+ configurator.add(HttpWhiteboardServletMultipart.Literal.of(true, multipartConfig.fileSizeThreshold(), multipartConfig.location(), multipartConfig.maxFileSize(), multipartConfig.maxRequestSize()));
+ }
+ }
+
+ // TODO HowTo: ServletSecurity ???
+ }
+
+ void beforeShutdown(@Observes BeforeShutdown bs) {
+ if (_listenerRegistration != null && !destroyed.get()) {
+ try {
+ _listenerRegistration.unregister();
+ } catch (IllegalStateException ise) {
+ // the service was already unregistered.
+ }
+ }
+ }
+}
diff --git a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebFilterProcessor.java b/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebFilterProcessor.java
deleted file mode 100644
index 6c22b38..0000000
--- a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebFilterProcessor.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Licensed 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.apache.aries.cdi.extension.servlet.common;
-
-import static java.util.Optional.ofNullable;
-import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
-
-import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
-import javax.servlet.Filter;
-import javax.servlet.annotation.WebFilter;
-
-import org.apache.aries.cdi.extension.spi.adapt.MergeServiceTypes;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardContextSelect;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterAsyncSupported;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterDispatcher;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterName;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterPattern;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardFilterServlet;
-import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
-import org.apache.aries.cdi.spi.configuration.Configuration;
-import org.osgi.service.cdi.annotations.Service;
-
-public class WebFilterProcessor {
-
- /**
- * Call this method from an observer defined as:
- * <pre>
- * <X> void webFilter(@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat) {
- * new WebFilterProcessor().process(configuration, pat);
- * }
- * </pre>
- * @param <X>
- * @param pat
- */
- public <X> void process(
- Configuration configuration, ProcessAnnotatedType<X> pat, BeanManager beanManager) {
- if (pat.getAnnotatedType().isAnnotationPresent(Service.class)) {
- return;
- }
-
- beanManager.fireEvent(new MergeServiceTypes<>(pat, Filter.class));
- final AnnotatedTypeConfigurator<X> configurator = pat.configureAnnotatedType();
- final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
-
- WebFilter webFilter = annotatedType.getAnnotation(WebFilter.class);
-
- if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
- ofNullable((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)).ifPresent(
- select -> configurator.add(HttpWhiteboardContextSelect.Literal.of(select))
- );
- }
-
- if (!annotatedType.isAnnotationPresent(ServiceDescription.class) && !webFilter.description().isEmpty()) {
- configurator.add(ServiceDescription.Literal.of(webFilter.description()));
- }
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterName.class) && !webFilter.filterName().isEmpty()) {
- configurator.add(HttpWhiteboardFilterName.Literal.of(webFilter.filterName()));
- }
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterServlet.class) && webFilter.servletNames().length > 0) {
- configurator.add(HttpWhiteboardFilterServlet.Literal.of(webFilter.servletNames()));
- }
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterPattern.class)) {
- if (webFilter.value().length > 0) {
- configurator.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.value()));
- }
- else if (webFilter.urlPatterns().length > 0) {
- configurator.add(HttpWhiteboardFilterPattern.Literal.of(webFilter.urlPatterns()));
- }
- }
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardFilterDispatcher.class) && webFilter.dispatcherTypes().length > 0) {
- configurator.add(HttpWhiteboardFilterDispatcher.Literal.of(webFilter.dispatcherTypes()));
- }
-
- if(!annotatedType.isAnnotationPresent(HttpWhiteboardFilterAsyncSupported.class)) {
- configurator.add(HttpWhiteboardFilterAsyncSupported.Literal.of(webFilter.asyncSupported()));
- }
- }
-
-}
diff --git a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebListenerProcessor.java b/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebListenerProcessor.java
deleted file mode 100644
index 55af105..0000000
--- a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebListenerProcessor.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/**
- * Licensed 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.apache.aries.cdi.extension.servlet.common;
-
-import static java.util.Optional.ofNullable;
-import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
-
-import java.util.stream.Stream;
-
-import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
-import javax.servlet.ServletContextAttributeListener;
-import javax.servlet.ServletContextListener;
-import javax.servlet.ServletRequestAttributeListener;
-import javax.servlet.ServletRequestListener;
-import javax.servlet.annotation.WebListener;
-import javax.servlet.http.HttpSessionAttributeListener;
-import javax.servlet.http.HttpSessionIdListener;
-import javax.servlet.http.HttpSessionListener;
-
-import org.apache.aries.cdi.extension.spi.adapt.MergeServiceTypes;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardContextSelect;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardListener;
-import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
-import org.apache.aries.cdi.spi.configuration.Configuration;
-import org.osgi.service.cdi.annotations.Service;
-
-public class WebListenerProcessor {
-
- /**
- * Call this method from an observer defined as:
- * <pre>
- * <X> void webListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat) {
- * new WebListenerProcessor().process(configuration, pat);
- * }
- * </pre>
- * @param <X>
- * @param pat
- */
- public <X> void process(
- Configuration configuration, ProcessAnnotatedType<X> pat, BeanManager beanManager) {
- if (pat.getAnnotatedType().isAnnotationPresent(Service.class)) {
- return;
- }
-
- final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
- final Class<X> javaClass = annotatedType.getJavaClass();
- final Class<?>[] serviceTypes = Stream.of(
- ServletContextListener.class,
- ServletContextAttributeListener.class,
- ServletRequestListener.class,
- ServletRequestAttributeListener.class,
- HttpSessionListener.class,
- HttpSessionAttributeListener.class,
- HttpSessionIdListener.class)
- .filter(c -> c.isAssignableFrom(javaClass))
- .toArray(Class[]::new);
-
- beanManager.fireEvent(new MergeServiceTypes<>(pat, serviceTypes));
-
- AnnotatedTypeConfigurator<X> configurator = pat.configureAnnotatedType();
-
- WebListener webListener = annotatedType.getAnnotation(WebListener.class);
-
- if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
- ofNullable((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)).ifPresent(
- select -> configurator.add(HttpWhiteboardContextSelect.Literal.of(select))
- );
- }
-
- if(!annotatedType.isAnnotationPresent(HttpWhiteboardListener.class)) {
- configurator.add(HttpWhiteboardListener.Literal.INSTANCE);
- }
-
- if (!annotatedType.isAnnotationPresent(ServiceDescription.class) && !webListener.value().isEmpty()) {
- configurator.add(ServiceDescription.Literal.of(webListener.value()));
- }
- }
-
-}
diff --git a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebServletProcessor.java b/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebServletProcessor.java
deleted file mode 100644
index 9737085..0000000
--- a/cdi-extension-servlet-common/src/main/java/org/apache/aries/cdi/extension/servlet/common/WebServletProcessor.java
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * Licensed 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.apache.aries.cdi.extension.servlet.common;
-
-import static java.util.Optional.ofNullable;
-import static org.osgi.service.http.whiteboard.HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT;
-
-import javax.enterprise.inject.spi.AnnotatedType;
-import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
-import javax.servlet.Servlet;
-import javax.servlet.annotation.MultipartConfig;
-import javax.servlet.annotation.WebServlet;
-
-import org.apache.aries.cdi.extension.spi.adapt.MergeServiceTypes;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardContextSelect;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletAsyncSupported;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletMultipart;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletName;
-import org.apache.aries.cdi.extra.propertytypes.HttpWhiteboardServletPattern;
-import org.apache.aries.cdi.extra.propertytypes.ServiceDescription;
-import org.apache.aries.cdi.extra.propertytypes.ServiceRanking;
-import org.apache.aries.cdi.spi.configuration.Configuration;
-import org.osgi.service.cdi.annotations.Service;
-
-public class WebServletProcessor {
-
- /**
- * Call this method from an observer defined as:
- * <pre>
- * <X> void webServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat) {
- * new WebServletProcessor().process(configuration, pat);
- * }
- * </pre>
- * @param <X>
- * @param pat
- */
- public <X> void process(
- Configuration configuration, ProcessAnnotatedType<X> pat, BeanManager beanManager) {
- if (pat.getAnnotatedType().isAnnotationPresent(Service.class)) {
- return;
- }
-
- beanManager.fireEvent(new MergeServiceTypes<>(pat, Servlet.class));
-
- final AnnotatedTypeConfigurator<X> configurator = pat.configureAnnotatedType();
- final AnnotatedType<X> annotatedType = pat.getAnnotatedType();
- WebServlet webServlet = annotatedType.getAnnotation(WebServlet.class);
-
- if(!annotatedType.isAnnotationPresent(HttpWhiteboardContextSelect.class)) {
- ofNullable((String)configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT)).ifPresent(
- select -> configurator.add(HttpWhiteboardContextSelect.Literal.of(select))
- );
- }
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletName.class) && !webServlet.name().isEmpty()) {
- configurator.add(HttpWhiteboardServletName.Literal.of(webServlet.name()));
- }
-
- if(!annotatedType.isAnnotationPresent(HttpWhiteboardServletPattern.class)) {
- if (webServlet.value().length > 0) {
- configurator.add(HttpWhiteboardServletPattern.Literal.of(webServlet.value()));
- }
- else if (webServlet.urlPatterns().length > 0) {
- configurator.add(HttpWhiteboardServletPattern.Literal.of(webServlet.urlPatterns()));
- }
- }
-
- if (!annotatedType.isAnnotationPresent(ServiceRanking.class)) {
- configurator.add(ServiceRanking.Literal.of(webServlet.loadOnStartup()));
- }
-
- // TODO Howto: INIT PARAMS ???
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletAsyncSupported.class)) {
- configurator.add(HttpWhiteboardServletAsyncSupported.Literal.of(webServlet.asyncSupported()));
- }
-
- if (!annotatedType.isAnnotationPresent(ServiceDescription.class) && !webServlet.description().isEmpty()) {
- configurator.add(ServiceDescription.Literal.of(webServlet.description()));
- }
-
- if (!annotatedType.isAnnotationPresent(HttpWhiteboardServletMultipart.class)) {
- MultipartConfig multipartConfig = annotatedType.getAnnotation(MultipartConfig.class);
-
- if (multipartConfig != null) {
- configurator.add(HttpWhiteboardServletMultipart.Literal.of(true, multipartConfig.fileSizeThreshold(), multipartConfig.location(), multipartConfig.maxFileSize(), multipartConfig.maxRequestSize()));
- }
- }
-
- // TODO HowTo: ServletSecurity ???
- }
-
-}
diff --git a/cdi-extension-servlet-owb/pom.xml b/cdi-extension-servlet-owb/pom.xml
index 4a709f0..5293e69 100644
--- a/cdi-extension-servlet-owb/pom.xml
+++ b/cdi-extension-servlet-owb/pom.xml
@@ -64,6 +64,11 @@
</dependency>
<dependency>
<groupId>org.apache.aries.cdi</groupId>
+ <artifactId>org.apache.aries.cdi.owb</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.aries.cdi</groupId>
<artifactId>org.apache.aries.cdi.extra</artifactId>
<version>${project.version}</version>
</dependency>
diff --git a/cdi-extension-servlet-owb/src/main/java/org/apache/aries/cdi/extension/servlet/owb/OWBServletExtension.java b/cdi-extension-servlet-owb/src/main/java/org/apache/aries/cdi/extension/servlet/owb/OWBServletExtension.java
index 931cb77..e730189 100644
--- a/cdi-extension-servlet-owb/src/main/java/org/apache/aries/cdi/extension/servlet/owb/OWBServletExtension.java
+++ b/cdi-extension-servlet-owb/src/main/java/org/apache/aries/cdi/extension/servlet/owb/OWBServletExtension.java
@@ -2,9 +2,9 @@
* Licensed 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
- *
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
* 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.
@@ -27,165 +27,126 @@
import java.lang.reflect.Proxy;
import java.util.Dictionary;
import java.util.Hashtable;
-import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Priority;
import javax.enterprise.event.Observes;
import javax.enterprise.inject.spi.AfterDeploymentValidation;
import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.BeforeShutdown;
-import javax.enterprise.inject.spi.Extension;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.WithAnnotations;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestListener;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.annotation.WebListener;
-import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpSessionListener;
-import org.apache.aries.cdi.extension.servlet.common.WebFilterProcessor;
-import org.apache.aries.cdi.extension.servlet.common.WebListenerProcessor;
-import org.apache.aries.cdi.extension.servlet.common.WebServletProcessor;
-import org.apache.aries.cdi.spi.configuration.Configuration;
+import org.apache.aries.cdi.extension.servlet.common.BaseServletExtension;
+import org.apache.aries.cdi.owb.spi.StartObjectSupplier;
import org.apache.webbeans.config.WebBeansContext;
import org.apache.webbeans.spi.ContainerLifecycle;
import org.apache.webbeans.web.lifecycle.test.MockServletContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
@SuppressWarnings("serial")
-public class OWBServletExtension extends ServletContextEvent implements Extension {
+public class OWBServletExtension extends BaseServletExtension implements StartObjectSupplier {
- private final BundleContext bundleContext;
- private final ServletContext proxyContext;
- private volatile ServletContext delegateContext;
- volatile Configuration configuration;
+ private final BundleContext bundleContext;
+ private final ServletContext proxyContext;
+ private final ServletContextEvent startEvent;
+ private volatile ServletContext delegateContext;
- public OWBServletExtension(Bundle bundle) {
- super(new MockServletContext());
+ protected OWBServletExtension() { // proxy
+ bundleContext = null;
+ proxyContext = null;
+ startEvent = null;
+ }
- this.bundleContext = bundle.getBundleContext();
+ public OWBServletExtension(Bundle bundle) {
+ this.startEvent = new ServletContextEvent(new MockServletContext()) {
+ @Override
+ public ServletContext getServletContext() {
+ return proxyContext;
+ }
+ };
- // ensure we can switch the impl and keep ServletContextBean working with an updated context
- this.proxyContext = ServletContext.class.cast(Proxy.newProxyInstance(ServletContext.class.getClassLoader(),
- new Class<?>[]{ServletContext.class},
- (proxy, method, args) -> {
- try {
- return method.invoke(ofNullable(delegateContext).orElseGet(OWBServletExtension.super::getServletContext), args);
- }
- catch (final InvocationTargetException ite) {
- throw ite.getTargetException();
- }
- }));
- }
+ this.bundleContext = bundle.getBundleContext();
- public void setDelegate(final ServletContext delegateContext) {
- this.delegateContext = delegateContext;
- }
+ // ensure we can switch the impl and keep ServletContextBean working with an updated context
+ this.proxyContext = ServletContext.class.cast(Proxy.newProxyInstance(ServletContext.class.getClassLoader(),
+ new Class<?>[]{ServletContext.class},
+ (proxy, method, args) -> {
+ try {
+ return method.invoke(ofNullable(delegateContext).orElseGet(startEvent::getServletContext), args);
+ } catch (final InvocationTargetException ite) {
+ throw ite.getTargetException();
+ }
+ }));
+ }
- public ServletContext getOriginal() {
- return super.getServletContext();
- }
+ public void setDelegate(final ServletContext delegateContext) {
+ this.delegateContext = delegateContext;
+ }
+
+ void afterDeploymentValidation(
+ @Observes @Priority(LIBRARY_AFTER + 800)
+ AfterDeploymentValidation adv, BeanManager beanManager) {
+
+ Dictionary<String, Object> properties = new Hashtable<>();
+ properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension for OpenWebBeans");
+ properties.put(SERVICE_VENDOR, "Apache Software Foundation");
+ properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT));
+ properties.put(HTTP_WHITEBOARD_LISTENER, Boolean.TRUE.toString());
+ properties.put(SERVICE_RANKING, Integer.MAX_VALUE - 100);
+
+ _listenerRegistration = bundleContext.registerService(
+ LISTENER_CLASSES, new CdiListener(WebBeansContext.currentInstance()), properties);
+ }
+
+ private static final String[] LISTENER_CLASSES = new String[]{
+ ServletContextListener.class.getName(),
+ ServletRequestListener.class.getName(),
+ HttpSessionListener.class.getName()
+ };
@Override
- public ServletContext getServletContext() {
- return proxyContext;
+ public Object getStartObject() {
+ return startEvent;
}
- void setConfiguration(@Observes Configuration configuration) {
- this.configuration = configuration;
- }
-
- <X> void webFilter(@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat,
- BeanManager beanManager) {
- new WebFilterProcessor().process(configuration, pat, beanManager);
- }
-
- <X> void webListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat,
- BeanManager beanManager) {
- new WebListenerProcessor().process(configuration, pat, beanManager);
- }
-
- <X> void webServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat,
- BeanManager beanManager) {
- new WebServletProcessor().process(configuration, pat, beanManager);
- }
-
- void afterDeploymentValidation(
- @Observes @Priority(LIBRARY_AFTER + 800)
- AfterDeploymentValidation adv, BeanManager beanManager) {
-
- Dictionary<String, Object> properties = new Hashtable<>();
- properties.put(SERVICE_DESCRIPTION, "Aries CDI - HTTP Portable Extension for OpenWebBeans");
- properties.put(SERVICE_VENDOR, "Apache Software Foundation");
- properties.put(HTTP_WHITEBOARD_CONTEXT_SELECT, configuration.get(HTTP_WHITEBOARD_CONTEXT_SELECT));
- properties.put(HTTP_WHITEBOARD_LISTENER, Boolean.TRUE.toString());
- properties.put(SERVICE_RANKING, Integer.MAX_VALUE - 100);
-
- _listenerRegistration = bundleContext.registerService(
- LISTENER_CLASSES, new CdiListener(WebBeansContext.currentInstance()), properties);
- }
-
- void beforeShutdown(@Observes BeforeShutdown bs) {
- if (_listenerRegistration != null && !destroyed.get()) {
- try {
- _listenerRegistration.unregister();
- }
- catch (IllegalStateException ise) {
- // the service was already unregistered.
- }
- }
- }
-
- private static final String[] LISTENER_CLASSES = new String[] {
- ServletContextListener.class.getName(),
- ServletRequestListener.class.getName(),
- HttpSessionListener.class.getName()
- };
-
- private volatile ServiceRegistration<?> _listenerRegistration;
- private final AtomicBoolean destroyed = new AtomicBoolean(false);
-
private class CdiListener extends org.apache.webbeans.servlet.WebBeansConfigurationListener {
- private final WebBeansContext webBeansContext;
+ private final WebBeansContext webBeansContext;
- private CdiListener(final WebBeansContext webBeansContext) {
- this.webBeansContext = webBeansContext;
- }
+ private CdiListener(final WebBeansContext webBeansContext) {
+ this.webBeansContext = webBeansContext;
+ }
- @Override
- public void contextInitialized(ServletContextEvent event) {
- ServletContext realSC = event.getServletContext();
+ @Override
+ public void contextInitialized(ServletContextEvent event) {
+ ServletContext realSC = event.getServletContext();
- // update the sce to have the real one in CDI
- setDelegate(realSC);
+ // update the sce to have the real one in CDI
+ setDelegate(realSC);
- // propagate attributes from the temporary sc
- list(getOriginal().getAttributeNames()).forEach(
- attr -> realSC.setAttribute(attr, getOriginal().getAttribute(attr)));
+ // propagate attributes from the temporary sc
+ list(startEvent.getServletContext().getAttributeNames()).forEach(
+ attr -> realSC.setAttribute(attr, startEvent.getServletContext().getAttribute(attr)));
- realSC.setAttribute(BundleContext.class.getName(), bundleContext);
- realSC.setAttribute(WebBeansContext.class.getName(), webBeansContext);
+ realSC.setAttribute(BundleContext.class.getName(), bundleContext);
+ realSC.setAttribute(WebBeansContext.class.getName(), webBeansContext);
- // already started in the activator so let's skip it, just ensure it is skipped if re-called
- event.getServletContext().setAttribute(getClass().getName(), true);
- if (lifeCycle == null) {
- lifeCycle = webBeansContext.getService(ContainerLifecycle.class);
- }
- }
+ // already started in the activator so let's skip it, just ensure it is skipped if re-called
+ event.getServletContext().setAttribute(getClass().getName(), true);
+ if (lifeCycle == null) {
+ lifeCycle = webBeansContext.getService(ContainerLifecycle.class);
+ }
+ }
- @Override
- public void contextDestroyed(ServletContextEvent sce) {
- try {
- super.contextDestroyed(sce);
- }
- finally {
- destroyed.set(true);
- }
- }
- }
+ @Override
+ public void contextDestroyed(ServletContextEvent sce) {
+ try {
+ super.contextDestroyed(sce);
+ } finally {
+ destroyed.set(true);
+ }
+ }
+ }
}
diff --git a/cdi-extension-servlet-weld/src/main/java/org/apache/aries/cdi/extension/servlet/weld/WeldServletExtension.java b/cdi-extension-servlet-weld/src/main/java/org/apache/aries/cdi/extension/servlet/weld/WeldServletExtension.java
index db86224..e76e6fe 100644
--- a/cdi-extension-servlet-weld/src/main/java/org/apache/aries/cdi/extension/servlet/weld/WeldServletExtension.java
+++ b/cdi-extension-servlet-weld/src/main/java/org/apache/aries/cdi/extension/servlet/weld/WeldServletExtension.java
@@ -25,7 +25,6 @@
import java.util.Hashtable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Priority;
import javax.enterprise.event.Observes;
@@ -34,58 +33,31 @@
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
-import javax.enterprise.inject.spi.BeforeShutdown;
-import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionTargetFactory;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-import javax.enterprise.inject.spi.WithAnnotations;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
-import javax.servlet.annotation.WebFilter;
-import javax.servlet.annotation.WebListener;
-import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
-import org.apache.aries.cdi.extension.servlet.common.WebFilterProcessor;
-import org.apache.aries.cdi.extension.servlet.common.WebListenerProcessor;
-import org.apache.aries.cdi.extension.servlet.common.WebServletProcessor;
-import org.apache.aries.cdi.spi.configuration.Configuration;
+import org.apache.aries.cdi.extension.servlet.common.BaseServletExtension;
import org.jboss.weld.module.web.servlet.WeldInitialListener;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceRegistration;
-public class WeldServletExtension implements Extension {
+public class WeldServletExtension extends BaseServletExtension {
private final BundleContext bundleContext;
- volatile Configuration configuration;
+
+ protected WeldServletExtension() { // proxy
+ bundleContext = null;
+ }
public WeldServletExtension(Bundle bundle) {
this.bundleContext = bundle.getBundleContext();
}
- void setConfiguration(@Observes Configuration configuration) {
- this.configuration = configuration;
- }
-
- <X> void webFilter(@Observes @WithAnnotations(WebFilter.class) ProcessAnnotatedType<X> pat,
- BeanManager beanManager) {
- new WebFilterProcessor().process(configuration, pat, beanManager);
- }
-
- <X> void webListener(@Observes @WithAnnotations(WebListener.class) ProcessAnnotatedType<X> pat,
- BeanManager beanManager) {
- new WebListenerProcessor().process(configuration, pat, beanManager);
- }
-
- <X> void webServlet(@Observes @WithAnnotations(WebServlet.class) ProcessAnnotatedType<X> pat,
- BeanManager beanManager) {
- new WebServletProcessor().process(configuration, pat, beanManager);
- }
-
void afterDeploymentValidation(
@Observes @Priority(LIBRARY_AFTER + 800)
AfterDeploymentValidation adv, BeanManager beanManager) {
@@ -114,26 +86,12 @@
LISTENER_CLASSES, new ListenerWrapper<>(initialListener), properties);
}
- void beforeShutdown(@Observes BeforeShutdown bs) {
- if (_listenerRegistration != null && !destroyed.get()) {
- try {
- _listenerRegistration.unregister();
- }
- catch (IllegalStateException ise) {
- // the service was already unregistered.
- }
- }
- }
-
private static final String[] LISTENER_CLASSES = new String[] {
ServletContextListener.class.getName(),
ServletRequestListener.class.getName(),
HttpSessionListener.class.getName()
};
- private volatile ServiceRegistration<?> _listenerRegistration;
- private final AtomicBoolean destroyed = new AtomicBoolean(false);
-
public static class Ready {}
private class ListenerWrapper<T extends HttpSessionListener & ServletContextListener & ServletRequestListener>
diff --git a/cdi-extension-spi/pom.xml b/cdi-extension-spi/pom.xml
index f010ece..3f1ff20 100644
--- a/cdi-extension-spi/pom.xml
+++ b/cdi-extension-spi/pom.xml
@@ -59,6 +59,10 @@
<artifactId>geronimo-jcdi_2.0_spec</artifactId>
</dependency>
<dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-atinject_1.0_spec</artifactId>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.service.cdi</artifactId>
</dependency>
diff --git a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/FiltersOn.java b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/FiltersOn.java
new file mode 100644
index 0000000..573dbd4
--- /dev/null
+++ b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/FiltersOn.java
@@ -0,0 +1,57 @@
+/**
+ * Licensed 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.apache.aries.cdi.extension.spi.adapt;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.enterprise.util.AnnotationLiteral;
+
+/**
+ * Close of {@link javax.enterprise.inject.spi.WithAnnotations} but for {@link ProcessPotentialService} event.
+ * Enables to filter the observed annotated types.
+ */
+@Target(ElementType.PARAMETER)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface FiltersOn {
+ /**
+ * @return the annotations the {@link javax.enterprise.inject.spi.ProcessAnnotatedType} should get filtered for.
+ */
+ Class<? extends Annotation>[] annotations() default {FiltersOn.class};
+
+ /**
+ * @return the types to filter the event on using {@link Class#isAssignableFrom(Class)}.
+ */
+ Class<?>[] types() default {FiltersOn.class};
+
+ class Literal extends AnnotationLiteral<FiltersOn> implements FiltersOn {
+ public static final Literal INSTANCE = new Literal();
+
+ private final Class[] defaultArray = new Class[0];
+
+ @Override
+ public Class<? extends Annotation>[] annotations() {
+ return defaultArray;
+ }
+
+ @Override
+ public Class<?>[] types() {
+ return defaultArray;
+ }
+ }
+}
+
diff --git a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/MergeServiceTypes.java b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/MergeServiceTypes.java
index e163269..a96e12e 100644
--- a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/MergeServiceTypes.java
+++ b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/MergeServiceTypes.java
@@ -17,11 +17,16 @@
import javax.enterprise.inject.spi.ProcessAnnotatedType;
-public class MergeServiceTypes<T> {
+/**
+ * If fired (using the {@link javax.enterprise.inject.spi.BeanManager}) during a {@link ProcessAnnotatedType} event,
+ * it will configure the annotated type to add {@link org.apache.aries.cdi.extension.spi.annotation.AdaptedService}
+ * with the referenced types - potentially merged with already existing ones.
+ */
+public class MergeServiceTypes {
private final Class<?>[] types;
- private final ProcessAnnotatedType<T> processAnnotatedType;
+ private final ProcessAnnotatedType<?> processAnnotatedType;
- public MergeServiceTypes(final ProcessAnnotatedType<T> processAnnotatedType,
+ private MergeServiceTypes(final ProcessAnnotatedType<?> processAnnotatedType,
final Class<?>... types) {
this.types = types;
this.processAnnotatedType = processAnnotatedType;
@@ -31,7 +36,7 @@
return types;
}
- public ProcessAnnotatedType<T> getProcessAnnotatedType() {
+ public ProcessAnnotatedType<?> getProcessAnnotatedType() {
return processAnnotatedType;
}
@@ -39,4 +44,36 @@
public String toString() {
return "MergeServiceTypes{types=" + Arrays.toString(types) + '}';
}
+
+ public static Builder forEvent(final ProcessAnnotatedType<?> pat) {
+ return new Builder(pat);
+ }
+
+ public static Builder forEvent(final ProcessPotentialService pat) {
+ return new Builder(pat.getProcessAnnotatedType());
+ }
+
+ public static final class Builder {
+ private final ProcessAnnotatedType<?> processAnnotatedType;
+ private Class<?>[] types;
+
+ private Builder(final ProcessAnnotatedType<?> processAnnotatedType) {
+ if (processAnnotatedType == null) {
+ throw new IllegalArgumentException("processAnnotatedType can't be null");
+ }
+ this.processAnnotatedType = processAnnotatedType;
+ }
+
+ public Builder withTypes(final Class<?>... types) {
+ this.types = types;
+ return this;
+ }
+
+ public MergeServiceTypes build() {
+ if (types == null) {
+ throw new IllegalArgumentException("No types set");
+ }
+ return new MergeServiceTypes(processAnnotatedType, types);
+ }
+ }
}
diff --git a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/ProcessPotentialService.java b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/ProcessPotentialService.java
new file mode 100644
index 0000000..4303f74
--- /dev/null
+++ b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/ProcessPotentialService.java
@@ -0,0 +1,49 @@
+/**
+ * Licensed 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.apache.aries.cdi.extension.spi.adapt;
+
+import static java.util.Objects.requireNonNull;
+
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.enterprise.inject.spi.configurator.AnnotatedTypeConfigurator;
+
+/**
+ * Can be observed in an extension to customize an annotated type without
+ * {@link org.osgi.service.cdi.annotations.Service} marker.
+ */
+public class ProcessPotentialService {
+ private final ProcessAnnotatedType<?> processAnnotatedType;
+
+ public ProcessPotentialService(final ProcessAnnotatedType<?> processAnnotatedType) {
+ this.processAnnotatedType = requireNonNull(processAnnotatedType, "processAnnotatedType can't be null");
+ }
+
+ public ProcessAnnotatedType<?> getProcessAnnotatedType() {
+ return processAnnotatedType;
+ }
+
+ public AnnotatedType<?> getAnnotatedType() {
+ return processAnnotatedType.getAnnotatedType();
+ }
+
+ public AnnotatedTypeConfigurator<?> configureAnnotatedType() {
+ return processAnnotatedType.configureAnnotatedType();
+ }
+
+ @Override
+ public String toString() {
+ return "ProcessPotentialService{processAnnotatedType=" + processAnnotatedType + '}';
+ }
+}
diff --git a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/RegisterExtension.java b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/RegisterExtension.java
new file mode 100644
index 0000000..f352716
--- /dev/null
+++ b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/adapt/RegisterExtension.java
@@ -0,0 +1,109 @@
+/**
+ * Licensed 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.apache.aries.cdi.extension.spi.adapt;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
+import static java.util.Collections.unmodifiableList;
+
+import java.lang.annotation.Annotation;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.BiConsumer;
+
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+
+/**
+ * If fired (using the {@link javax.enterprise.inject.spi.BeanManager})
+ * during a {@link javax.enterprise.inject.spi.BeforeBeanDiscovery} event,
+ * it will enable to filter {@link ProcessAnnotatedType} event and convert them to {@link ProcessPotentialService}
+ * event with {@link FiltersOn} support.
+ */
+public class RegisterExtension {
+ private final Extension extension;
+ private final Collection<ObserverBuilder> builders = new ArrayList<>();
+
+ public RegisterExtension(final Extension extension) {
+ this.extension = extension;
+ }
+
+ public Extension getExtension() {
+ return extension;
+ }
+
+ public Collection<ObserverBuilder> getBuilders() {
+ return builders;
+ }
+
+ public ObserverBuilder registerObserver() {
+ return new ObserverBuilder(this);
+ }
+
+ public static class ObserverBuilder {
+ private final RegisterExtension parent;
+
+ // defaults aligned on the annotation to have a single impl
+ private List<Class<?>> types = new ArrayList<>(singletonList(FiltersOn.class));
+ private List<Class<? extends Annotation>> annotations = new ArrayList<>(singletonList(FiltersOn.class));
+ private BiConsumer<BeanManager, ProcessPotentialService> consumer;
+
+ private ObserverBuilder(final RegisterExtension parent) {
+ this.parent = parent;
+ }
+
+ public ObserverBuilder forTypes(final Class<?>... types) {
+ if (types.length > 0) {
+ this.types.remove(FiltersOn.class);
+ }
+ this.types.addAll(asList(types));
+ return this;
+ }
+
+ public ObserverBuilder forAnnotations(final Class<? extends Annotation>... annotations) {
+ if (annotations.length > 0) {
+ this.annotations.remove(FiltersOn.class);
+ }
+ this.annotations.addAll(asList(annotations));
+ return this;
+ }
+
+ public ObserverBuilder execute(final BiConsumer<BeanManager, ProcessPotentialService> consumer) {
+ this.consumer = consumer;
+ return this;
+ }
+
+ public Collection<Class<?>> getTypes() {
+ return unmodifiableList(types);
+ }
+
+ public Collection<Class<?>> getAnnotations() {
+ return unmodifiableList(annotations);
+ }
+
+ public BiConsumer<BeanManager, ProcessPotentialService> getConsumer() {
+ return consumer;
+ }
+
+ public RegisterExtension done() {
+ if (consumer == null) {
+ throw new IllegalArgumentException("No consumer registered on observer builder");
+ }
+ parent.builders.add(this);
+ return parent;
+ }
+ }
+}
diff --git a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/annotation/AdaptedService.java b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/annotation/AdaptedService.java
index b7a22fc..35479d2 100644
--- a/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/annotation/AdaptedService.java
+++ b/cdi-extension-spi/src/main/java/org/apache/aries/cdi/extension/spi/annotation/AdaptedService.java
@@ -37,16 +37,16 @@
/**
* Support inline instantiation of the {@link AdaptedService} annotation.
*/
- public static final class Literal extends AnnotationLiteral<AdaptedService>
+ final class Literal extends AnnotationLiteral<AdaptedService>
implements AdaptedService {
private static final long serialVersionUID = 1L;
/**
- * @param interfaces
+ * @param interfaces value.
* @return instance of {@link AdaptedService}
*/
- public static final Literal of(Class<?>[] interfaces) {
+ public static Literal of(Class<?>[] interfaces) {
return new Literal(interfaces);
}
diff --git a/cdi-itests/owb-itest.bndrun b/cdi-itests/owb-itest.bndrun
index c614a4d..edef0c5 100644
--- a/cdi-itests/owb-itest.bndrun
+++ b/cdi-itests/owb-itest.bndrun
@@ -33,7 +33,6 @@
org.apache.aries.cdi.extension.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.extra;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.itests;version='[1.1.0,1.1.1)',\
- org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)',\
org.apache.aries.cdi.spi;version='[1.1.0,1.1.1)',\
org.apache.aries.jax.rs.whiteboard;version='[1.0.6,1.0.7)',\
org.apache.aries.jndi.api;version='[1.1.0,1.1.1)',\
@@ -64,4 +63,5 @@
org.osgi.test.common;version='[1.0.0,1.0.1)',\
org.osgi.test.junit4;version='[1.0.0,1.0.1)',\
org.osgi.util.function;version='[1.1.0,1.1.1)',\
- org.osgi.util.promise;version='[1.1.0,1.1.1)'
+ org.osgi.util.promise;version='[1.1.0,1.1.1)',\
+ org.apache.aries.cdi.owb;version='[1.1.0,1.1.1)'
diff --git a/cdi-owb/pom.xml b/cdi-owb/pom.xml
index e4de12d..14b1fcd 100644
--- a/cdi-owb/pom.xml
+++ b/cdi-owb/pom.xml
@@ -52,7 +52,6 @@
<configuration>
<bnd><![CDATA[
-cdiannotations:
- -noclassforname: true
]]></bnd>
</configuration>
</plugin>
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/Activator.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/Activator.java
similarity index 97%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/Activator.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/Activator.java
index 91e8fb3..9680f5f 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/Activator.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/Activator.java
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
import static org.osgi.framework.Constants.BUNDLE_ACTIVATOR;
import static org.osgi.framework.Constants.SERVICE_DESCRIPTION;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/CdiScannerService.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/CdiScannerService.java
similarity index 97%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/CdiScannerService.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/CdiScannerService.java
index 0a6bc04..0274fec 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/CdiScannerService.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/CdiScannerService.java
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
import static java.util.Collections.emptySet;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OSGiDefiningClassService.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OSGiDefiningClassService.java
similarity index 98%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/OSGiDefiningClassService.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OSGiDefiningClassService.java
index 8186eb7..a04ae37 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OSGiDefiningClassService.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OSGiDefiningClassService.java
@@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
import java.lang.reflect.Modifier;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializer.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OWBCDIContainerInitializer.java
similarity index 92%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializer.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OWBCDIContainerInitializer.java
index fc665d7..1b34f7b 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializer.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OWBCDIContainerInitializer.java
@@ -12,11 +12,11 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
+import static java.util.Comparator.comparing;
import static java.util.Objects.requireNonNull;
import static org.osgi.framework.namespace.PackageNamespace.PACKAGE_NAMESPACE;
-import static org.osgi.service.cdi.CDIConstants.CDI_EXTENSION_PROPERTY;
import java.io.IOException;
import java.lang.annotation.Annotation;
@@ -39,6 +39,7 @@
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.util.TypeLiteral;
+import org.apache.aries.cdi.owb.spi.StartObjectSupplier;
import org.apache.aries.cdi.spi.CDIContainerInitializer;
import org.apache.aries.cdi.spi.loader.SpiLoader;
import org.apache.webbeans.config.WebBeansContext;
@@ -152,17 +153,17 @@
// This Extension will have properties:
// osgi.cdi.extension = aries.cdi.http
// aries.cdi.http.provider = OpenWebBeans
- extensions.entrySet().stream().filter(
- e -> "aries.cdi.http".equals(e.getValue().get(CDI_EXTENSION_PROPERTY)) &&
- "OpenWebBeans".equalsIgnoreCase(String.valueOf(e.getValue().get("aries.cdi.http.provider")))
- ).findFirst().ifPresent(entry -> {
- // The service properties of the extension should list any properties needed
- // to configure OWB for web support.
- properties.putAll(entry.getValue());
+ extensions.entrySet().stream()
+ .filter(it -> StartObjectSupplier.class.isInstance(it.getKey()))
+ .max(comparing(it -> StartObjectSupplier.class.cast(it.getKey()).ordinal()))
+ .ifPresent(entry -> {
+ // The service properties of the extension should list any properties needed
+ // to configure OWB for web support.
+ properties.putAll(entry.getValue());
- // The extension itself implements ServletContextEvent so set as the start object
- startObject = entry.getKey();
- });
+ // Extract the start instance to ensure it works with the configured services (properties)
+ startObject = StartObjectSupplier.class.cast(entry.getKey()).getStartObject();
+ });
bootstrap = new WebBeansContext(services, properties) {
private final ExtensionLoader overridenExtensionLoader = new ExtensionLoader(this) {
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializerFactory.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OWBCDIContainerInitializerFactory.java
similarity index 97%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializerFactory.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OWBCDIContainerInitializerFactory.java
index db10ecd..c8f973b 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OWBCDIContainerInitializerFactory.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OWBCDIContainerInitializerFactory.java
@@ -12,7 +12,7 @@
* limitations under the License.
*/
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
import org.apache.aries.cdi.spi.CDIContainerInitializer;
import org.osgi.framework.Bundle;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OsgiApplicationBoundaryService.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OsgiApplicationBoundaryService.java
similarity index 97%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/OsgiApplicationBoundaryService.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OsgiApplicationBoundaryService.java
index b3985f9..b254bdb 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/OsgiApplicationBoundaryService.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/OsgiApplicationBoundaryService.java
@@ -11,7 +11,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
import org.apache.webbeans.spi.ApplicationBoundaryService;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/package-info.java
similarity index 95%
rename from cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
rename to cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/package-info.java
index 5e523d8..25a6297 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/core/package-info.java
@@ -17,4 +17,4 @@
namespace = org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE
)
@org.osgi.service.cdi.annotations.RequireCDIImplementation
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.core;
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/spi/StartObjectSupplier.java
similarity index 64%
copy from cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
copy to cdi-owb/src/main/java/org/apache/aries/cdi/owb/spi/StartObjectSupplier.java
index 5e523d8..a4590f3 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/spi/StartObjectSupplier.java
@@ -11,10 +11,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+package org.apache.aries.cdi.owb.spi;
-@org.osgi.annotation.bundle.Capability(
- attribute = "objectClass:List<String>=org.apache.aries.cdi.spi.CDIContainerInitializer",
- namespace = org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE
-)
-@org.osgi.service.cdi.annotations.RequireCDIImplementation
-package org.apache.aries.cdi.owb;
+public interface StartObjectSupplier<T> {
+ T getStartObject();
+
+ default int ordinal() {
+ return 0;
+ }
+}
diff --git a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/spi/package-info.java
similarity index 72%
copy from cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
copy to cdi-owb/src/main/java/org/apache/aries/cdi/owb/spi/package-info.java
index 5e523d8..4dfef30 100644
--- a/cdi-owb/src/main/java/org/apache/aries/cdi/owb/package-info.java
+++ b/cdi-owb/src/main/java/org/apache/aries/cdi/owb/spi/package-info.java
@@ -12,9 +12,8 @@
* limitations under the License.
*/
-@org.osgi.annotation.bundle.Capability(
- attribute = "objectClass:List<String>=org.apache.aries.cdi.spi.CDIContainerInitializer",
- namespace = org.osgi.namespace.service.ServiceNamespace.SERVICE_NAMESPACE
-)
+@Export
@org.osgi.service.cdi.annotations.RequireCDIImplementation
-package org.apache.aries.cdi.owb;
+package org.apache.aries.cdi.owb.spi;
+
+import org.osgi.annotation.bundle.Export;
\ No newline at end of file