Seleccionar página

Cómo implementar un ELResolver personalizado

por | Feb 1, 2008 | General

El Expression Language de JSF nos permite acceder a propiedades de los objetos siempre que estas estén disponibles mediante getters.

Esto está muy bien, pero en ocasiones lo que queremos obtener es un objeto que solo está accesible a través de un método que no es un getter, como por ejemplo el tamaño de una java.util.Collection disponible a través de su método collection.size(), o los valores de un java.util.Map disponibles a través del método values().

Para ello podemos realizar nuestra propia implementación de la clase javax.el.ELResolver.
Esta clase es la encargada de evaluar las ELs (las expresiones que van entre #{}) y realizar las acciones correspondientes.
Sustituye a los antiguos PropertyResolver y VariableResolver, que están marcados como obsoletos (deprecated) en la especificación 1.2 de JSF (que es la usada en la versión 5 de Java EE).

Para usar nuestro propio ELResolver solo deboemos seguir tres sencillos pasos:

    • 1) Implementar nuestra clase que extienda de javax.el.ELResolver
      Puedes descargarla aquí: MyELResolver
      Necesitarás añadir al classpath de compilación el archivo el-api.jar

package tes.jsf;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.el.ELContext;

public class MyELResolver extends javax.el.ELResolver {

@Override
public Class getCommonPropertyType(ELContext context, Object base) {
return null;
}

@Override
public Iterator 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 instanceof Collection) {
return resolveInCollection(context, (Collection)base, property);
} else if (base instanceof Map) {
return resolveInMap(context, (Map)base, property);
} else {
return null;
}
}

@Override
public boolean isReadOnly(ELContext arg0, Object arg1, Object arg2) {
return true;
}

@Override
public void setValue(ELContext arg0, Object arg1, Object arg2, Object arg3) {
}

private Object resolveInCollection(ELContext context, Collection base, Object property) {
if (property.equals(«size»)) {
context.setPropertyResolved(true);
return base.size();
} else if (property.equals(«toMap»)) {
context.setPropertyResolved(true);
return collectionToMap(base);
} else if (property.equals(«toList»)) {
context.setPropertyResolved(true);
return new ArrayList(base);
}else {
return null;
}
}

private Object resolveInMap(ELContext context, Map base, Object property) {
if (property.equals(«size»)) {
context.setPropertyResolved(true);
return base.size();
} else if (property.equals(«values»)) {
context.setPropertyResolved(true);
return base.values();
} else if (property.equals(«keySet»)) {
context.setPropertyResolved(true);
return base.keySet();
} else if (property.equals(«entrySet»)) {
context.setPropertyResolved(true);
return base.entrySet();
} else {
return null;
}
}

private Map collectionToMap(Collection col) {
Map map = new HashMap();
for (Object obj : col) {
map.put(obj, obj);
}
return map;
}
}

  • 2) Declarar el ELResolver en el archivo faces-config.xml
    La declaración debe hacerse dentro de la seccion <application>.
    <el-resolver>tes.jsf.MyELResolver</el-resolver>
  • 3) Usar las nuevas posibilidades del Language Expression
      • El tamaño de mi Collection es: #{myCollection.size}
      • Puedes usarlo para rellenar tus combos:
         <h:selectOneMenu>
              <f:selectItems value="#{myCollection.toMap}" />
         <h:selectOneMenu>
      • Para asociar tu java.util.Set con un dataTable
             <h:dataTable value="#{mySet.toList}" var="entry">
                  ...
             </h:dataTable>
      • Para iterar sobre las entradas de un Map
         <ui:repeat value="#{myMap.entrySet.toList}" var="entry">
              #{entry.key} : #{entry.value} <br />
         </ui:repeat>
    • Y para todo lo que se te ocurra añadir

0 comentarios

Enviar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Blog de Neodoo Microsystems
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles. Puedes encontrar más información en nuestra Política de privacidad y Política de cookies.