So che questa domanda è un po 'più vecchio, ma ho avuto lo stesso problema e ha trovato un'altra soluzione, che voglio condividere:
Creare una personalizzata EL-Resolver e uso enumerazioni e Java costanti come oggetti in JSF el:
<h:graphicImage name="error.png" library="images"
rendered="#{viewController.current.status == Status.ERROR}" />
Ma prima di poter utilizzare enumerazioni questo modo si ha a che fare 3 passi.
1. passo - Copia questa classe e sostituire "MY_ENUM" attraverso il vostro enumClass (nell'esempio di cui sopra sarebbe "Stato")
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. passo - aggiungere questo ENUMresolver - Questo classe sarà mappare la tua espressione JSF alla enum nella cache (fase 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. passo - registrare l'ENUMresolver in faces-config.xml
<faces-config>
<application>
<el-resolver>com.asd.MyEnumResolver</el-resolver>
</application>
</faces-config>
NOTA: Se si vuole accedere ai costanti Java in questo modo, devi solo di estendere il costruttore della classe enumCache. Questo (untestet) esempio dovrebbe funzionare:
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) { }
}
Spero che questo codice ridotto, ma di lavoro può aiutare qualcuno.
Aggiornamento
vedo questo vantaggi:
Se si utilizza stringhe in JSF (viewController.current.status == 'ERROR_abcdefg'), è possibile misspell il valore e non lo riconoscerò così in fretta. Con la mia soluzione si otterrebbe un errore durante il caricamento del file jsf, perché l'enum non può essere risolto.
È possibile visualizzare nel codice sorgente che "ERRORE" è il valore dell'enum "STATO".
Quando si confrontano due valori in el, verrà confrontata anche la classe dell'enumerazione. Quindi, ad esempio, PersonState.ACTIV non è lo stesso di AccounState.ACTIV.
Quando devo modificare il mio valore enum da PersonState.ACTIV a PersonState.ACTIVATED posso cercare la stringa "PersonState.ACTIV" nel mio codice sorgente. cercare "ACTIV" avrebbe molte più corrispondenze.
stringa viene valutata come chiamare metodo Equals() o un confronto omogeneo con riferimento? – user3663882