package org.jboss.seam.ioc.spring;
import java.beans.FeatureDescriptor;
import java.util.Iterator;
import javax.el.CompositeELResolver;
import javax.el.ELContext;
import javax.el.ELResolver;
import javax.servlet.ServletContext;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Install;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Startup;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.ServletLifecycle;
import org.jboss.seam.el.EL;
import org.jboss.seam.log.LogProvider;
import org.jboss.seam.log.Logging;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* Resolver patterned after the Spring DelegatingVariableResolver providing el access
* to Spring beans in non Faces Requests.
* @author youngstrommj
*
*/
@Scope(ScopeType.APPLICATION)
@Name("org.jboss.seam.ioc.spring.springELResolver")
@Install(precedence = Install.FRAMEWORK, classDependencies="org.springframework.beans.factory.BeanFactory")
@Startup
@BypassInterceptors
public class SpringELResolver extends ELResolver
{
private static final LogProvider log = Logging.getLogProvider(SpringELResolver.class);
@Create
public void initialize()
{
ELResolver resolver = EL.EL_RESOLVER;
if (resolver == null || !(resolver instanceof CompositeELResolver))
{
throw new IllegalStateException("Could not add Spring ELResolver to Resolver Chain. "
+ "Seam resolver was not an instance of CompositeELResolver.");
}
((CompositeELResolver) resolver).add(this);
}
@Override
public Class<?> getCommonPropertyType(ELContext context, Object base)
{
return null;
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base)
{
return null;
}
@Override
public Class<?> getType(ELContext context, Object base, Object property)
{
return null;
}
@Override
public Object getValue(ELContext context, Object base, Object property)
{
if (base != null)
{
// We only resolve root variable.
return null;
}
ServletContext servletContext = ServletLifecycle.getServletContext();
if (servletContext == null)
{
log.debug("Could not locate seam stored servletContext. Skipping.");
return null;
}
BeanFactory bf = getBeanFactory(servletContext);
if (bf == null)
{
log.debug("No Spring BeanFactory found. Skipping.");
return null;
}
if (!(property instanceof String))
{
log.debug("Property not a string. Skipping");
return null;
}
if (bf.containsBean((String) property))
{
if (log.isDebugEnabled())
{
log.debug("Successfully resolved property '" + property
+ "' in root WebApplicationContext");
}
context.setPropertyResolved(true);
return bf.getBean((String) property);
}
if (log.isDebugEnabled())
{
log.debug("Could not resolve property of name '" + property + "'");
}
return null;
}
@Override
public boolean isReadOnly(ELContext context, Object base, Object property)
{
return true;
}
@Override
public void setValue(ELContext context, Object base, Object property, Object value)
{
}
/**
* Obtain the BeanFactory using
* WebApplicationContextxUtils.getWebApplicationContext
*/
protected BeanFactory getBeanFactory(ServletContext servletContext)
{
return WebApplicationContextUtils.getWebApplicationContext(servletContext);
}
}