Sé que esta pregunta es un poco más viejo ahora, pero que tenía el mismo problema y ha encontrado otra solución, que quiero compartir:
Crea una alfombrilla de EL-Resolver y enumeraciones de uso y Java constantes como objetos en el JSF:
<h:graphicImage name="error.png" library="images"
rendered="#{viewController.current.status == Status.ERROR}" />
Pero antes de poder utilizar las enumeraciones de esta manera usted tiene que hacer 3 pasos.
1. paso - Copia esta clase y reemplazar "MY_ENUM" a través de su enumClass (en el ejemplo anterior sería "Estado")
public class EnumCache {
private Map<String, Object> propertCache = new HashMap<String, Object>();
private Map<String, Class> baseCache = new HashMap<String, Class>();
private static EnumCache staticEnumCache = null;
public static EnumCache instance() {
if (staticEnumCache == null) { staticEnumCache = new EnumCache(); }
return staticEnumCache;
}
private EnumCache() {
List<Class<?>> classes = new ArrayList<Class<?>>();
classes.add(MY_ENUM.class);
for(Class clazz : classes) {
try {
baseCache.put(clazz.getSimpleName(), clazz);
Method m = clazz.getMethod("values", (Class[]) null);
Enum<?>[] valueList = (Enum[]) m.invoke(null, (Object[]) null);
for (Enum<?> en : valueList) {
propertCache.put(clazz.getSimpleName() + "." + en.name(), en);
}
} catch (Exception e) {
System.err.println(clazz.getSimpleName(), e);
}
}
}
public Object getValueForKey(String key) {
return propertCache.get(key);
}
public Class getClassForKey(String key) {
return baseCache.get(key);
}
}
2. paso - añadir este EnumResolver - Este clase será el mapa de su expresión JSF para la enumeración en la memoria caché (paso 1)
public class MyEnumResolver extends ELResolver {
public Object getValue(ELContext context, Object base, Object property) {
Object result = null;
if (base == null) {
result = EnumCache.instance().getClassForKey(property + "");
} else if (base instanceof Class) {
result = EnumCache.instance().getValueForKey(((Class) base).getSimpleName() + "." + property);
}
if (result != null) {
context.setPropertyResolved(true);
}
return result;
}
public Class<?> getCommonPropertyType(ELContext context, Object base) {
return null;
}
public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base) {
return null;
}
public Class<?> getType(ELContext context, Object base, Object property) {
return null;
}
public boolean isReadOnly(ELContext context, Object base, Object property) {
return false;
}
public void setValue(ELContext context, Object base, Object property, Object arg3) {
}
}
3. paso - registrar el EnumResolver en faces-config.xml
<faces-config>
<application>
<el-resolver>com.asd.MyEnumResolver</el-resolver>
</application>
</faces-config>
NOTA: Si desea acceder a sus constantes java esta manera, sólo hay que extender el constructor de la clase enumCache. Este (untestet) ejemplo debería funcionar:
baseCache.put(CLASS_WITH_CONSTANTS.getSimpleName(), clazz);
for (Field field : CLASS_WITH_CONSTANTS.getDeclaredFields()) {
try {
propertCache.put(CLASS_WITH_CONSTANTS.getSimpleName() + "."
+ field.getName(), field.get(null));
} catch (Exception e) { }
}
Esperanza este código reducido, pero de trabajo puede ayudar a nadie.
actualización
veo estos beneficios:
Si utiliza cadenas en JSF (viewController.current.status == 'ERROR_abcdefg'), se puede escribir mal el valor y no lo reconocerá tan rápido. Con mi solución, se obtendría un error al cargar el archivo jsf, porque la enumeración no se pudo resolver.
Puede ver en el código fuente que "ERROR" es el valor de la enumeración "ESTADO".
Al comparar dos valores en el, se comparará también la clase de las enumeraciones. Entonces, por ejemplo, PersonState.ACTIV no es lo mismo que AccounState.ACTIV.
Cuando tengo que cambiar mi valor enum de PersonState.ACTIV a PersonState.ACTIVATED puedo buscar el String "PersonState.ACTIV" en mi código fuente. buscar "ACTIV" tendría muchas más coincidencias.
cadena es evaluada como llamar método equals() o como la comparación por referencia? – user3663882