Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 3BBD8200B7F for ; Fri, 5 Aug 2016 02:31:09 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 28A7D160AAE; Fri, 5 Aug 2016 00:31:09 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 50EB6160AAB for ; Fri, 5 Aug 2016 02:31:08 +0200 (CEST) Received: (qmail 57905 invoked by uid 500); 5 Aug 2016 00:31:07 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 57890 invoked by uid 99); 5 Aug 2016 00:31:07 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 05 Aug 2016 00:31:07 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 291D2E0A7D; Fri, 5 Aug 2016 00:31:07 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: reta@apache.org To: commits@cxf.apache.org Date: Fri, 05 Aug 2016 00:31:07 -0000 Message-Id: X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cxf git commit: [CXF-6987] Also consider the classes defined on an application when singletons are populated. This closes #149 archived-at: Fri, 05 Aug 2016 00:31:09 -0000 Repository: cxf Updated Branches: refs/heads/master 4d76ebba4 -> cb405d427 [CXF-6987] Also consider the classes defined on an application when singletons are populated. This closes #149 Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/6becb31c Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/6becb31c Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/6becb31c Branch: refs/heads/master Commit: 6becb31c62ef0845a5078f4ec2124fe7bc264e58 Parents: 4d76ebb Author: John D. Ament Authored: Tue Aug 2 19:49:29 2016 -0400 Committer: reta Committed: Thu Aug 4 20:29:43 2016 -0400 ---------------------------------------------------------------------- .../cxf/cdi/JAXRSCdiResourceExtension.java | 211 ++++++++++++------- .../jaxrs/BookStoreCustomApplication.java | 12 +- 2 files changed, 140 insertions(+), 83 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/6becb31c/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 85b63f0..99f6d87 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,8 +19,13 @@ package org.apache.cxf.cdi; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.List; import java.util.ServiceLoader; +import java.util.Set; import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AfterBeanDiscovery; @@ -41,21 +46,22 @@ import javax.ws.rs.ext.Provider; import org.apache.cxf.Bus; import org.apache.cxf.bus.extension.ExtensionManagerBus; import org.apache.cxf.feature.Feature; +import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.jaxrs.JAXRSServerFactoryBean; import org.apache.cxf.jaxrs.utils.ResourceUtils; /** * Apache CXF portable CDI extension to support initialization of JAX-RS resources. */ -public class JAXRSCdiResourceExtension implements Extension { +public class JAXRSCdiResourceExtension implements Extension { private Bean< ? > busBean; private Bus bus; - + 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< ? extends Feature > > featureBeans = new ArrayList< Bean< ? extends Feature > >(); - + @SuppressWarnings("unchecked") public void collect(@Observes final ProcessBean< T > event) { if (event.getAnnotated().isAnnotationPresent(ApplicationPath.class)) { @@ -66,54 +72,56 @@ public class JAXRSCdiResourceExtension implements Extension { providerBeans.add(event.getBean()); } else if (event.getBean().getTypes().contains(Feature.class)) { featureBeans.add((Bean< ? extends Feature >)event.getBean()); - } else if (CdiBusBean.CXF.equals(event.getBean().getName()) + } else if (CdiBusBean.CXF.equals(event.getBean().getName()) && Bus.class.isAssignableFrom(event.getBean().getBeanClass())) { busBean = event.getBean(); } } - + public void load(@Observes final AfterDeploymentValidation event, final BeanManager beanManager) { bus = (Bus)beanManager.getReference( - busBean, - busBean.getBeanClass(), + busBean, + busBean.getBeanClass(), beanManager.createCreationalContext(busBean) ); - + for (final Bean< ? > application: applicationBeans) { final Application instance = (Application)beanManager.getReference( - application, - application.getBeanClass(), - beanManager.createCreationalContext(application) + application, + application.getBeanClass(), + beanManager.createCreationalContext(application) ); - + // If there is an application without any singletons and classes defined, we will - // create a server factory bean with all services and providers discovered. + // create a server factory bean with all services and providers discovered. if (instance.getSingletons().isEmpty() && instance.getClasses().isEmpty()) { final JAXRSServerFactoryBean factory = createFactoryInstance(instance, - loadServices(beanManager), loadProviders(beanManager), loadFeatures(beanManager)); - factory.init(); + loadServices(beanManager, Collections.>emptySet()), + loadProviders(beanManager, Collections.>emptySet()), + loadFeatures(beanManager, Collections.>emptySet())); + factory.init(); } else { // If there is an application with any singletons or classes defined, we will // create a server factory bean with only application singletons and classes. - final JAXRSServerFactoryBean factory = createFactoryInstance(instance); - factory.init(); + final JAXRSServerFactoryBean factory = createFactoryInstance(instance, beanManager); + factory.init(); } } } public void injectBus(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) { if (busBean == null) { - final AnnotatedType< ExtensionManagerBus > busAnnotatedType = + final AnnotatedType< ExtensionManagerBus > busAnnotatedType = beanManager.createAnnotatedType(ExtensionManagerBus.class); - - final InjectionTarget busInjectionTarget = + + final InjectionTarget busInjectionTarget = beanManager.createInjectionTarget(busAnnotatedType); - + busBean = new CdiBusBean(busInjectionTarget); event.addBean(busBean); - } + } } - + /** * Create the JAXRSServerFactoryBean from the application and all discovered service and provider instances. * @param application application instance @@ -123,30 +131,71 @@ public class JAXRSCdiResourceExtension implements Extension { */ private JAXRSServerFactoryBean createFactoryInstance(final Application application, final List< ? > services, final List< ? > providers, final List< ? extends Feature > features) { - - final JAXRSServerFactoryBean instance = ResourceUtils.createApplication(application, false, false); - instance.setServiceBeans(new ArrayList< Object >(services)); + + final JAXRSServerFactoryBean instance = ResourceUtils.createApplication(application, false, false); + instance.setServiceBeans(new ArrayList<>(services)); instance.setProviders(providers); instance.setProviders(loadExternalProviders()); instance.setFeatures(features); - instance.setBus(bus); - - return instance; + instance.setBus(bus); + + return instance; } - + /** * Create the JAXRSServerFactoryBean from the objects declared by application itself. * @param application application instance * @return JAXRSServerFactoryBean instance */ - private JAXRSServerFactoryBean createFactoryInstance(final Application application) { - + private JAXRSServerFactoryBean createFactoryInstance(final Application application, final BeanManager beanManager) { + final JAXRSServerFactoryBean instance = ResourceUtils.createApplication(application, false, false); + final Map< Class< ? >, List< Object > > classified = classifySingletons(application, beanManager); + instance.setServiceBeans(classified.get(Path.class)); + instance.setProviders(classified.get(Provider.class)); + instance.setFeatures(CastUtils.cast(classified.get(Feature.class), Feature.class)); instance.setBus(bus); - return instance; + return instance; } - + + /** + * JAX-RS application has defined singletons as being instances of any providers, resources and features. + * In the JAXRSServerFactoryBean, those should be split around several method calls depending on instance + * type. At the moment, only the Feature is CXF-specific and should be replaced by JAX-RS Feature implementation. + * @param application the application instance + * @return classified singletons by instance types + */ + private Map< Class< ? >, List< Object > > classifySingletons(final Application application, + final BeanManager beanManager) { + final Set singletons = application.getSingletons(); + final Map< Class< ? >, List< Object > > classified = + new HashMap<>(); + + classified.put(Feature.class, new ArrayList<>()); + classified.put(Provider.class, new ArrayList<>()); + classified.put(Path.class, new ArrayList<>()); + + for (final Object singleton: singletons) { + if (singleton instanceof Feature) { + classified.get(Feature.class).add(singleton); + } else if (singleton.getClass().isAnnotationPresent(Provider.class)) { + classified.get(Provider.class).add(singleton); + } else if (singleton.getClass().isAnnotationPresent(Path.class)) { + classified.get(Path.class).add(singleton); + } + } + + // now loop through the classes + Set> classes = application.getClasses(); + if (!classes.isEmpty()) { + classified.get(Path.class).addAll(loadServices(beanManager, classes)); + classified.get(Provider.class).addAll(loadProviders(beanManager, classes)); + classified.get(Feature.class).addAll(loadFeatures(beanManager, classes)); + } + return classified; + } + /** * Load external providers from service loader * @return loaded external providers @@ -154,78 +203,84 @@ public class JAXRSCdiResourceExtension implements Extension { @SuppressWarnings("rawtypes") private List< Object > loadExternalProviders() { final List< Object > providers = new ArrayList< Object >(); - + final ServiceLoader< MessageBodyWriter > writers = ServiceLoader.load(MessageBodyWriter.class); for (final MessageBodyWriter< ? > writer: writers) { providers.add(writer); } - + final ServiceLoader< MessageBodyReader > readers = ServiceLoader.load(MessageBodyReader.class); for (final MessageBodyReader< ? > reader: readers) { providers.add(reader); } - + return providers; } - + /** - * Gets the references for all discovered JAX-RS resources + * Gets the references for all discovered JAX-RS resources * @param beanManager bean manager instance - * @return the references for all discovered JAX-RS resources + * @param limitedClasses not null, if empty ignored. the set of classes to consider as providers + * @return the references for all discovered JAX-RS resources */ - private List< Object > loadProviders(final BeanManager beanManager) { - final List< Object > providers = new ArrayList< Object >(); - - for (final Bean< ? > bean: providerBeans) { - providers.add( - beanManager.getReference( - bean, - bean.getBeanClass(), - beanManager.createCreationalContext(bean) - ) - ); - } - - return providers; + private List< Object > loadProviders(final BeanManager beanManager, Collection> limitedClasses) { + return loadBeans(beanManager, limitedClasses, providerBeans); } /** - * Gets the references for all discovered JAX-RS providers + * Gets the references for all discovered JAX-RS providers * @param beanManager bean manager instance - * @return the references for all discovered JAX-RS providers + * @param limitedClasses not null, if empty ignored. the set of classes to consider as providers + * @return the references for all discovered JAX-RS providers */ - private List< Object > loadServices(final BeanManager beanManager) { - final List< Object > services = new ArrayList< Object >(); - - for (final Bean< ? > bean: serviceBeans) { - services.add( - beanManager.getReference( - bean, - bean.getBeanClass(), - beanManager.createCreationalContext(bean) - ) - ); + private List< Object > loadServices(final BeanManager beanManager, Collection> limitedClasses) { + return loadBeans(beanManager, limitedClasses, serviceBeans); + } + + /** + * Gets references for all beans of a given type + * @param beanManager bean manager instance + * @param limitedClasses not null, if empty ignored. the set of classes to consider as providers + * @param beans the collection of beans to go through + * @return the references for all discovered JAX-RS providers + */ + private List< Object > loadBeans(final BeanManager beanManager, Collection> limitedClasses, + Collection> beans) { + final List< Object > instances = new ArrayList<>(); + + for (final Bean< ? > bean: beans) { + if (limitedClasses.isEmpty() || limitedClasses.contains(bean.getBeanClass())) { + instances.add( + beanManager.getReference( + bean, + bean.getBeanClass(), + beanManager.createCreationalContext(bean) + ) + ); + } } - - return services; + + return instances; } - + /** * Gets the references for all discovered CXF-specific features * @param beanManager bean manager instance * @return the references for all discovered CXF-specific features */ - private List< Feature > loadFeatures(final BeanManager beanManager) { + private List< Feature > loadFeatures(final BeanManager beanManager, Collection> limitedClasses) { final List< Feature > services = new ArrayList<>(); for (final Bean< ? extends Feature > bean: featureBeans) { - services.add( - (Feature)beanManager.getReference( - bean, - bean.getBeanClass(), - beanManager.createCreationalContext(bean) - ) - ); + if (limitedClasses.isEmpty() || limitedClasses.contains(bean.getBeanClass())) { + services.add( + (Feature) beanManager.getReference( + bean, + bean.getBeanClass(), + beanManager.createCreationalContext(bean) + ) + ); + } } return services; http://git-wip-us.apache.org/repos/asf/cxf/blob/6becb31c/systests/cdi/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java ---------------------------------------------------------------------- diff --git a/systests/cdi/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java b/systests/cdi/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java index eeb20f4..5756344 100644 --- a/systests/cdi/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java +++ b/systests/cdi/src/test/java/org/apache/cxf/systest/jaxrs/BookStoreCustomApplication.java @@ -18,9 +18,9 @@ */ package org.apache.cxf.systest.jaxrs; +import java.util.Collections; import java.util.Set; -import javax.inject.Inject; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @@ -33,14 +33,16 @@ import org.apache.cxf.systest.jaxrs.cdi.BookStore; @ApplicationPath("/custom") public class BookStoreCustomApplication extends Application { - @Inject private BookStore bookStore; - @Override public Set< Object > getSingletons() { - return Sets.< Object >newHashSet( - bookStore, + return Sets.newHashSet( new JacksonJsonProvider(), new ValidationExceptionMapper(), new JAXRSBeanValidationFeature()); } + + @Override + public Set> getClasses() { + return Collections.>singleton(BookStore.class); + } }