Seleccionar página

El Expression Language de JSF nos permite acceder a propiedades de los objetos siempre que estas esten 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.
Sustiye 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

Este sitio web utiliza cookies para que usted tenga la mejor experiencia de usuario. Si continúa navegando está dando su consentimiento para la aceptación de las mencionadas cookies y la aceptación de nuestra política de cookies, pinche el enlace para mayor información.plugin cookies

ACEPTAR
Aviso de cookies