reta closed pull request #329: CXF-7501: Cannot inject field in 
ContainerRequestFilter (and generally, into any providers registered using 
FeatureContext)
URL: https://github.com/apache/cxf/pull/329
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/integration/cdi/src/main/java/org/apache/cxf/cdi/CdiServerConfigurableFactory.java
 
b/integration/cdi/src/main/java/org/apache/cxf/cdi/CdiServerConfigurableFactory.java
new file mode 100644
index 00000000000..15d4643d847
--- /dev/null
+++ 
b/integration/cdi/src/main/java/org/apache/cxf/cdi/CdiServerConfigurableFactory.java
@@ -0,0 +1,91 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.cdi;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanAttributes;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTargetFactory;
+import javax.ws.rs.RuntimeType;
+import javax.ws.rs.core.Configurable;
+import javax.ws.rs.core.FeatureContext;
+
+import org.apache.cxf.cdi.event.DisposableCreationalContext;
+import org.apache.cxf.jaxrs.impl.ConfigurableImpl;
+import org.apache.cxf.jaxrs.impl.ConfigurableImpl.Instantiator;
+import org.apache.cxf.jaxrs.provider.ServerConfigurableFactory;
+
+/** 
+ * Creates the instance of Configurable<?> suitable for CDI-managed runtime.
+ */
+public class CdiServerConfigurableFactory implements ServerConfigurableFactory 
{
+    private final BeanManager beanManager;
+    
+    CdiServerConfigurableFactory(final BeanManager beanManager) {
+        this.beanManager = beanManager;
+    }
+    
+    @Override
+    public Configurable<FeatureContext> create(FeatureContext context) {
+        return new CdiServerFeatureContextConfigurable(context, beanManager);
+    }
+    
+    /** 
+     * Instantiates the instance of the provider using CDI/BeanManager 
+     */
+    private static class CdiInstantiator implements Instantiator {
+        private final BeanManager beanManager;
+        
+        CdiInstantiator(final BeanManager beanManager) {
+            this.beanManager = beanManager;
+        }
+        
+        @Override
+        public <T> Object create(Class<T> cls) {
+            final AnnotatedType<T> annotatedType = 
beanManager.createAnnotatedType(cls);
+            final InjectionTargetFactory<T> injectionTargetFactory = 
+                beanManager.getInjectionTargetFactory(annotatedType);
+            final BeanAttributes<T> attributes = 
beanManager.createBeanAttributes(annotatedType);
+            final Bean<T> bean = beanManager.createBean(attributes, cls, 
injectionTargetFactory);
+            final CreationalContext<?> context = 
beanManager.createCreationalContext(bean);
+            
+            if (!beanManager.isNormalScope(bean.getScope())) {
+                beanManager.fireEvent(new 
DisposableCreationalContext(context));
+            }
+            
+            return beanManager.getReference(bean, cls, context);
+        }
+    }
+    
+    private static class CdiServerFeatureContextConfigurable extends 
ConfigurableImpl<FeatureContext> {
+        private final Instantiator instantiator;
+        
+        CdiServerFeatureContextConfigurable(FeatureContext mc, BeanManager 
beanManager) {
+            super(mc, RuntimeType.SERVER, SERVER_FILTER_INTERCEPTOR_CLASSES);
+            this.instantiator = new CdiInstantiator(beanManager);
+        }
+        
+        @Override
+        protected Instantiator getInstantiator() {
+            return instantiator;
+        }
+    }
+}
diff --git 
a/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
 
b/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
index 2a36a3a4877..ce23e1a924c 100644
--- 
a/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
+++ 
b/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java
@@ -49,9 +49,11 @@
 
 import org.apache.cxf.Bus;
 import org.apache.cxf.bus.extension.ExtensionManagerBus;
+import org.apache.cxf.cdi.event.DisposableCreationalContext;
 import org.apache.cxf.cdi.extension.JAXRSServerFactoryCustomizationExtension;
 import org.apache.cxf.feature.Feature;
 import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.provider.ServerConfigurableFactory;
 import org.apache.cxf.jaxrs.utils.ResourceUtils;
 
 /**
@@ -138,6 +140,11 @@ public void load(@Observes final AfterDeploymentValidation 
event, final BeanMana
                 busBean,
                 Bus.class,
                 beanManager.createCreationalContext(busBean));
+        
+        // Adding the extension for dynamic providers registration and 
instantiation
+        if (bus.getExtension(ServerConfigurableFactory.class) == null) {
+            bus.setExtension(new CdiServerConfigurableFactory(beanManager), 
ServerConfigurableFactory.class);
+        }
 
         for (final Bean< ? > application: applicationBeans) {
             final Application instance = (Application)beanManager.getReference(
@@ -182,11 +189,22 @@ public void injectBus(@Observes final AfterBeanDiscovery 
event, final BeanManage
     }
 
     /**
+     * Registers created CreationalContext instances for disposal
+     */
+    public void registerCreationalContextForDisposal(@Observes final 
DisposableCreationalContext event) {
+        synchronized (disposableCreationalContexts) {
+            disposableCreationalContexts.add(event.getContext());
+        }
+    }
+    
+    /**
      * Releases created CreationalContext instances
      */
     public void release(@Observes final BeforeShutdown event) {
-        for (final CreationalContext<?> disposableCreationalContext: 
disposableCreationalContexts) {
-            disposableCreationalContext.release();
+        synchronized (disposableCreationalContexts) {
+            for (final CreationalContext<?> disposableCreationalContext: 
disposableCreationalContexts) {
+                disposableCreationalContext.release();
+            }
         }
     }
 
@@ -375,9 +393,13 @@ private void customize(final BeanManager beanManager, 
final JAXRSServerFactoryBe
      */
     private<T> CreationalContext< T > createCreationalContext(final 
BeanManager beanManager, Bean< T > bean) {
         final CreationalContext< T > creationalContext = 
beanManager.createCreationalContext(bean);
+        
         if (!(bean instanceof DefaultApplicationBean)) {
-            disposableCreationalContexts.add(creationalContext);
+            synchronized (disposableCreationalContexts) {
+                disposableCreationalContexts.add(creationalContext);
+            }
         }
+        
         return creationalContext;
     }
 
diff --git 
a/integration/cdi/src/main/java/org/apache/cxf/cdi/event/DisposableCreationalContext.java
 
b/integration/cdi/src/main/java/org/apache/cxf/cdi/event/DisposableCreationalContext.java
new file mode 100644
index 00000000000..0944e4a057f
--- /dev/null
+++ 
b/integration/cdi/src/main/java/org/apache/cxf/cdi/event/DisposableCreationalContext.java
@@ -0,0 +1,34 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.cdi.event;
+
+import javax.enterprise.context.spi.CreationalContext;
+
+public class DisposableCreationalContext {
+    private final CreationalContext<?> context;
+    
+    public DisposableCreationalContext(CreationalContext<?> context) {
+        this.context = context;
+    }
+    
+    public CreationalContext<?> getContext() {
+        return context;
+    }
+}
diff --git 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
index 9be144d0a55..54540272018 100644
--- 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
+++ 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/impl/ConfigurableImpl.java
@@ -31,12 +31,17 @@
 
 public class ConfigurableImpl<C extends Configurable<C>> implements 
Configurable<C> {
     private ConfigurationImpl config;
-    private C configurable;
-    private Class<?>[] supportedProviderClasses;
+    private final C configurable;
+    private final Class<?>[] supportedProviderClasses;
+    
+    public interface Instantiator {
+        <T> Object create(Class<T> cls);
+    }
+    
     public ConfigurableImpl(C configurable, RuntimeType rt, Class<?>[] 
supportedProviderClasses) {
         this(configurable, supportedProviderClasses, new 
ConfigurationImpl(rt));
     }
-
+    
     public ConfigurableImpl(C configurable, Class<?>[] 
supportedProviderClasses, Configuration config) {
         this(configurable, supportedProviderClasses);
         this.config = config instanceof ConfigurationImpl
@@ -98,8 +103,7 @@ public C register(Class<?> providerClass) {
 
     @Override
     public C register(Class<?> providerClass, int bindingPriority) {
-        return doRegister(ConfigurationImpl.createProvider(providerClass),
-                          bindingPriority, supportedProviderClasses);
+        return doRegister(getInstantiator().create(providerClass), 
bindingPriority, supportedProviderClasses);
     }
 
     @Override
@@ -109,7 +113,11 @@ public C register(Class<?> providerClass, Class<?>... 
contracts) {
 
     @Override
     public C register(Class<?> providerClass, Map<Class<?>, Integer> 
contracts) {
-        return register(ConfigurationImpl.createProvider(providerClass), 
contracts);
+        return register(getInstantiator().create(providerClass), contracts);
+    }
+    
+    protected Instantiator getInstantiator() {
+        return ConfigurationImpl::createProvider;
     }
 
     private C doRegister(Object provider, int bindingPriority, Class<?>... 
contracts) {
diff --git 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerConfigurableFactory.java
 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerConfigurableFactory.java
new file mode 100644
index 00000000000..f4e9ef8e955
--- /dev/null
+++ 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerConfigurableFactory.java
@@ -0,0 +1,42 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.jaxrs.provider;
+
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.Configurable;
+import javax.ws.rs.core.FeatureContext;
+import javax.ws.rs.ext.ReaderInterceptor;
+import javax.ws.rs.ext.WriterInterceptor;
+
+/**
+ * Manages the creation of server-side Configurable<FeatureContext> depending 
on 
+ * the presence of managed runtime (like CDI f.e.). 
+ */
+public interface ServerConfigurableFactory {
+    Class<?>[] SERVER_FILTER_INTERCEPTOR_CLASSES = new Class<?>[] {
+        ContainerRequestFilter.class,
+        ContainerResponseFilter.class,
+        ReaderInterceptor.class,
+        WriterInterceptor.class 
+    };
+    
+    Configurable<FeatureContext> create(FeatureContext context);
+}
diff --git 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
index dbacd48c3a1..dda7ee290d3 100644
--- 
a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
+++ 
b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/provider/ServerProviderFactory.java
@@ -21,11 +21,9 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
@@ -40,6 +38,7 @@
 import javax.ws.rs.container.ContainerResponseFilter;
 import javax.ws.rs.container.DynamicFeature;
 import javax.ws.rs.container.PreMatching;
+import javax.ws.rs.core.Configurable;
 import javax.ws.rs.core.Configuration;
 import javax.ws.rs.core.Feature;
 import javax.ws.rs.core.FeatureContext;
@@ -72,12 +71,6 @@
 import org.apache.cxf.message.MessageUtils;
 
 public final class ServerProviderFactory extends ProviderFactory {
-    private static final Set<Class<?>> SERVER_FILTER_INTERCEPTOR_CLASSES =
-        new 
HashSet<Class<?>>(Arrays.<Class<?>>asList(ContainerRequestFilter.class,
-                                                      
ContainerResponseFilter.class,
-                                                      ReaderInterceptor.class,
-                                                      
WriterInterceptor.class));
-
     private static final String WADL_PROVIDER_NAME = 
"org.apache.cxf.jaxrs.model.wadl.WadlGenerator";
     private static final String MAKE_DEFAULT_WAE_LEAST_SPECIFIC = 
"default.wae.mapper.least.specific";
     private List<ProviderInfo<ExceptionMapper<?>>> exceptionMappers =
@@ -399,8 +392,11 @@ private void doApplyDynamicFeatures(ClassResourceInfo cri) 
{
     }
 
     private FeatureContext createServerFeatureContext() {
-        FeatureContextImpl featureContext = new FeatureContextImpl();
-        ServerFeatureContextConfigurable configImpl = new 
ServerFeatureContextConfigurable(featureContext);
+        final FeatureContextImpl featureContext = new FeatureContextImpl();
+        final ServerConfigurableFactory factory = 
getBus().getExtension(ServerConfigurableFactory.class);
+        final Configurable<FeatureContext> configImpl = (factory == null) 
+            ? new ServerFeatureContextConfigurable(featureContext) 
+                : factory.create(featureContext);
         featureContext.setConfigurable(configImpl);
 
         if (application != null) {
@@ -418,7 +414,7 @@ protected static boolean isPrematching(Class<?> filterCls) {
 
     private static class ServerFeatureContextConfigurable extends 
ConfigurableImpl<FeatureContext> {
         protected ServerFeatureContextConfigurable(FeatureContext mc) {
-            super(mc, RuntimeType.SERVER, 
SERVER_FILTER_INTERCEPTOR_CLASSES.toArray(new Class<?>[]{}));
+            super(mc, RuntimeType.SERVER, 
ServerConfigurableFactory.SERVER_FILTER_INTERCEPTOR_CLASSES);
         }
     }
 
diff --git 
a/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/BookStoreAuthenticator.java
 
b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/BookStoreAuthenticator.java
new file mode 100644
index 00000000000..d2448cec54b
--- /dev/null
+++ 
b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/BookStoreAuthenticator.java
@@ -0,0 +1,33 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systests.cdi.base;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Named;
+
+@Named @ApplicationScoped
+public class BookStoreAuthenticator {
+    public BookStoreAuthenticator() {
+        
+    }
+    
+    public boolean authenticated() {
+        return true;
+    }
+}
diff --git 
a/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/BookStoreRequestFilter.java
 
b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/BookStoreRequestFilter.java
new file mode 100644
index 00000000000..cbd88115afe
--- /dev/null
+++ 
b/systests/cdi/base/src/main/java/org/apache/cxf/systests/cdi/base/BookStoreRequestFilter.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.cxf.systests.cdi.base;
+
+import java.io.IOException;
+
+import javax.inject.Inject;
+import javax.ws.rs.container.ContainerRequestContext;
+import javax.ws.rs.container.ContainerRequestFilter;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.Response.Status;
+
+public class BookStoreRequestFilter implements ContainerRequestFilter {
+    @Inject private BookStoreAuthenticator authenticator;
+    
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws 
IOException {
+        if (!authenticator.authenticated()) {
+            
requestContext.abortWith(Response.status(Status.UNAUTHORIZED).build());
+        }
+    }
+}
diff --git 
a/systests/cdi/cdi-owb/cdi-producers-owb/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
 
b/systests/cdi/cdi-owb/cdi-producers-owb/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
index 6a108dc1834..ba340825828 100644
--- 
a/systests/cdi/cdi-owb/cdi-producers-owb/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
+++ 
b/systests/cdi/cdi-owb/cdi-producers-owb/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
@@ -23,11 +23,13 @@
 import javax.ws.rs.core.FeatureContext;
 
 import org.apache.cxf.jaxrs.provider.atom.AtomFeedProvider;
+import org.apache.cxf.systests.cdi.base.BookStoreRequestFilter;
 
 public class SampleFeature implements Feature {
     @Override
     public boolean configure(FeatureContext context) {
         context.register(AtomFeedProvider.class);
+        context.register(BookStoreRequestFilter.class);
         return false;
     }
 }
diff --git 
a/systests/cdi/cdi-weld/cdi-producers-weld/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
 
b/systests/cdi/cdi-weld/cdi-producers-weld/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
index 6a108dc1834..ba340825828 100644
--- 
a/systests/cdi/cdi-weld/cdi-producers-weld/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
+++ 
b/systests/cdi/cdi-weld/cdi-producers-weld/src/test/java/org/apache/cxf/systest/jaxrs/cdi/SampleFeature.java
@@ -23,11 +23,13 @@
 import javax.ws.rs.core.FeatureContext;
 
 import org.apache.cxf.jaxrs.provider.atom.AtomFeedProvider;
+import org.apache.cxf.systests.cdi.base.BookStoreRequestFilter;
 
 public class SampleFeature implements Feature {
     @Override
     public boolean configure(FeatureContext context) {
         context.register(AtomFeedProvider.class);
+        context.register(BookStoreRequestFilter.class);
         return false;
     }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to