openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject svn commit: r1797826 - in /openwebbeans/meecrowave/trunk/meecrowave-core/src: main/java/org/apache/meecrowave/cxf/ main/java/org/apache/meecrowave/openwebbeans/ main/resources/META-INF/services/ test/java/org/apache/meecrowave/
Date Tue, 06 Jun 2017 21:20:51 GMT
Author: rmannibucau
Date: Tue Jun  6 21:20:51 2017
New Revision: 1797826

URL: http://svn.apache.org/viewvc?rev=1797826&view=rev
Log:
MEECROWAVE-37 fixing @Context for fields in cdi proxies

Added:
    openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/cxf/JAXRSFieldInjectionInterceptor.java
    openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveExtension.java
      - copied, changed from r1797825, openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveBeansExtension.java
    openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ContextInProxiedInstancesTest.java
Removed:
    openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveBeansExtension.java
Modified:
    openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java
    openwebbeans/meecrowave/trunk/meecrowave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
    openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/InstanceCustomizerTest.java

Added: openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/cxf/JAXRSFieldInjectionInterceptor.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/cxf/JAXRSFieldInjectionInterceptor.java?rev=1797826&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/cxf/JAXRSFieldInjectionInterceptor.java
(added)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/cxf/JAXRSFieldInjectionInterceptor.java
Tue Jun  6 21:20:51 2017
@@ -0,0 +1,108 @@
+/**
+ * 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.meecrowave.cxf;
+
+import org.apache.cxf.jaxrs.model.ApplicationInfo;
+import org.apache.cxf.jaxrs.model.OperationResourceInfoStack;
+import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.JAXRSUtils;
+import org.apache.cxf.message.Message;
+import org.apache.webbeans.annotation.EmptyAnnotationLiteral;
+import org.apache.webbeans.intercept.ConstructorInterceptorInvocationContext;
+
+import javax.annotation.Priority;
+import javax.interceptor.AroundConstruct;
+import javax.interceptor.AroundInvoke;
+import javax.interceptor.Interceptor;
+import javax.interceptor.InterceptorBinding;
+import javax.interceptor.InvocationContext;
+import javax.ws.rs.core.Application;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Interceptor
+@Priority(Interceptor.Priority.PLATFORM_BEFORE)
+@JAXRSFieldInjectionInterceptor.Binding
+public class JAXRSFieldInjectionInterceptor implements Serializable {
+    private final AtomicBoolean injected = new AtomicBoolean();
+
+    @AroundConstruct
+    public Object injectContexts(final InvocationContext ic) throws Exception {
+        doInject(ic);
+        return ic.proceed();
+    }
+
+    @AroundInvoke
+    public Object lazyInjectContexts(final InvocationContext ic) throws Exception {
+        if (!injected.get()) {
+            doInject(ic);
+        }
+        return ic.proceed();
+    }
+
+    private void doInject(final InvocationContext ic) throws Exception {
+        final Message current = JAXRSUtils.getCurrentMessage();
+        if (current != null) {
+            final OperationResourceInfoStack stack = OperationResourceInfoStack.class.cast(current.get(OperationResourceInfoStack.class.getName()));
+            if (stack != null && !stack.isEmpty()) {
+                final Object instance;
+                if (ConstructorInterceptorInvocationContext.class.isInstance(ic)) {
+                    final ConstructorInterceptorInvocationContext constructorInterceptorInvocationContext
= ConstructorInterceptorInvocationContext.class.cast(ic);
+                    constructorInterceptorInvocationContext.directProceed();
+                    instance = constructorInterceptorInvocationContext.getNewInstance();
+                } else {
+                    instance = ic.getTarget();
+                }
+                Application application = null;
+                final Object appInfo = current.getExchange().getEndpoint().get(Application.class.getName());
+                if (ApplicationInfo.class.isInstance(appInfo)) {
+                    application = ApplicationInfo.class.cast(appInfo).getProvider();
+                }
+                synchronized (this) {
+                    if (injected.get()) {
+                        return;
+                    }
+                    InjectionUtils.injectContextProxiesAndApplication(
+                            stack.lastElement().getMethodInfo().getClassResourceInfo(),
+                            instance,
+                            application);
+                    injected.compareAndSet(false, true);
+                }
+            }
+        }
+    }
+
+    @Target(TYPE)
+    @Retention(RUNTIME)
+    @InterceptorBinding
+    public  @interface Binding {
+        Annotation INSTANCE = new EmptyAnnotationLiteral<Binding>() {
+            @Override
+            public Class<? extends Annotation> annotationType() {
+                return Binding.class;
+            }
+        };
+    }
+}

Copied: openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveExtension.java
(from r1797825, openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveBeansExtension.java)
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveExtension.java?p2=openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveExtension.java&p1=openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveBeansExtension.java&r1=1797825&r2=1797826&rev=1797826&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveBeansExtension.java
(original)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/MeecrowaveExtension.java
Tue Jun  6 21:20:51 2017
@@ -18,17 +18,59 @@
  */
 package org.apache.meecrowave.openwebbeans;
 
+import org.apache.meecrowave.cxf.JAXRSFieldInjectionInterceptor;
 import org.apache.meecrowave.cxf.MeecrowaveBus;
+import org.apache.webbeans.container.AnnotatedTypeWrapper;
 
 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.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
+import javax.ws.rs.Path;
+import java.lang.annotation.Annotation;
+import java.util.HashSet;
+import java.util.Set;
 import java.util.stream.Stream;
 
-public class MeecrowaveBeansExtension implements Extension {
+public class MeecrowaveExtension implements Extension {
     void addBeansFromJava(@Observes final BeforeBeanDiscovery bbd, final BeanManager bm)
{
         // stream not really needed but here for the pattern in case we need other beans
         Stream.of(MeecrowaveBus.class).forEach(type -> bbd.addAnnotatedType(bm.createAnnotatedType(type)));
     }
+
+    void enableContextFieldInjectionWorks(@Observes final ProcessAnnotatedType<?> pat,
final BeanManager bm) {
+        final AnnotatedType<?> at = pat.getAnnotatedType();
+        if (at.isAnnotationPresent(Path.class) && !at.isAnnotationPresent(JAXRSFieldInjectionInterceptor.Binding.class)
+                && at.getAnnotations().stream().anyMatch(a -> bm.isNormalScope(a.annotationType())))
{
+            pat.setAnnotatedType(new JAXRSFIeldInjectionAT(this, at));
+        }
+    }
+
+    private static class JAXRSFIeldInjectionAT<T> extends AnnotatedTypeWrapper<T>
{
+        private final Set<Annotation> annotations;
+
+        private JAXRSFIeldInjectionAT(final Extension extension, final AnnotatedType<T>
original) {
+            super(extension, original);
+            this.annotations = new HashSet<>(original.getAnnotations().size() + 1);
+            this.annotations.addAll(original.getAnnotations());
+            this.annotations.add(JAXRSFieldInjectionInterceptor.Binding.INSTANCE);
+        }
+
+        @Override
+        public Set<Annotation> getAnnotations() {
+            return annotations;
+        }
+
+        @Override
+        public <T1 extends Annotation> T1 getAnnotation(final Class<T1> t1Class)
{
+            return t1Class == JAXRSFieldInjectionInterceptor.Binding.class ? t1Class.cast(JAXRSFieldInjectionInterceptor.Binding.INSTANCE)
: super.getAnnotation(t1Class);
+        }
+
+        @Override
+        public boolean isAnnotationPresent(final Class<? extends Annotation> aClass)
{
+            return JAXRSFieldInjectionInterceptor.Binding.class == aClass || super.isAnnotationPresent(aClass);
+        }
+    }
 }

Modified: openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java?rev=1797826&r1=1797825&r2=1797826&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java
(original)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/main/java/org/apache/meecrowave/openwebbeans/OWBAutoSetup.java
Tue Jun  6 21:20:51 2017
@@ -19,15 +19,19 @@
 package org.apache.meecrowave.openwebbeans;
 
 import org.apache.meecrowave.Meecrowave;
+import org.apache.meecrowave.cxf.JAXRSFieldInjectionInterceptor;
 import org.apache.webbeans.annotation.AnyLiteral;
 import org.apache.webbeans.annotation.DefaultLiteral;
 import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.container.BeanManagerImpl;
+import org.apache.webbeans.intercept.InterceptorsManager;
 import org.apache.webbeans.servlet.WebBeansConfigurationListener;
 import org.apache.webbeans.web.context.WebConversationFilter;
 
 import javax.enterprise.context.ApplicationScoped;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.Extension;
 import javax.enterprise.inject.spi.InjectionPoint;
 import javax.servlet.DispatcherType;
 import javax.servlet.FilterRegistration;
@@ -59,7 +63,7 @@ public class OWBAutoSetup implements Ser
         ctx.addListener(bootListener);
     }
 
-    public static class EagerBootListener extends WebBeansConfigurationListener {
+    public static class EagerBootListener extends WebBeansConfigurationListener implements
Extension {
         private final Meecrowave.Builder config;
 
         private EagerBootListener(final Meecrowave.Builder builder) {
@@ -73,13 +77,24 @@ public class OWBAutoSetup implements Ser
 
         private void doContextInitialized(final ServletContextEvent event) {
             try {
-                WebBeansContext.getInstance().getBeanManagerImpl().addInternalBean(new ConfigBean(config));
+                final WebBeansContext instance = WebBeansContext.getInstance();
+                customizeContext(instance);
             } catch (final IllegalStateException ise) {
                 // lifecycle not supporting it
             }
             super.contextInitialized(event);
         }
 
+        private void customizeContext(final WebBeansContext instance) {
+            final BeanManagerImpl beanManager = instance.getBeanManagerImpl();
+            final InterceptorsManager interceptorsManager = instance.getInterceptorsManager();
+
+            beanManager.addInternalBean(new ConfigBean(config));
+
+            interceptorsManager.addInterceptorBindingType(JAXRSFieldInjectionInterceptor.Binding.class);
+            beanManager.addAdditionalAnnotatedType(this, beanManager.createAnnotatedType(JAXRSFieldInjectionInterceptor.class));
+        }
+
         private static class ConfigBean implements Bean<Meecrowave.Builder> {
             private final Meecrowave.Builder value;
             private final Set<Type> types = new HashSet<>(asList(Meecrowave.Builder.class,
Object.class));

Modified: openwebbeans/meecrowave/trunk/meecrowave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1797826&r1=1797825&r2=1797826&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
(original)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
Tue Jun  6 21:20:51 2017
@@ -1 +1 @@
-org.apache.meecrowave.openwebbeans.MeecrowaveBeansExtension
+org.apache.meecrowave.openwebbeans.MeecrowaveExtension

Added: openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ContextInProxiedInstancesTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ContextInProxiedInstancesTest.java?rev=1797826&view=auto
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ContextInProxiedInstancesTest.java
(added)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/ContextInProxiedInstancesTest.java
Tue Jun  6 21:20:51 2017
@@ -0,0 +1,101 @@
+/**
+ * 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
+ * <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.meecrowave;
+
+import org.apache.tomcat.util.http.fileupload.util.Streams;
+import org.junit.Test;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.Initialized;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.CDI;
+import javax.servlet.ServletContext;
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.UriInfo;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+import static org.junit.Assert.assertEquals;
+
+public class ContextInProxiedInstancesTest {
+    @Test
+    public void fields() throws IOException {
+        try (final Meecrowave meecrowave = new Meecrowave(new Meecrowave.Builder()
+                .randomHttpPort()
+                .includePackages(ContextInProxiedInstancesTest.class.getName())).bake())
{
+            // proxies can use @Context
+            try (final InputStream stream = new URL("http://localhost:" + meecrowave.getConfiguration().getHttpPort()
+ "/app").openStream()) {
+                assertEquals("app", Streams.asString(stream, "UTF-8"));
+            }
+            try (final InputStream stream = new URL("http://localhost:" + meecrowave.getConfiguration().getHttpPort()
+ "/req").openStream()) {
+                assertEquals("req", Streams.asString(stream, "UTF-8"));
+            }
+            // not proxied can also
+            try (final InputStream stream = new URL("http://localhost:" + meecrowave.getConfiguration().getHttpPort()
+ "/dep").openStream()) {
+                assertEquals("dep", Streams.asString(stream, "UTF-8"));
+            }
+            assertEquals(Dep.class, CDI.current().select(Dep.class).get().getClass()); //
ensure it is not proxied but injection works (thanks CXF)
+        }
+    }
+
+    @Path("app")
+    @ApplicationScoped
+    public static class App {
+        @Context
+        private UriInfo uri;
+
+        public void init(@Observes @Initialized(ApplicationScoped.class) final ServletContext
sc) {
+            // init without a Message
+        }
+
+        @GET
+        public String get() {
+            return uri.getPath();
+        }
+    }
+
+    @Path("req")
+    @RequestScoped
+    public static class Req {
+        @Context
+        private UriInfo uri;
+
+        @GET
+        public String get() {
+            return uri.getPath();
+        }
+    }
+
+    @Path("dep")
+    @Dependent
+    public static class Dep {
+        @Context
+        private UriInfo uri;
+
+        @GET
+        public String get() {
+            return uri.getPath();
+        }
+    }
+}

Modified: openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/InstanceCustomizerTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/InstanceCustomizerTest.java?rev=1797826&r1=1797825&r2=1797826&view=diff
==============================================================================
--- openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/InstanceCustomizerTest.java
(original)
+++ openwebbeans/meecrowave/trunk/meecrowave-core/src/test/java/org/apache/meecrowave/InstanceCustomizerTest.java
Tue Jun  6 21:20:51 2017
@@ -35,6 +35,7 @@ public class InstanceCustomizerTest {
     @Test
     public void instanceCustomizer() throws IOException {
         try (final Meecrowave meecrowave = new Meecrowave(new Meecrowave.Builder()
+                .randomHttpPort()
                 .instanceCustomizer(t -> t.getHost().getPipeline().addValve(new ValveBase()
{
                     @Override
                     public void invoke(final Request request, final Response response) throws
IOException, ServletException {



Mime
View raw message