package com.anem.green.web.convert; import java.util.Collection; import javax.el.ValueExpression; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; public class ValueExpressionHelper { /** * Source adapted from Seam's enumConverter. The goal is to get the type to which this component's value is bound. * First, check if the valueExpression provides the type. For dropdown-like components, this may not work, so check * for SelectItems children. * * @param context the current FacesContext * @param uiComponent * @param validTypes a list of types to look for * @return null if a valid type cannot be found */ public static Class<?> getValueType(FacesContext context, UIComponent uiComponent, Collection<Class<?>> validTypes) { Class<?> valueType = getValueType(context, uiComponent); if (valueType != null && isValid(validTypes, valueType)) { return valueType; } else { for (UIComponent child : uiComponent.getChildren()) { UIComponent c = (UIComponent) child; ValueExpression expr = c.getValueExpression("value"); Object val = expr == null ? null : expr.getValue(context.getELContext()); if (val != null) { valueType = val.getClass(); if (valueType.isArray() && isValid(validTypes, valueType.getComponentType())) { return valueType; } else if (val instanceof Collection<?>) { valueType = ((Collection<?>) val).iterator().next().getClass(); if (isValid(validTypes, valueType)) { return valueType; } } } } } return null; } /** * return the type for the "value" attribute of the given component, if it exists. Return null otherwise. * @param context * @param comp * @return */ public static Class<?> getValueType(FacesContext context, UIComponent comp) { ValueExpression expr = comp.getValueExpression("value"); Class<?> valueType = expr == null ? null : expr.getType(context.getELContext()); return valueType; } private static boolean isValid(Collection<Class<?>> validTypes, Class<?> valueType) { for (Class<?> validType : validTypes) { if (validType.isAssignableFrom(valueType)) { return true; } } return false; } }