Author: cmoulliard Date: Mon Feb 6 11:08:44 2012 New Revision: 1240976 URL: http://svn.apache.org/viewvc?rev=1240976&view=rev Log: Add BeanManagerProvider and services (javax.enterprise.inject.spi.extension)
Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/AnyLiteral.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanManagerProvider.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanProvider.java camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/package-info.java camel/trunk/components/camel-cdi/src/main/resources/META-INF/beans.xml - copied unchanged from r1233921, camel/trunk/components/camel-cdi/src/test/resources/META-INF/beans.xml camel/trunk/components/camel-cdi/src/main/resources/META-INF/services/ camel/trunk/components/camel-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Modified: camel/trunk/components/camel-cdi/pom.xml camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/CdiContainerBeanManagerTest.java Modified: camel/trunk/components/camel-cdi/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/pom.xml?rev=1240976&r1=1240975&r2=1240976&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/pom.xml (original) +++ camel/trunk/components/camel-cdi/pom.xml Mon Feb 6 11:08:44 2012 @@ -41,6 +41,7 @@ ${camel.osgi.import.defaults}, * </camel.osgi.import.pkg> + <openwebbeans.version>1.1.4-SNAPSHOT</openwebbeans.version> </properties> <dependencies> @@ -48,20 +49,24 @@ <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> </dependency> + <dependency> + <groupId>org.apache.camel</groupId> + <artifactId>camel-spring</artifactId> + </dependency> <!-- JSR-299 Impl --> <dependency> <groupId>org.apache.openwebbeans</groupId> <artifactId>openwebbeans-impl</artifactId> - <version>${openwebbeans-version}</version> - <scope>compile</scope> + <version>${openwebbeans.version}</version> + <scope>test</scope> </dependency> <!-- SPI API --> <dependency> <groupId>org.apache.openwebbeans</groupId> <artifactId>openwebbeans-spi</artifactId> - <version>${openwebbeans-version}</version> + <version>${openwebbeans.version}</version> <scope>compile</scope> </dependency> @@ -76,7 +81,7 @@ <dependency> <groupId>org.apache.openwebbeans</groupId> <artifactId>openwebbeans-el10</artifactId> - <version>${openwebbeans-version}</version> + <version>${openwebbeans.version}</version> <scope>compile</scope> </dependency> @@ -85,6 +90,7 @@ <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jcdi_1.0_spec</artifactId> <version>1.0</version> + <scope>provided</scope> </dependency> <!-- JSR-330 API --> @@ -92,6 +98,7 @@ <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-atinject_1.0_spec</artifactId> <version>1.0</version> + <scope>provided</scope> </dependency> <!-- logging --> @@ -112,13 +119,13 @@ <dependency> <groupId>org.apache.openwebbeans.test</groupId> <artifactId>cditest</artifactId> - <version>${openwebbeans-version}</version> + <version>${openwebbeans.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.openwebbeans.test</groupId> <artifactId>cditest-owb</artifactId> - <version>${openwebbeans-version}</version> + <version>${openwebbeans.version}</version> <scope>test</scope> </dependency> <dependency> @@ -139,5 +146,8 @@ </dependency> </dependencies> - + + <build> + <defaultGoal>install</defaultGoal> + </build> </project> Modified: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java?rev=1240976&r1=1240975&r2=1240976&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java (original) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/CdiBeanRegistry.java Mon Feb 6 11:08:44 2012 @@ -16,19 +16,18 @@ */ package org.apache.camel.component.cdi; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; -import javax.enterprise.context.spi.CreationalContext; -import javax.enterprise.inject.spi.Bean; -import javax.enterprise.inject.spi.BeanManager; - import org.apache.camel.spi.Registry; -import org.apache.camel.util.ObjectHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.Map; + +import static org.apache.camel.component.cdi.util.BeanProvider.getContextualNamesReferences; +import static org.apache.camel.component.cdi.util.BeanProvider.getContextualReference; +import static org.apache.camel.util.ObjectHelper.notEmpty; +import static org.apache.camel.util.ObjectHelper.notNull; + + /** * CdiBeanRegistry used by Camel to perform lookup into the * Cdi BeanManager. The BeanManager must be passed as argument @@ -36,72 +35,34 @@ import org.slf4j.LoggerFactory; */ public class CdiBeanRegistry implements Registry { - private static final Logger LOG = LoggerFactory.getLogger(CdiBeanRegistry.class); - private final BeanManager delegate; - - public CdiBeanRegistry(final BeanManager delegate) throws IllegalArgumentException { - ObjectHelper.notNull(delegate, "delegate"); - this.delegate = delegate; - } + private final Logger log = LoggerFactory.getLogger(getClass()); + /** + * @see org.apache.camel.spi.Registry#lookup(java.lang.String) + */ @Override public Object lookup(final String name) { - ObjectHelper.notEmpty(name, "name"); - LOG.trace("Looking up bean using name = [{}] in CDI registry.", name); - - final Set<Bean<?>> beans = getDelegate().getBeans(name); - if (beans.isEmpty()) { - LOG.debug("Found no bean matching name = [{}] in CDI registry.", name); - return null; - } - if (beans.size() > 1) { - throw new IllegalStateException("Expected to find exactly one bean having name [" + name + "], but got [" + beans.size() + "]"); - } - final Bean<?> bean = beans.iterator().next(); - LOG.debug("Found bean [{}] matching name = [{}] in CDI registry.", bean, name); + notEmpty(name, "name"); + log.trace("Looking up bean using name = [{}] in CDI registry ...", name); - final CreationalContext<?> context = getDelegate().createCreationalContext(null); - return getDelegate().getReference(bean, bean.getBeanClass(), context); + return getContextualReference(name, true); } - @Override - public <T> T lookup(final String name, final Class<T> type) { - ObjectHelper.notEmpty(name, "name"); - ObjectHelper.notNull(type, "type"); - LOG.trace("Looking up bean using name = [{}] having expected type = [{}] in CDI registry.", name, type.getName()); - - return type.cast(lookup(name)); - } - - @Override - public <T> Map<String, T> lookupByType(final Class<T> type) { - ObjectHelper.notNull(type, "type"); - LOG.trace("Looking up all beans having expected type = [{}] in CDI registry.", type.getName()); - - final Set<Bean<?>> beans = getDelegate().getBeans(type); - if (beans.isEmpty()) { - LOG.debug("Found no beans having expected type = [{}] in CDI registry.", type.getName()); - return Collections.emptyMap(); - } - - LOG.debug("Found [{}] beans having expected type = [{}] in CDI registry.", Integer.valueOf(beans.size()), type.getName()); - - final Map<String, T> beansByName = new HashMap<String, T>(beans.size()); - final CreationalContext<?> context = getDelegate().createCreationalContext(null); - - for (final Bean<?> bean : beans) { - beansByName.put(bean.getName(), type.cast(getDelegate().getReference(bean, type, context))); - } - - return beansByName; - } - - @Override - public String toString() { - return "CdiRegistry[" + this.delegate + "]"; - } - - private BeanManager getDelegate() { - return this.delegate; - } + @Override + public <T> T lookup(final String name, final Class<T> type) { + notEmpty(name, "name"); + notNull(type, "type"); + return type.cast(lookup(name)); + } + + @Override + public <T> Map<String, T> lookupByType(final Class<T> type) { + notNull(type, "type"); + return getContextualNamesReferences(type, true, true); + } + + @Override + public String toString() { + return "CdiRegistry[" + System.identityHashCode(this) + "]"; + } } Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/AnyLiteral.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/AnyLiteral.java?rev=1240976&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/AnyLiteral.java (added) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/AnyLiteral.java Mon Feb 6 11:08:44 2012 @@ -0,0 +1,7 @@ +package org.apache.camel.component.cdi.util; + +import javax.enterprise.inject.Any; +import javax.enterprise.util.AnnotationLiteral; + +public class AnyLiteral extends AnnotationLiteral<Any> implements Any { +} Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanManagerProvider.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanManagerProvider.java?rev=1240976&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanManagerProvider.java (added) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanManagerProvider.java Mon Feb 6 11:08:44 2012 @@ -0,0 +1,193 @@ +/* + * 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.camel.component.cdi.util; + +import javax.enterprise.event.Observes; +import javax.enterprise.inject.spi.AfterBeanDiscovery; +import javax.enterprise.inject.spi.BeanManager; +import javax.enterprise.inject.spi.BeforeShutdown; +import javax.enterprise.inject.spi.Extension; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + + +/** + * <p>This class provides access to the {@link BeanManager} + * by registering the current {@link BeanManager} in an extension and + * making it available via a singleton factory for the current application.</p> + * <p>This is really handy if you like to access CDI functionality + * from places where no injection is available.</p> + * <p>If a simple but manual bean-lookup is needed, it's easier to use the {@link BeanProvider}.</p> + * <p/> + * <p>As soon as an application shuts down, the reference to the {@link BeanManager} will be removed.<p> + * <p/> + * <p>Usage:<p/> + * <pre> + * BeanManager bm = BeanManagerProvider.getInstance().getBeanManager(); + * </pre> + */ +public class BeanManagerProvider implements Extension { + private static BeanManagerProvider bmp = null; + + private volatile Map<ClassLoader, BeanManager> bms = new ConcurrentHashMap<ClassLoader, BeanManager>(); + + /** + * Returns if the {@link BeanManagerProvider} has been initialized. + * Usually it isn't needed to call this method in application code. + * It's e.g. useful for other frameworks to check if DeltaSpike and the CDI container in general have been started. + * + * @return true if the bean-manager-provider is ready to be used + */ + public static boolean isActive() { + return bmp != null; + } + + /** + * Allows to get the current provider instance which provides access to the current {@link BeanManager} + * + * @return the singleton BeanManagerProvider + * @throws IllegalStateException if the {@link BeanManagerProvider} isn't ready to be used. + * That's the case if the environment isn't configured properly and therefore the {@link AfterBeanDiscovery} + * hasn't be called before this method gets called. + */ + public static BeanManagerProvider getInstance() { + if (bmp == null) { + //X TODO Java-EE5 support needs to be discussed + // workaround for some Java-EE5 environments in combination with a special + // StartupBroadcaster for bootstrapping CDI + + // CodiStartupBroadcaster.broadcastStartup(); + // here bmp might not be null (depends on the broadcasters) + } + if (bmp == null) { + throw new IllegalStateException("No " + BeanManagerProvider.class.getName() + " in place! " + + "Please ensure that you configured the CDI implementation of your choice properly. " + + "If your setup is correct, please clear all caches and compiled artifacts."); + } + return bmp; + } + + + /** + * The active {@link BeanManager} for the current application (/{@link ClassLoader}) + * + * @return the current bean-manager + */ + public BeanManager getBeanManager() { + ClassLoader classLoader = getClassLoader(); + + BeanManager result = bms.get(classLoader); + + if (result == null) { + result = resolveBeanManagerViaJndi(); + + if (result != null) { + bms.put(classLoader, result); + } + } + return result; + } + + public static ClassLoader getClassLoader() { + ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { + /** + * {@inheritDoc} + */ + @Override + public ClassLoader run() { + try { + return Thread.currentThread().getContextClassLoader(); + } catch (Exception e) { + return null; + } + } + } + ); + + if (loader == null) { + loader = BeanManagerProvider.class.getClassLoader(); + } + + return loader; + } + + /** + * It basically doesn't matter which of the system events we use, + * but basically we use the {@link AfterBeanDiscovery} event since it allows to use the + * {@link BeanManagerProvider} for all events which occur after the {@link AfterBeanDiscovery} event. + * + * @param afterBeanDiscovery event which we don't actually use ;) + * @param beanManager the BeanManager we store and make available. + */ + protected void setBeanManager(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager) { + BeanManagerProvider bmpFirst = setBeanManagerProvider(this); + + ClassLoader cl = getClassLoader(); + bmpFirst.bms.put(cl, beanManager); + + //X TODO Java-EE5 support needs to be discussed + //CodiStartupBroadcaster.broadcastStartup(); + } + + /** + * Cleanup on container shutdown + * + * @param beforeShutdown cdi shutdown event + */ + protected void cleanupStoredBeanManagerOnShutdown(@Observes BeforeShutdown beforeShutdown) { + bms.remove(getClassLoader()); + } + + /** + * Get the BeanManager from the JNDI registry. + * <p/> + * Workaround for JBossAS 6 (see EXTCDI-74) + * {@link #setBeanManager(javax.enterprise.inject.spi.AfterBeanDiscovery, javax.enterprise.inject.spi.BeanManager)} + * is called in context of a different {@link ClassLoader} + * + * @return current {@link javax.enterprise.inject.spi.BeanManager} which is provided via JNDI + */ + private BeanManager resolveBeanManagerViaJndi() { + try { + return (BeanManager) new InitialContext().lookup("java:comp/BeanManager"); + } catch (NamingException e) { + //workaround didn't work -> force NPE + return null; + } + } + + /** + * This function exists to prevent findbugs to complain about + * setting a static member from a non-static function. + * + * @param beanManagerProvider the bean-manager-provider which should be used if there isn't an existing provider + * @return the first BeanManagerProvider + */ + private static BeanManagerProvider setBeanManagerProvider(BeanManagerProvider beanManagerProvider) { + if (bmp == null) { + bmp = beanManagerProvider; + } + + return bmp; + } +} Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanProvider.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanProvider.java?rev=1240976&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanProvider.java (added) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/BeanProvider.java Mon Feb 6 11:08:44 2012 @@ -0,0 +1,267 @@ +/* + * 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.camel.component.cdi.util; + +import javax.enterprise.context.Dependent; +import javax.enterprise.context.spi.CreationalContext; +import javax.enterprise.inject.Typed; +import javax.enterprise.inject.spi.Bean; +import javax.enterprise.inject.spi.BeanManager; +import java.lang.annotation.Annotation; +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.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * This class contains utility methods to resolve contextual references + * in situations where no injection is available. + * + * @see BeanManagerProvider + */ +@Typed +public final class BeanProvider { + + private BeanProvider() { + // this is a utility class which doesn't get instantiated. + } + + /** + * <p></p>Get a Contextual Reference by it's type and annotation (qualifier). + * You can use this method to get contextual references of a given type. + * A 'Contextual Reference' is a proxy which will automatically resolve + * the correct contextual instance when you access any method.</p> + * <p/> + * <p><b>Attention:</b> You shall not use this method to manually resolve a + * @Dependent bean! The reason is that this contextual instances do usually + * live in the well defined lifecycle of their injection point (the bean they got + * injected into). But if we manually resolve a @Dependent bean, then it does <b>not</b> + * belong to such a well defined lifecycle (because @Dependent it is not + * @NormalScoped) and thus will not automatically be + * destroyed at the end of the lifecycle. You need to manually destroy this contextual instance via + * {@link javax.enterprise.context.spi.Contextual#destroy(Object, javax.enterprise.context.spi.CreationalContext)}. + * Thus you also need to manually store the CreationalContext and the Bean you + * used to create the contextual instance which this method will not provide.</p> + * + * @param type the type of the bean in question + * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created. + * Otherwise it will throw an {@code IllegalStateException} + * @param qualifiers additional qualifiers which further distinct the resolved bean + * @param <T> target type + * @return the resolved Contextual Reference + */ + public static <T> T getContextualReference(Class<T> type, boolean optional, Annotation... qualifiers) { + BeanManager beanManager = getBeanManager(); + Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers); + + if (beans == null || beans.isEmpty()) { + if (optional) { + return null; + } + + throw new IllegalStateException("Could not find beans for Type=" + type + + " and qualifiers:" + Arrays.toString(qualifiers)); + } + + return getContextualReference(type, beanManager, beans); + } + + /** + * <p>Get a Contextual Reference by it's EL Name. + * This only works for beans with the @Named annotation.</p> + * <p/> + * <p><b>Attention:</b> please see the notes on manually resolving @Dependent bean + * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p> + * + * @param name the EL name of the bean + * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created. + * Otherwise it will throw an {@code IllegalStateException} + * @return the resolved Contextual Reference + */ + public static Object getContextualReference(String name, boolean optional) { + return getContextualReference(name, optional, Object.class); + } + + /** + * <p>Get a Contextual Reference by it's EL Name. + * This only works for beans with the @Named annotation.</p> + * <p/> + * <p><b>Attention:</b> please see the notes on manually resolving @Dependent bean + * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p> + * + * @param name the EL name of the bean + * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created. + * Otherwise it will throw an {@code IllegalStateException} + * @param type the type of the bean in question - use {@link #getContextualReference(String, boolean)} + * if the type is unknown e.g. in dyn. use-cases + * @param <T> target type + * @return the resolved Contextual Reference + */ + public static <T> T getContextualReference(String name, boolean optional, Class<T> type) { + BeanManager beanManager = getBeanManager(); + Set<Bean<?>> beans = beanManager.getBeans(name); + + if (beans == null || beans.isEmpty()) { + if (optional) { + return null; + } + + throw new IllegalStateException("Could not find beans for Type=" + type + + " and name:" + name); + } + + return getContextualReference(type, beanManager, beans); + } + + /** + * <p>Get a list of Contextual References by it's type independent of the qualifier + * (including dependent scoped beans). + * <p/> + * You can use this method to get all contextual references of a given type. + * A 'Contextual Reference' is a proxy which will automatically resolve + * the correct contextual instance when you access any method.</p> + * <p/> + * <p><b>Attention:</b> please see the notes on manually resolving @Dependent bean + * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p> + * + * @param type the type of the bean in question + * @param optional if <code>true</code> it will return an empty list if no bean could be found or created. + * Otherwise it will throw an {@code IllegalStateException} + * @param <T> target type + * @return the resolved list of Contextual Reference or an empty-list if optional is true + */ + public static <T> List<T> getContextualReferences(Class<T> type, + boolean optional) { + return getContextualReferences(type, optional, true); + } + + /** + * <p>Get a list of Contextual References by it's type independent of the qualifier. + * <p/> + * Further details are available at {@link #getContextualReferences(Class, boolean)} + * + * @param type the type of the bean in question + * @param optional if <code>true</code> it will return an empty list if no bean could be found or created. + * Otherwise it will throw an {@code IllegalStateException} + * @param includeDefaultScopedBeans specifies if dependent scoped beans should be included in the in the result + * @param <T> target type + * @return the resolved list of Contextual Reference or an empty-list if optional is true + */ + public static <T> List<T> getContextualReferences(Class<T> type, + boolean optional, + boolean includeDefaultScopedBeans) { + BeanManager beanManager = getBeanManager(); + Set<Bean<?>> beans = beanManager.getBeans(type, new AnyLiteral()); + + if (beans == null || beans.isEmpty()) { + if (optional) { + return Collections.emptyList(); + } + + throw new IllegalStateException("Could not find beans for Type=" + type); + } + + if (!includeDefaultScopedBeans) { + beans = filterDefaultScopedBeans(beans); + } + + List<T> result = new ArrayList<T>(beans.size()); + + for (Bean<?> bean : beans) { + result.add(getContextualReference(type, beanManager, + new HashSet<Bean<?>>((Collection) Arrays.asList(new Object[]{bean})))); + } + return result; + } + + public static <T> Map<String, T> getContextualNamesReferences(Class<T> type, + boolean optional, + boolean includeDefaultScopedBeans) { + BeanManager beanManager = getBeanManager(); + Set<Bean<?>> beans = beanManager.getBeans(type, new AnyLiteral()); + + if (beans == null || beans.isEmpty()) { + if (optional) { + return Collections.emptyMap(); + } + + throw new IllegalStateException("Could not find beans for Type=" + type); + } + + if (!includeDefaultScopedBeans) { + beans = filterDefaultScopedBeans(beans); + } + + Map<String, T> result = new HashMap<String, T>(beans.size()); + + for (Bean<?> bean : beans) { + result.put(bean.getName(), getContextualReference(type, beanManager, + new HashSet<Bean<?>>((Collection) Arrays.asList(new Object[]{bean})))); + } + return result; + } + + private static Set<Bean<?>> filterDefaultScopedBeans(Set<Bean<?>> beans) { + Set<Bean<?>> result = new HashSet<Bean<?>>(beans.size()); + + Iterator<Bean<?>> beanIterator = beans.iterator(); + + Bean<?> currentBean; + while (beanIterator.hasNext()) { + currentBean = beanIterator.next(); + + if (!Dependent.class.isAssignableFrom(currentBean.getScope())) { + result.add(currentBean); + } + } + return result; + } + + /** + * Internal helper method to resolve the right bean and resolve the contextual reference. + * + * @param type the type of the bean in question + * @param beanManager current bean-manager + * @param beans beans in question + * @param <T> target type + * @return the contextual reference + */ + private static <T> T getContextualReference(Class<T> type, BeanManager beanManager, Set<Bean<?>> beans) { + Bean<?> bean = beanManager.resolve(beans); + + CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean); + + @SuppressWarnings({"unchecked", "UnnecessaryLocalVariable"}) + T result = (T) beanManager.getReference(bean, type, creationalContext); + return result; + } + + /** + * Internal method to resolve the BeanManager via the {@link BeanManagerProvider} + */ + private static BeanManager getBeanManager() { + return BeanManagerProvider.getInstance().getBeanManager(); + } +} Added: camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/package-info.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/package-info.java?rev=1240976&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/package-info.java (added) +++ camel/trunk/components/camel-cdi/src/main/java/org/apache/camel/component/cdi/util/package-info.java Mon Feb 6 11:08:44 2012 @@ -0,0 +1,5 @@ +/** + * mainly copied from deltaspike to avoid to bring to whole + * package when only 2 classes are useful. + */ +package org.apache.camel.component.cdi.util; Added: camel/trunk/components/camel-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1240976&view=auto ============================================================================== --- camel/trunk/components/camel-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added) +++ camel/trunk/components/camel-cdi/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Mon Feb 6 11:08:44 2012 @@ -0,0 +1,17 @@ +# +# 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. +# +org.apache.camel.component.cdi.util.BeanManagerProvider Modified: camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/CdiContainerBeanManagerTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/CdiContainerBeanManagerTest.java?rev=1240976&r1=1240975&r2=1240976&view=diff ============================================================================== --- camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/CdiContainerBeanManagerTest.java (original) +++ camel/trunk/components/camel-cdi/src/test/java/org/apache/camel/cdi/CdiContainerBeanManagerTest.java Mon Feb 6 11:08:44 2012 @@ -1,28 +1,8 @@ -/** - * 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.camel.cdi; -import java.util.ArrayList; -import java.util.List; -import javax.enterprise.inject.spi.BeanManager; -import javax.inject.Inject; - import org.apache.camel.CamelContext; import org.apache.camel.Exchange; +import org.apache.camel.ProducerTemplate; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.cdi.store.Item; import org.apache.camel.cdi.store.ShoppingBean; @@ -36,27 +16,38 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + public class CdiContainerBeanManagerTest extends CamelTestSupport { - private CdiTestContainer cdiContainer; + private MockEndpoint resultEndpoint; + + private ProducerTemplate template; + + CdiTestContainer cdiContainer; + CamelContext camelContext; @Inject - private ShoppingBean shoppingBean; + ShoppingBean shoppingBean; @Before public void setUp() throws Exception { cdiContainer = CdiTestContainerLoader.getCdiContainer(); cdiContainer.bootContainer(); - cdiContainer.startContexts(); - super.setUp(); - } + System.out.println(">> Container started and bean manager instantiated !"); - @Override - protected CamelContext createCamelContext() throws Exception { - BeanManager beanManager = cdiContainer.getBeanManager(); - context = new DefaultCamelContext(new CdiBeanRegistry(beanManager)); - return context; + // Camel + context = new DefaultCamelContext(new CdiBeanRegistry()); + context.addRoutes(createRouteBuilder()); + context.setTracing(true); + context.start(); + resultEndpoint = context.getEndpoint("mock:result", MockEndpoint.class); + template = context.createProducerTemplate(); + + System.out.println(">> Camel started !"); } @After @@ -66,25 +57,22 @@ public class CdiContainerBeanManagerTest } @Test - @SuppressWarnings("unchecked") public void testInjection() throws InterruptedException { - MockEndpoint mock = getMockEndpoint("mock:result"); - mock.expectedMessageCount(1); - + resultEndpoint.expectedMessageCount(1); template.sendBody("direct:inject", "hello"); assertMockEndpointsSatisfied(); - Exchange exchange = mock.getExchanges().get(0); + Exchange exchange = resultEndpoint.getExchanges().get(0); List<Item> results = (List<Item>) exchange.getIn().getBody(); - Object[] items = results.toArray(); - Object[] itemsExpected = itemsExpected().toArray(); - for (int i = 0; i < items.length; ++i) { - Item itemExpected = (Item) items[i]; - Item itemReceived = (Item) itemsExpected[i]; - assertEquals(itemExpected.getName(), itemReceived.getName()); - assertEquals(itemExpected.getPrice(), itemReceived.getPrice()); + Object[] items = (Object[]) results.toArray(); + Object[] itemsExpected = (Object[]) itemsExpected().toArray(); + for(int i=0; i< items.length; ++i) { + Item itemExpected = (Item)items[i]; + Item itemReceived = (Item)itemsExpected[i]; + assertEquals(itemExpected.getName(), itemReceived.getName()); + assertEquals(itemExpected.getPrice(), itemReceived.getPrice()); } assertNotNull(results); @@ -109,11 +97,15 @@ public class CdiContainerBeanManagerTest return new RouteBuilder() { @Override public void configure() throws Exception { + from("direct:inject") .beanRef("shoppingBean", "listAllProducts") .to("mock:result"); + } + }; } + }