package org.jboss.jsfunit.analysis.el;
import java.beans.BeanInfo;
import java.beans.FeatureDescriptor;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.Iterator;
import javax.el.ELContext;
import javax.el.ELException;
import javax.el.ELResolver;
import javax.el.PropertyNotFoundException;
/**
*
* @author Jason
* @since 1.0
*/
public class JSFUnitELResolver extends ELResolver
{
//TODO: do we need to implement the current unsupported operations?
//TODO: figure out how to work with expressions with operators (!, <, etc.)
@Override
public Class<?> getCommonPropertyType(final ELContext context, final Object base)
{
throw new UnsupportedOperationException();
}
@Override
public Iterator<FeatureDescriptor> getFeatureDescriptors(
final ELContext context, final Object base)
{
throw new UnsupportedOperationException();
}
@Override
public Class<?> getType(final ELContext context, final Object base,
final Object property)
{
throw new UnsupportedOperationException();
}
@Override
public Object getValue(final ELContext context, final Object base,
final Object property)
{
if(context == null) {
throw new NullPointerException("context is null");
}
if(base instanceof Class<?>) {
final BeanInfo beanInfo;
try {
beanInfo = Introspector.getBeanInfo((Class<?>)base);
} catch ( final IntrospectionException e ) {
throw new ELException(e);
}
for(final PropertyDescriptor pDes: beanInfo.getPropertyDescriptors()) {
if(pDes.getName().equals(property)) {
context.setPropertyResolved(true);
return pDes.getReadMethod();
}
}
for(final MethodDescriptor mDes: beanInfo.getMethodDescriptors()) {
if(mDes.getName().equals(property)) {
context.setPropertyResolved(true);
return mDes.getMethod();
}
}
throw new PropertyNotFoundException("Could not resolve property " +
property + " for base " + base);
}
else if (base instanceof Method) {
final Class<?> baseClass = ((Method)base).getReturnType();
return getValue(context, baseClass, property);
}
else {
//TODO: do we need to handle (base == null) case?
//We don't handle non-Class and non-Method bases, so according to
//my reading of the ELResolver docs, we shouldn't throw a
//PropertyNotFoundException. Instead, we just rely on the
//ELContext's propertyResolved not being set to true.
return null;
}
}
@Override
public boolean isReadOnly(final ELContext context, final Object base,
final Object property)
{
throw new UnsupportedOperationException();
}
@Override
public void setValue(final ELContext context, final Object base,
final Object property, final Object value)
{
throw new UnsupportedOperationException();
}
}