Repository: cxf Updated Branches: refs/heads/master 14c241f0b -> 3cd24f083
CXF-5576: Initital support for CDI integration. Refactored JAXRSServerFactoryBean instantiation flow. Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/3cd24f08 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/3cd24f08 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/3cd24f08 Branch: refs/heads/master Commit: 3cd24f083d410f2335245a377f961b48341705fa Parents: 14c241f Author: reta <[email protected]> Authored: Sun Mar 16 13:34:08 2014 -0400 Committer: reta <[email protected]> Committed: Sun Mar 16 13:34:08 2014 -0400 ---------------------------------------------------------------------- .../java/org/apache/cxf/cdi/CXFCdiServlet.java | 29 +---- .../cxf/cdi/JAXRSCdiResourceExtension.java | 91 +++++++++++---- .../cxf/cdi/JAXRSCdiServerFactoryBean.java | 117 +++++++++++++++++++ .../apache/cxf/jaxrs/utils/ResourceUtils.java | 10 +- 4 files changed, 200 insertions(+), 47 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/3cd24f08/integration/cdi/src/main/java/org/apache/cxf/cdi/CXFCdiServlet.java ---------------------------------------------------------------------- diff --git a/integration/cdi/src/main/java/org/apache/cxf/cdi/CXFCdiServlet.java b/integration/cdi/src/main/java/org/apache/cxf/cdi/CXFCdiServlet.java index b3867b9..2cae17d 100644 --- a/integration/cdi/src/main/java/org/apache/cxf/cdi/CXFCdiServlet.java +++ b/integration/cdi/src/main/java/org/apache/cxf/cdi/CXFCdiServlet.java @@ -18,19 +18,12 @@ */ package org.apache.cxf.cdi; -import java.util.ArrayList; -import java.util.ServiceLoader; - import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.CDI; import javax.servlet.ServletConfig; import javax.servlet.ServletException; -import javax.ws.rs.core.Application; -import javax.ws.rs.ext.MessageBodyReader; -import javax.ws.rs.ext.MessageBodyWriter; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; -import org.apache.cxf.jaxrs.utils.ResourceUtils; import org.apache.cxf.transport.servlet.CXFNonSpringServlet; /** @@ -40,31 +33,15 @@ public class CXFCdiServlet extends CXFNonSpringServlet { private static final long serialVersionUID = -2890970731778523861L; @Override - @SuppressWarnings("rawtypes") public void init(ServletConfig servletConfig) throws ServletException { super.init(servletConfig); final BeanManager beanManager = CDI.current().getBeanManager(); final JAXRSCdiResourceExtension extension = beanManager.getExtension(JAXRSCdiResourceExtension.class); if (extension != null) { - for (final Application application: extension.getApplications()) { - final JAXRSServerFactoryBean bean = ResourceUtils.createApplication(application, false, false); - - bean.setServiceBeans(new ArrayList< Object >(extension.getServices())); - bean.setProviders(extension.getProviders()); - bean.setBus(getBus()); - - final ServiceLoader< MessageBodyWriter > writers = ServiceLoader.load(MessageBodyWriter.class); - for (final MessageBodyWriter< ? > writer: writers) { - bean.setProvider(writer); - } - - final ServiceLoader< MessageBodyReader > readers = ServiceLoader.load(MessageBodyReader.class); - for (final MessageBodyReader< ? > reader: readers) { - bean.setProvider(reader); - } - - bean.create(); + for (final JAXRSServerFactoryBean factory: extension.getFactories()) { + factory.setBus(getBus()); + factory.init(); } } } http://git-wip-us.apache.org/repos/asf/cxf/blob/3cd24f08/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiResourceExtension.java ---------------------------------------------------------------------- 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 cf537a4..97c6e6f 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 @@ -19,28 +19,43 @@ package org.apache.cxf.cdi; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; import javax.enterprise.inject.spi.AfterDeploymentValidation; +import javax.enterprise.inject.spi.AnnotatedType; import javax.enterprise.inject.spi.Bean; import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; +import javax.enterprise.inject.spi.InjectionTarget; import javax.enterprise.inject.spi.ProcessBean; import javax.ws.rs.ApplicationPath; import javax.ws.rs.Path; import javax.ws.rs.core.Application; +import javax.ws.rs.ext.MessageBodyReader; +import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; +import org.apache.cxf.jaxrs.utils.ResourceUtils; + /** * Apache CXF portable CDI extension to support initialization of JAX-RS / JAX-WS resources. */ + public class JAXRSCdiResourceExtension implements Extension { - private final List< Bean< ? > > applicationBeans = new ArrayList<Bean<?>>(); - private final List< Bean< ? > > serviceBeans = new ArrayList<Bean<?>>(); - private final List< Bean< ? > > providerBeans = new ArrayList<Bean<?>>(); + private final List< Bean< ? > > applicationBeans = new ArrayList< Bean< ? > >(); + private final List< Bean< ? > > serviceBeans = new ArrayList< Bean< ? > >(); + private final List< Bean< ? > > providerBeans = new ArrayList< Bean< ? > >(); + private final Map< Bean< ? >, Bean< JAXRSServerFactoryBean > > factoryBeans = + new HashMap< Bean< ? >, Bean< JAXRSServerFactoryBean > >(); - private final List< Application > applications = new ArrayList< Application >(); + private final List< JAXRSServerFactoryBean > factories = new ArrayList< JAXRSServerFactoryBean >(); private final List< Object > services = new ArrayList< Object >(); private final List< Object > providers = new ArrayList< Object >(); @@ -55,16 +70,6 @@ public class JAXRSCdiResourceExtension implements Extension { } public void load(@Observes final AfterDeploymentValidation event, final BeanManager beanManager) { - for (final Bean< ? > bean: applicationBeans) { - applications.add( - (Application)beanManager.getReference( - bean, - bean.getBeanClass(), - beanManager.createCreationalContext(bean) - ) - ); - } - for (final Bean< ? > bean: serviceBeans) { services.add( beanManager.getReference( @@ -84,17 +89,63 @@ public class JAXRSCdiResourceExtension implements Extension { ) ); } + + for (final Map.Entry< Bean< ? >, Bean< JAXRSServerFactoryBean > > entry: factoryBeans.entrySet()) { + final Application instance = (Application)beanManager.getReference( + entry.getKey(), + entry.getKey().getBeanClass(), + beanManager.createCreationalContext(entry.getKey()) + ); + + // Create the JAXRSServerFactoryBean for each application we have discovered + factories.add(createFactoryInstance(instance, entry.getValue(), beanManager)); + } } - public List<Application> getApplications() { - return applications; + public void injectFactories(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) { + final AnnotatedType< JAXRSServerFactoryBean > factoryAnnotatedType = + beanManager.createAnnotatedType(JAXRSServerFactoryBean.class); + + final InjectionTarget<JAXRSServerFactoryBean> injectionTarget = + beanManager.createInjectionTarget(factoryAnnotatedType); + + for (final Bean< ? > applicationBean: applicationBeans) { + final Bean< JAXRSServerFactoryBean > factoryBean = + new JAXRSCdiServerFactoryBean(applicationBean, injectionTarget); + + event.addBean(factoryBean); + factoryBeans.put(applicationBean, factoryBean); + } } - public List< Object > getServices() { - return services; + public List< JAXRSServerFactoryBean > getFactories() { + return Collections.< JAXRSServerFactoryBean > unmodifiableList(factories); } - public List< Object > getProviders() { - return providers; + @SuppressWarnings("rawtypes") + private JAXRSServerFactoryBean createFactoryInstance(final Application application, + final Bean< ? > factoryBean, final BeanManager beanManager) { + + final JAXRSServerFactoryBean instance = (JAXRSServerFactoryBean)beanManager.getReference( + factoryBean, + factoryBean.getBeanClass(), + beanManager.createCreationalContext(factoryBean) + ); + + ResourceUtils.initializeApplication(instance, application, false, false); + instance.setServiceBeans(new ArrayList< Object >(services)); + instance.setProviders(providers); + + final ServiceLoader< MessageBodyWriter > writers = ServiceLoader.load(MessageBodyWriter.class); + for (final MessageBodyWriter< ? > writer: writers) { + instance.setProvider(writer); + } + + final ServiceLoader< MessageBodyReader > readers = ServiceLoader.load(MessageBodyReader.class); + for (final MessageBodyReader< ? > reader: readers) { + instance.setProvider(reader); + } + + return instance; } } http://git-wip-us.apache.org/repos/asf/cxf/blob/3cd24f08/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiServerFactoryBean.java ---------------------------------------------------------------------- diff --git a/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiServerFactoryBean.java b/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiServerFactoryBean.java new file mode 100644 index 0000000..6a1b714 --- /dev/null +++ b/integration/cdi/src/main/java/org/apache/cxf/cdi/JAXRSCdiServerFactoryBean.java @@ -0,0 +1,117 @@ +/** + * 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 java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Any; +import javax.enterprise.inject.Default; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.InjectionPoint; +import javax.enterprise.inject.spi.InjectionTarget; +import javax.enterprise.util.AnnotationLiteral; + +import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; + +public final class JAXRSCdiServerFactoryBean implements Bean< JAXRSServerFactoryBean > { + private static final String FACTORY_BEAN = "factoryBean"; + + private final Bean< ? > applicationBean; + private final InjectionTarget<JAXRSServerFactoryBean> injectionTarget; + + JAXRSCdiServerFactoryBean(final Bean< ? > applicationBean, + final InjectionTarget<JAXRSServerFactoryBean> injectionTarget) { + this.applicationBean = applicationBean; + this.injectionTarget = injectionTarget; + } + + @Override + public Class< ? > getBeanClass() { + return JAXRSServerFactoryBean.class; + } + + @Override + public Set<InjectionPoint> getInjectionPoints() { + return injectionTarget.getInjectionPoints(); + } + + @Override + public String getName() { + return FACTORY_BEAN + applicationBean.getName(); + } + + @SuppressWarnings("serial") + @Override + public Set< Annotation > getQualifiers() { + Set<Annotation> qualifiers = new HashSet<Annotation>(); + qualifiers.add(new AnnotationLiteral< Default >() { }); + qualifiers.add(new AnnotationLiteral< Any >() { }); + return qualifiers; + } + + @Override + public Set<Type> getTypes() { + final Set< Type > types = new HashSet< Type >(); + types.add(JAXRSServerFactoryBean.class); + types.add(Object.class); + return types; + } + + @Override + public Class<? extends Annotation> getScope() { + return ApplicationScoped.class; + } + + @Override + public boolean isAlternative() { + return false; + } + + @Override + public boolean isNullable() { + return false; + } + + @Override + public Set< Class< ? extends Annotation > > getStereotypes() { + return Collections.< Class< ? extends Annotation > >emptySet(); + } + + @Override + public JAXRSServerFactoryBean create(final CreationalContext< JAXRSServerFactoryBean > ctx) { + final JAXRSServerFactoryBean instance = injectionTarget.produce(ctx); + injectionTarget.inject(instance, ctx); + injectionTarget.postConstruct(instance); + return instance; + } + + @Override + public void destroy(final JAXRSServerFactoryBean instance, + final CreationalContext< JAXRSServerFactoryBean > ctx) { + injectionTarget.preDestroy(instance); + injectionTarget.dispose(instance); + ctx.release(); + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/3cd24f08/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java ---------------------------------------------------------------------- diff --git a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java index 67e3634..b67fa79 100644 --- a/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java +++ b/rt/frontend/jaxrs/src/main/java/org/apache/cxf/jaxrs/utils/ResourceUtils.java @@ -722,11 +722,19 @@ public final class ResourceUtils { } return values; } + public static JAXRSServerFactoryBean createApplication(Application app, boolean ignoreAppPath) { return createApplication(app, ignoreAppPath, false); } + public static JAXRSServerFactoryBean createApplication(Application app, boolean ignoreAppPath, boolean staticSubresourceResolution) { + return initializeApplication(new JAXRSServerFactoryBean(), app, + ignoreAppPath, staticSubresourceResolution); + } + + public static JAXRSServerFactoryBean initializeApplication(JAXRSServerFactoryBean bean, + Application app, boolean ignoreAppPath, boolean staticSubresourceResolution) { Set<Object> singletons = app.getSingletons(); verifySingletons(singletons); @@ -767,7 +775,6 @@ public final class ResourceUtils { } } - JAXRSServerFactoryBean bean = new JAXRSServerFactoryBean(); String address = "/"; if (!ignoreAppPath) { ApplicationPath appPath = app.getClass().getAnnotation(ApplicationPath.class); @@ -793,6 +800,7 @@ public final class ResourceUtils { return bean; } + private static boolean isValidProvider(Class<?> c) { if (c == null || c == Object.class) {
