Skip to content

Commit

Permalink
WW-3767:
Browse files Browse the repository at this point in the history
- added support for servlet container JNDI lookup key java:comp/env/BeanManager
- added support for custom configuration constant to override standard lookup

git-svn-id: https://svn.apache.org/repos/asf/struts/struts2/trunk@1294420 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
rgielen committed Feb 28, 2012
1 parent 94d75f9 commit 20689c0
Showing 1 changed file with 87 additions and 28 deletions.
115 changes: 87 additions & 28 deletions plugins/cdi/src/main/java/org/apache/struts2/cdi/CdiObjectFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package org.apache.struts2.cdi;

import com.opensymphony.xwork2.ObjectFactory;
import com.opensymphony.xwork2.inject.Inject;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;

Expand All @@ -35,6 +36,13 @@
/**
* CdiObjectFactory allows Struts 2 managed objects, like Actions, Interceptors or Results, to be injected by a Contexts
* and Dependency Injection container (JSR299 / WebBeans).
* The BeanManager instance will be searched in the container's JNDI context, according to following algorithm:
* <ul>
* <li>if a value for configuration constant <code>struts.objectFactory.cdi.jndiKey</code> is given, this key will be looked up</li>
* <li>if no BeanManager found so far, look under {@link #CDI_JNDIKEY_BEANMANAGER_COMP}</li>
* <li>if no BeanManager found so far, look under {@link #CDI_JNDIKEY_BEANMANAGER_APP}</li>
* <li>if no BeanManager found so far, look under {@link #CDI_JNDIKEY_BEANMANAGER_COMP_ENV}</li>
* </ul>
*/
public class CdiObjectFactory extends ObjectFactory {

Expand All @@ -48,8 +56,20 @@ public class CdiObjectFactory extends ObjectFactory {
* The key under which the BeanManager can be found according to JBoss Weld docs
*/
public static final String CDI_JNDIKEY_BEANMANAGER_APP = "java:app/BeanManager";
/**
* The key under which the BeanManager can be found in pure Servlet containers according to JBoss Weld docs.
*/
public static final String CDI_JNDIKEY_BEANMANAGER_COMP_ENV = "java:comp/env/BeanManager";

protected BeanManager beanManager;

private String jndiKey;

@Inject(value = "struts.objectFactory.cdi.jndiKey", required = false)
public void setJndiKey( String jndiKey ) {
this.jndiKey = jndiKey;
}

protected BeanManager beanManager;
protected CreationalContext ctx;

Map<Class<?>, InjectionTarget<?>> injectionTargetCache = new ConcurrentHashMap<Class<?>, InjectionTarget<?>>();
Expand All @@ -66,33 +86,72 @@ public CdiObjectFactory() {
}
}

/**
* Try to find the CDI BeanManager from JNDI context. First the key {@link #CDI_JNDIKEY_BEANMANAGER_COMP} will be
* tested. If nothing is found there, the key {@link #CDI_JNDIKEY_BEANMANAGER_APP} will be checked.
*
* @return the BeanManager, if found. <tt>null</tt> otherwise.
*/
protected BeanManager findBeanManager() {
BeanManager bm;
try {
Context initialContext = new InitialContext();
LOG.info("[findBeanManager]: Checking for BeanManager under JNDI key " + CDI_JNDIKEY_BEANMANAGER_COMP);
try {
bm = (BeanManager) initialContext.lookup(CdiObjectFactory.CDI_JNDIKEY_BEANMANAGER_COMP);
} catch (NamingException e) {
LOG.warn("[findBeanManager]: Lookup failed.", e);
LOG.info("[findBeanManager]: Checking for BeanManager under JNDI key " + CDI_JNDIKEY_BEANMANAGER_APP);
bm = (BeanManager) initialContext.lookup(CdiObjectFactory.CDI_JNDIKEY_BEANMANAGER_APP);
}
LOG.info("[findBeanManager]: BeanManager found.");
return bm;
} catch (NamingException e) {
LOG.error("Could not get BeanManager from JNDI context", e);
}
return null;
}

@Override
/**
* Try to find the CDI BeanManager from JNDI context. First, if provided, the key given by
* struts.objectFactory.cdi.jndiKey will be checked. Then, if nothing was found or no explicit configuration was
* given, the key {@link #CDI_JNDIKEY_BEANMANAGER_COMP} will be tested. If nothing is found there, the key {@link
* #CDI_JNDIKEY_BEANMANAGER_APP} will be checked. If still nothing is found there, the key {@link
* #CDI_JNDIKEY_BEANMANAGER_COMP_ENV} will be checked.
*
* @return the BeanManager, if found. <tt>null</tt> otherwise.
*/
protected BeanManager findBeanManager() {
BeanManager bm = null;
try {
Context initialContext = new InitialContext();
if (jndiKey != null && jndiKey.trim().length() > 0) {
// Check explicit configuration first, if given
bm = lookup(initialContext, jndiKey);
}
if (bm == null) {
// Check CDI default
bm = lookup(initialContext, CDI_JNDIKEY_BEANMANAGER_COMP);
}
if (bm == null) {
// Check WELD default
bm = lookup(initialContext, CDI_JNDIKEY_BEANMANAGER_APP);
}
if (bm == null) {
// Check Tomcat / Jetty default
bm = lookup(initialContext, CDI_JNDIKEY_BEANMANAGER_COMP_ENV);
}
if (bm == null) {
if (LOG.isErrorEnabled()) {
LOG.error("[findBeanManager]: Could not find BeanManager instance for any given JNDI key, giving up");
}
}
} catch ( NamingException e ) {
if (LOG.isErrorEnabled()) {
LOG.error("[findBeanManager]: Unable to get InitialContext for BeanManager lookup", e);
}
}
return bm;
}

/**
* Lookup the given JNDI key in the given context.
*
* @param context the context to use for lookup.
* @param jndiKeyToCheck the key to lookup.
*
* @return the BeanManager, if found; <tt>null</tt> if not found or {@link javax.naming.NamingException} was thrown.
*/
protected BeanManager lookup( Context context, String jndiKeyToCheck ) {
if (LOG.isInfoEnabled()) {
LOG.info("[lookup]: Checking for BeanManager under JNDI key " + jndiKeyToCheck);
}
BeanManager result = null;
try {
result = (BeanManager) context.lookup(jndiKeyToCheck);
} catch ( NamingException e ) {
if (LOG.isDebugEnabled()) {
LOG.debug("[lookup]: BeanManager lookup failed for JNDI key " + jndiKeyToCheck, e);
}
}
return result;
}

@Override
@SuppressWarnings("unchecked")
public Object buildBean(String className, Map<String, Object> extraContext, boolean injectInternal)
throws Exception {
Expand Down

0 comments on commit 20689c0

Please sign in to comment.