Author: rmannibucau Date: Thu Jan 24 16:26:57 2013 New Revision: 1438062 URL: http://svn.apache.org/viewvc?rev=1438062&view=rev Log: TOMEE-749 TOMEE-750 @Context for cdi interceptors + basic cdi config in @Classes for tests
Added: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java - copied, changed from r1436554, tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java Removed: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/ContextReferenceTypes.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/RestDeploymentTest.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/AutoJAXRSInvoker.java tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/Contexts.java tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBEJBInvoker.java tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBPerRequestPojoResourceProvider.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ApplicationFromWebXmlTest.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CDIApplicationTest.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSRoutingTest.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSWithInterfaceTest.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationTest.java tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/config/TldScanner.java Thu Jan 24 16:26:57 2013 @@ -259,6 +259,10 @@ public class TldScanner { // this method clean the cacheByhash too public static void forceCompleteClean(final ClassLoader loader) { + if (loader == null) { + return; + } + quickClean(loader); cacheByhashCode.remove(hash(urls(loader))); Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/ApplicationComposers.java Thu Jan 24 16:26:57 2013 @@ -316,10 +316,17 @@ public final class ApplicationComposers final org.apache.openejb.junit.Classes classesAnnotationOld = method.getAnnotation(org.apache.openejb.junit.Classes.class); Class<?>[] classes = null; + Class<?>[] cdiInterceptors = null; + Class<?>[] cdiAlternatives = null; + Class<?>[] cdiDecorators = null; boolean cdi = false; if (classesAnnotation != null) { classes = classesAnnotation.value(); - cdi = classesAnnotation.cdi(); + cdiInterceptors = classesAnnotation.cdiInterceptors(); + cdiDecorators = classesAnnotation.cdiDecorators(); + cdiAlternatives = classesAnnotation.cdiAlternatives(); + cdi = classesAnnotation.cdi() || cdiAlternatives.length > 0 + || cdiDecorators.length > 0 || cdiInterceptors.length > 0; } else if (classesAnnotationOld != null) { classes = classesAnnotationOld.value(); } @@ -343,7 +350,7 @@ public final class ApplicationComposers } final EjbModule ejbModule = DeploymentLoader.addWebModule(webModule, appModule); if (cdi) { - ejbModule.setBeans(new Beans()); + ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives)); } } else if (obj instanceof WebModule) { // will add the ejbmodule too webModulesNb++; @@ -356,7 +363,10 @@ public final class ApplicationComposers if (classes != null) { webModule.setFinder(finderFromClasses(classes)); } - DeploymentLoader.addWebModule(webModule, appModule); + final EjbModule ejbModule = DeploymentLoader.addWebModule(webModule, appModule); + if (cdi) { + ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives)); + } } else if (obj instanceof EjbModule) { final EjbModule ejbModule = (EjbModule) obj; @@ -368,6 +378,9 @@ public final class ApplicationComposers } ejbModule.initAppModule(appModule); appModule.getEjbModules().add(ejbModule); + if (cdi) { + ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives)); + } } else if (obj instanceof EjbJar) { final EjbJar ejbJar = (EjbJar) obj; @@ -382,6 +395,9 @@ public final class ApplicationComposers if (classes != null) { ejbModule.setFinder(finderFromClasses(classes)); } + if (cdi) { + ejbModule.setBeans(beans(new Beans(), cdiDecorators, cdiInterceptors, cdiAlternatives)); + } } else if (obj instanceof EnterpriseBean) { final EnterpriseBean bean = (EnterpriseBean) obj; @@ -422,6 +438,9 @@ public final class ApplicationComposers ejbModule.setFinder(finderFromClasses(classes)); } appModule.getEjbModules().add(ejbModule); + if (cdi) { + ejbModule.setBeans(beans(beans, cdiDecorators, cdiInterceptors, cdiAlternatives)); + } } else if (obj instanceof Class[]) { @@ -571,6 +590,26 @@ public final class ApplicationComposers previous = ThreadContext.enter(new ThreadContext(context, null, Operation.BUSINESS)); } + private Beans beans(final Beans beans, final Class<?>[] cdiDecorators, final Class<?>[] cdiInterceptors, + final Class<?>[] cdiAlternatives) { + if (cdiDecorators != null) { + for (Class<?> clazz : cdiDecorators) { + beans.addDecorator(clazz); + } + } + if (cdiInterceptors != null) { + for (Class<?> clazz : cdiInterceptors) { + beans.addInterceptor(clazz); + } + } + if (cdiAlternatives != null) { + for (Class<?> clazz : cdiAlternatives) { + beans.addAlternativeClass(clazz); + } + } + return beans; + } + private void setComponent(Object testInstance, Method method) throws IllegalAccessException, InvocationTargetException, InstantiationException { Object value = method.invoke(testInstance); if (value instanceof Class<?>) { Modified: tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java (original) +++ tomee/tomee/trunk/container/openejb-core/src/main/java/org/apache/openejb/testing/Classes.java Thu Jan 24 16:26:57 2013 @@ -25,5 +25,8 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface Classes { Class<?>[] value() default {}; + Class<?>[] cdiInterceptors() default {}; + Class<?>[] cdiDecorators() default {}; + Class<?>[] cdiAlternatives() default {}; boolean cdi() default false; } Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/AutoJAXRSInvoker.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/AutoJAXRSInvoker.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/AutoJAXRSInvoker.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/AutoJAXRSInvoker.java Thu Jan 24 16:26:57 2013 @@ -20,9 +20,12 @@ import org.apache.cxf.jaxrs.JAXRSInvoker import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.message.Exchange; import org.apache.cxf.service.invoker.Invoker; +import org.apache.openejb.BeanContext; import org.apache.openejb.BeanType; import org.apache.openejb.server.rest.EJBRestServiceInfo; +import java.util.ArrayList; +import java.util.Collection; import java.util.Map; public class AutoJAXRSInvoker implements Invoker { @@ -36,12 +39,20 @@ public class AutoJAXRSInvoker implements // delegates jaxrsInvoker = new JAXRSInvoker(); if (!ejbs.isEmpty()) { - ejbInvoker = new OpenEJBEJBInvoker(); + ejbInvoker = new OpenEJBEJBInvoker(beanContexts(restEjbs)); } else { ejbInvoker = null; // no need } } + private static Collection<BeanContext> beanContexts(final Map<String, EJBRestServiceInfo> restEjbs) { + final Collection<BeanContext> bc = new ArrayList<BeanContext>(); + for (EJBRestServiceInfo i : restEjbs.values()) { + bc.add(i.context); + } + return bc; + } + @Override public Object invoke(Exchange exchange, Object o) { // mainly a select the right invoker impl final ClassResourceInfo cri = (ClassResourceInfo) exchange.get("root.resource.class"); Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/Contexts.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/Contexts.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/Contexts.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/Contexts.java Thu Jan 24 16:26:57 2013 @@ -20,23 +20,28 @@ import org.apache.cxf.jaxrs.ext.ContextP import org.apache.cxf.jaxrs.model.ClassResourceInfo; import org.apache.cxf.jaxrs.model.OperationResourceInfo; import org.apache.cxf.jaxrs.provider.ProviderFactory; +import org.apache.cxf.jaxrs.utils.AnnotationUtils; import org.apache.cxf.jaxrs.utils.JAXRSUtils; import org.apache.cxf.message.Exchange; import org.apache.cxf.message.Message; import org.apache.openejb.rest.ThreadLocalContextManager; +import javax.annotation.Resource; import javax.servlet.ServletConfig; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Request; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.ContextResolver; import javax.ws.rs.ext.Providers; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -47,6 +52,22 @@ public final class Contexts { // no-op } + public static Collection<Class<?>> findContextFields(final Class<?> cls, final Collection<Class<?>> types) { + if (cls == Object.class || cls == null) { + return Collections.emptyList(); + } + for (Field f : cls.getDeclaredFields()) { + for (Annotation a : f.getAnnotations()) { + if (a.annotationType() == Context.class || a.annotationType() == Resource.class + && AnnotationUtils.isContextClass(f.getType())) { + types.add(f.getType()); + } + } + } + findContextFields(cls.getSuperclass(), types); + return types; + } + public static void bind(final Exchange exchange) { if (exchange == null) { return; @@ -72,7 +93,7 @@ public final class Contexts { * @param exchange * @param types */ - public static void bind(Exchange exchange, Set<Class<?>> types) { + public static void bind(Exchange exchange, Collection<Class<?>> types) { for (Class<?> type : types) { if (Request.class.equals(type)) { Request binding = JAXRSUtils.createContextValue(exchange.getInMessage(), null, Request.class); Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/CxfRsHttpListener.java Thu Jan 24 16:26:57 2013 @@ -36,21 +36,16 @@ import org.apache.openejb.Injection; import org.apache.openejb.assembler.classic.ServiceInfo; import org.apache.openejb.assembler.classic.util.ServiceConfiguration; import org.apache.openejb.assembler.classic.util.ServiceInfos; -import org.apache.openejb.core.interceptor.InterceptorData; import org.apache.openejb.server.cxf.transport.util.CxfUtil; import org.apache.openejb.server.httpd.HttpRequest; import org.apache.openejb.server.httpd.HttpRequestImpl; import org.apache.openejb.server.httpd.HttpResponse; import org.apache.openejb.server.rest.EJBRestServiceInfo; import org.apache.openejb.server.rest.RsHttpListener; -import org.apache.openejb.util.Classes; import org.apache.openejb.util.LogCategory; import org.apache.openejb.util.Logger; -import org.apache.openejb.util.doc.Revisit; import org.apache.openejb.util.proxy.ProxyEJB; import org.apache.webbeans.config.WebBeansContext; -import org.apache.xbean.finder.AnnotationFinder; -import org.apache.xbean.finder.archive.ClassesArchive; import javax.naming.Context; import javax.servlet.ServletException; @@ -62,16 +57,13 @@ import javax.ws.rs.core.Application; import javax.xml.bind.Marshaller; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Field; 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.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Pattern; @@ -200,29 +192,8 @@ public class CxfRsHttpListener implement public void deployEJB(String fullContext, BeanContext beanContext, Collection<Object> additionalProviders, ServiceConfiguration configuration) { final Object proxy = ProxyEJB.subclassProxy(beanContext); - addContextTypes(beanContext); - deploy(beanContext.getBeanClass(), fullContext, new NoopResourceProvider(beanContext.getBeanClass(), proxy), - proxy, null, new OpenEJBEJBInvoker(), additionalProviders, configuration); - } - - @Revisit("We should not be scanning after the ConfigurationFactory completes") - private void addContextTypes(BeanContext beanContext) { - final Set<Class<?>> classes = new HashSet<Class<?>>(); - classes.addAll(Classes.ancestors(beanContext.getBeanClass())); - for (InterceptorData interceptorData : beanContext.getInstanceScopedInterceptors()) { - classes.addAll(Classes.ancestors(interceptorData.getInterceptorClass())); - } - - // We really shouldn't do this here -- should be done in the AnnotationDeployer where we already payed for the AnnotationFinder - final AnnotationFinder finder = new AnnotationFinder(new ClassesArchive(classes)); - final List<Field> fields = finder.findAnnotatedFields(javax.ws.rs.core.Context.class); - final Set<Class<?>> contextTypes = new HashSet<Class<?>>(); - for (Field field : fields) { - contextTypes.add(field.getType()); - } - - beanContext.set(ContextReferenceTypes.class, new ContextReferenceTypes(contextTypes)); + proxy, null, new OpenEJBEJBInvoker(Collections.singleton(beanContext)), additionalProviders, configuration); } private void deploy(Class<?> clazz, String address, ResourceProvider rp, Object serviceBean, Application app, Invoker invoker, @@ -313,7 +284,6 @@ public class CxfRsHttpListener implement if (restEjbs.containsKey(name)) { final BeanContext bc = restEjbs.get(name).context; final Object proxy = ProxyEJB.subclassProxy(bc); - addContextTypes(bc); factory.setResourceProvider(clazz, new NoopResourceProvider(bc.getBeanClass(), proxy)); } else { factory.setResourceProvider(clazz, new OpenEJBPerRequestPojoResourceProvider(clazz, injections, context, owbCtx)); Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBEJBInvoker.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBEJBInvoker.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBEJBInvoker.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBEJBInvoker.java Thu Jan 24 16:26:57 2013 @@ -20,7 +20,9 @@ import org.apache.cxf.jaxrs.JAXRSInvoker import org.apache.cxf.message.Exchange; import org.apache.openejb.BeanContext; import org.apache.openejb.InvalidateReferenceException; +import org.apache.openejb.core.interceptor.InterceptorData; import org.apache.openejb.rest.ThreadLocalContextManager; +import org.apache.openejb.server.rest.EJBRestServiceInfo; import org.apache.openejb.util.proxy.BeanContextInvocationHandler; import org.apache.openejb.util.proxy.LocalBeanProxyFactory; import org.apache.openejb.util.proxy.ProxyManager; @@ -29,19 +31,33 @@ import java.lang.reflect.InvocationHandl import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.rmi.RemoteException; -import java.util.Set; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; public class OpenEJBEJBInvoker extends JAXRSInvoker { + private final Map<Class<?>, Collection<Class<?>>> contextTypes = new HashMap<Class<?>, Collection<Class<?>>>(); + + public OpenEJBEJBInvoker(final Collection<BeanContext> restEjbs) { + for (BeanContext context : restEjbs) { + final Collection<Class<?>> classes = new HashSet<Class<?>>(); + Contexts.findContextFields(context.getBeanClass(), classes); + for (InterceptorData id : context.getInterceptorData()) { + Contexts.findContextFields(id.getInterceptorClass(), classes); + } + for (InterceptorData id : context.getCallbackInterceptors()) { + Contexts.findContextFields(id.getInterceptorClass(), classes); + } + contextTypes.put(context.getBeanClass(), classes); + } + } + @Override public Object invoke(final Exchange exchange, final Object request, final Object resourceObject) { - final Set<Class<?>> types = getContextTypes(resourceObject); - - if (types != null) { - Contexts.bind(exchange, types); - } else { - Contexts.bind(exchange); - } + Contexts.bind(exchange, getContextTypes(resourceObject)); try { return super.invoke(exchange, request, resourceObject); @@ -50,18 +66,23 @@ public class OpenEJBEJBInvoker extends J } } - private Set<Class<?>> getContextTypes(Object resourceObject) { + private Collection<Class<?>> getContextTypes(Object resourceObject) { if (!ProxyManager.isProxyClass(resourceObject.getClass()) - && !LocalBeanProxyFactory.isProxy(resourceObject.getClass())) return null; + && !LocalBeanProxyFactory.isProxy(resourceObject.getClass())) { + return Collections.emptySet(); + } + final InvocationHandler handler = ProxyManager.getInvocationHandler(resourceObject); - if (!(handler instanceof BeanContextInvocationHandler)) return null; + if (!(handler instanceof BeanContextInvocationHandler)) { + return Collections.emptySet(); + } final BeanContext beanContext = ((BeanContextInvocationHandler) handler).getBeanContext(); - final ContextReferenceTypes contextReferenceTypes = beanContext.get(ContextReferenceTypes.class); - - if (contextReferenceTypes == null) return null; - return contextReferenceTypes.get(); + if (beanContext == null) { + return Collections.emptySet(); + } + return contextTypes.get(beanContext.getBeanClass()); } @Override Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBPerRequestPojoResourceProvider.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBPerRequestPojoResourceProvider.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBPerRequestPojoResourceProvider.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/main/java/org/apache/openejb/server/cxf/rs/OpenEJBPerRequestPojoResourceProvider.java Thu Jan 24 16:26:57 2013 @@ -24,15 +24,19 @@ import org.apache.openejb.Injection; import org.apache.openejb.InjectionProcessor; import org.apache.openejb.OpenEJBException; import org.apache.openejb.rest.ThreadLocalContextManager; +import org.apache.webbeans.component.AbstractInjectionTargetBean; import org.apache.webbeans.config.WebBeansContext; import org.apache.webbeans.container.BeanManagerImpl; import org.apache.webbeans.inject.AbstractInjectable; import org.apache.webbeans.inject.OWBInjector; +import org.apache.webbeans.intercept.InterceptorData; +import org.apache.webbeans.util.WebBeansUtil; import javax.enterprise.context.spi.CreationalContext; import javax.enterprise.inject.InjectionException; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.Interceptor; import javax.naming.Context; import javax.naming.InitialContext; import javax.ws.rs.WebApplicationException; @@ -44,18 +48,21 @@ import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; +import java.util.HashSet; +import java.util.List; import java.util.Set; public class OpenEJBPerRequestPojoResourceProvider implements ResourceProvider { - protected Collection<Injection> injections; - protected Context context; - protected WebBeansContext webbeansContext; - - protected Constructor<?> constructor; - protected Method postConstructMethod; - protected Method preDestroyMethod; + protected final Collection<Injection> injections; + protected final Context context; + protected final WebBeansContext webbeansContext; + + protected final Constructor<?> constructor; + protected final Method postConstructMethod; + protected final Method preDestroyMethod; private BeanCreator creator; + private final Collection<Class<?>> contextTypes = new HashSet<Class<?>>(); public OpenEJBPerRequestPojoResourceProvider(final Class<?> clazz, final Collection<Injection> injectionCollection, final Context initialContext, final WebBeansContext owbCtx) { injections = injectionCollection; @@ -68,16 +75,51 @@ public class OpenEJBPerRequestPojoResour } postConstructMethod = ResourceUtils.findPostConstructMethod(clazz); preDestroyMethod = ResourceUtils.findPreDestroyMethod(clazz); + + final Bean<?> bean; + final BeanManagerImpl bm = webbeansContext.getBeanManagerImpl(); + if (bm.isInUse()) { + try { + final Set<Bean<?>> beans = bm.getBeans(clazz); + bean = bm.resolve(beans); + if (bean == null) { + throw new NoBeanFoundException(clazz.getName()); + } + } catch (InjectionException ie) { + final String msg = "Resource class " + constructor.getDeclaringClass().getName() + " can not be instantiated"; + throw new WebApplicationException(Response.serverError().entity(msg).build()); + } + + if (bean instanceof AbstractInjectionTargetBean<?>) { + final List<InterceptorData> stack = ((AbstractInjectionTargetBean) bean).getInterceptorStack(); + if (stack != null) { + for (InterceptorData id : stack) { + final Interceptor<?> webBeansInterceptor = id.getWebBeansInterceptor(); + if (webBeansInterceptor == null || webBeansInterceptor.getBeanClass() == null) { + continue; + } + + Contexts.findContextFields(webBeansInterceptor.getBeanClass(), contextTypes); + } + } + } + } else { + bean = null; + } + + Contexts.findContextFields(clazz, contextTypes); // for the class itself + if (bean != null) { + creator = new CdiBeanCreator(bm, bean); + } else { // do it manually + creator = null; + } } @Override public Object getInstance(Message m) { - Contexts.bind(m.getExchange()); + Contexts.bind(m.getExchange(), contextTypes); - final BeanManagerImpl bm = webbeansContext.getBeanManagerImpl(); - if (bm.isInUse()) { - creator = new CdiBeanCreator(bm); - } else { // do it manually + if (creator == null) { creator = new DefaultBeanCreator(m); } @@ -155,29 +197,23 @@ public class OpenEJBPerRequestPojoResour } private class CdiBeanCreator implements BeanCreator { - private BeanManager bm; + private final BeanManager bm; + private final Bean<?> bean; private CreationalContext<?> toClean; - public CdiBeanCreator(BeanManager bm) { + public CdiBeanCreator(BeanManager bm, final Bean<?> bean) { this.bm = bm; + this.bean = bean; } @Override public Object create() { - final Class<?> clazz = constructor.getDeclaringClass(); try { - final Set<Bean<?>> beans = bm.getBeans(clazz); - final Bean<?> bean = bm.resolve(beans); - if (bean == null) { - throw new NoBeanFoundException(); - } - toClean = bm.createCreationalContext(bean); - try { - return bm.getReference(bean, clazz, toClean); + return bm.getReference(bean, bean.getBeanClass(), toClean); } finally { - if (bm.isNormalScope(bean.getScope())) { + if (!WebBeansUtil.isDependent(bean)) { toClean = null; // will be released by the container } } @@ -269,5 +305,8 @@ public class OpenEJBPerRequestPojoResour } private static class NoBeanFoundException extends RuntimeException { + public NoBeanFoundException(final String name) { + super(name); + } } } Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ApplicationFromWebXmlTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ApplicationFromWebXmlTest.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ApplicationFromWebXmlTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/ApplicationFromWebXmlTest.java Thu Jan 24 16:26:57 2013 @@ -20,6 +20,7 @@ import org.apache.cxf.jaxrs.client.WebCl import org.apache.openejb.jee.WebApp; import org.apache.openejb.junit.ApplicationComposer; import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass; +import org.apache.openejb.testing.Classes; import org.apache.openejb.testing.EnableServices; import org.apache.openejb.testing.Module; import org.junit.Test; @@ -38,6 +39,7 @@ public class ApplicationFromWebXmlTest { public static final String BASE_URL = "http://localhost:4204/foo/bar"; @Module + @Classes(value = { MyFirstRestClass.class }, cdi = true) public WebApp war() { return new WebApp() .contextRoot("foo") Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CDIApplicationTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CDIApplicationTest.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CDIApplicationTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CDIApplicationTest.java Thu Jan 24 16:26:57 2013 @@ -38,7 +38,7 @@ import static org.junit.Assert.assertTru @RunWith(ApplicationComposer.class) public class CDIApplicationTest { @Module - @Classes(cdi = true, value = { MyCdiRESTApplication.class, ACdiBeanInjectedInApp.class }) + @Classes(cdi = true, value = { MyCdiRESTApplication.class, MyFirstRestClass.class, ACdiBeanInjectedInApp.class }) public WebApp war() { return new WebApp() .contextRoot("foo") Copied: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java (from r1436554, tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java) URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java?p2=tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java&p1=tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java&r1=1436554&r2=1438062&rev=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/CdiInterceptorContextTest.java Thu Jan 24 16:26:57 2013 @@ -17,46 +17,85 @@ package org.apache.openejb.server.cxf.rs; import org.apache.cxf.jaxrs.client.WebClient; -import org.apache.openejb.OpenEjbContainer; -import org.apache.openejb.assembler.classic.WebAppBuilder; -import org.apache.openejb.config.WebModule; import org.apache.openejb.jee.WebApp; import org.apache.openejb.junit.ApplicationComposer; -import org.apache.openejb.testing.Component; -import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass; -import org.apache.openejb.testing.Configuration; +import org.apache.openejb.testing.Classes; +import org.apache.openejb.testing.EnableServices; import org.apache.openejb.testing.Module; -import org.apache.openejb.web.LightweightWebAppBuilder; import org.junit.Test; import org.junit.runner.RunWith; -import java.util.Properties; +import javax.interceptor.AroundInvoke; +import javax.interceptor.Interceptor; +import javax.interceptor.InterceptorBinding; +import javax.interceptor.InvocationContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Context; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.util.HashSet; +import java.util.Set; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.junit.Assert.assertEquals; +@EnableServices("jax-rs") @RunWith(ApplicationComposer.class) -public class SimplePojoTest { - @Component - public WebAppBuilder webAppBuilder() { - return new LightweightWebAppBuilder(); +public class CdiInterceptorContextTest { + @Module + @Classes(value = { Endpoint.class, AnswerPerfect.class }, cdiInterceptors = AnswerPerfect.class) + public WebApp war() { + return new WebApp() + .contextRoot("app") + .addServlet("REST Application", Application.class.getName()) + .addInitParam("REST Application", "javax.ws.rs.Application", PerfectApplication.class.getName()); } - @Configuration - public Properties configuration() { - final Properties properties = new Properties(); - properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, "true"); - return properties; + @Test + public void checkServiceWasDeployed() { + assertEquals("perfect", WebClient.create("http://localhost:4204/app").path("/foo").get(String.class)); } - @Module - public WebModule war() { - final WebModule webModule = new WebModule(new WebApp(), "/foo", Thread.currentThread().getContextClassLoader(), "", "foo"); - webModule.getRestClasses().add(MyFirstRestClass.class.getName()); - return webModule; + @Path("/foo") + @Perfect + public static class Endpoint { + @GET + public String bar() { + return "bar"; + } } - @Test - public void checkServiceWasDeployed() { - assertEquals("Hi from REST World!", WebClient.create("http://localhost:4204/foo").path("/first/hi").get(String.class)); + @InterceptorBinding + @Target(TYPE) + @Retention(RUNTIME) + public static @interface Perfect { + + } + + @Interceptor @Perfect + public static class AnswerPerfect { + @Context + private HttpServletRequest request; + + @AroundInvoke + public Object invoke(final InvocationContext ic) throws Exception { + if (ic.getMethod().getName().equals("bar") && "foo".equals(request.getRequestURI())) { + return "perfect"; + } + return ic.proceed(); + } + } + + public static class PerfectApplication extends Application { + @Override + public Set<Class<?>> getClasses() { + final Set<Class<?>> classes = new HashSet<Class<?>>(); + classes.add(Endpoint.class); + return classes; + } } } Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSRoutingTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSRoutingTest.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSRoutingTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSRoutingTest.java Thu Jan 24 16:26:57 2013 @@ -43,7 +43,7 @@ public class JAXRSRoutingTest { public static final String BASE_URL = "http://localhost:4204/foo/"; @Module - @Classes({ RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class }) + @Classes(cdi = true, value = { RestWithInjections.class, FirstService.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class }) public WebApp war() { return new WebApp() .contextRoot("foo") Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSWithInterfaceTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSWithInterfaceTest.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSWithInterfaceTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/JAXRSWithInterfaceTest.java Thu Jan 24 16:26:57 2013 @@ -43,7 +43,7 @@ public class JAXRSWithInterfaceTest { public static final String BASE_URL = "http://localhost:4204/foo/"; @Module - @Classes({ RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class }) + @Classes(cdi = true, value = { Impl.class, RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class }) public WebApp war() { return new WebApp() .contextRoot("foo") Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationTest.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimpleApplicationTest.java Thu Jan 24 16:26:57 2013 @@ -20,9 +20,11 @@ import org.apache.cxf.jaxrs.client.Serve import org.apache.cxf.jaxrs.client.WebClient; import org.apache.openejb.jee.WebApp; import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.server.cxf.rs.beans.HookedRest; import org.apache.openejb.server.cxf.rs.beans.MyExpertRestClass; import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass; import org.apache.openejb.server.cxf.rs.beans.MyRESTApplication; +import org.apache.openejb.server.cxf.rs.beans.MySecondRestClass; import org.apache.openejb.server.cxf.rs.beans.RestWithInjections; import org.apache.openejb.server.cxf.rs.beans.SimpleEJB; import org.apache.openejb.testing.Classes; @@ -45,7 +47,7 @@ public class SimpleApplicationTest { public static final String BASE_URL = "http://localhost:4204/foo/my-app"; @Module - @Classes({ RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class }) + @Classes(cdi = true, value = {MySecondRestClass.class, HookedRest.class, RestWithInjections.class, SimpleEJB.class, MyExpertRestClass.class, MyFirstRestClass.class }) public WebApp war() { return new WebApp() .contextRoot("foo") Modified: tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java URL: http://svn.apache.org/viewvc/tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java?rev=1438062&r1=1438061&r2=1438062&view=diff ============================================================================== --- tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java (original) +++ tomee/tomee/trunk/server/openejb-cxf-rs/src/test/java/org/apache/openejb/server/cxf/rs/SimplePojoTest.java Thu Jan 24 16:26:57 2013 @@ -22,6 +22,7 @@ import org.apache.openejb.assembler.clas import org.apache.openejb.config.WebModule; import org.apache.openejb.jee.WebApp; import org.apache.openejb.junit.ApplicationComposer; +import org.apache.openejb.testing.Classes; import org.apache.openejb.testing.Component; import org.apache.openejb.server.cxf.rs.beans.MyFirstRestClass; import org.apache.openejb.testing.Configuration; @@ -49,6 +50,7 @@ public class SimplePojoTest { } @Module + @Classes(cdi = true, value = { MyFirstRestClass.class }) public WebModule war() { final WebModule webModule = new WebModule(new WebApp(), "/foo", Thread.currentThread().getContextClassLoader(), "", "foo"); webModule.getRestClasses().add(MyFirstRestClass.class.getName());