How does EL empty operator work in JSF?
Asked Answered
C

2

93

In JSF an component can be rendered or not using the EL empty operator

rendered="#{not empty myBean.myList}"

As I've understood the operator works both as null-check, but also check checks if the list is empty.

I want to do empty checks on some objects of my own custom class, which interface(s) or parts of interfaces do I need to implement? Which interface is the empty operator compatible with?

Chalkboard answered 6/1, 2013 at 18:0 Comment(0)
S
161

From EL 5.0 specification:

1.11 Empty Operator - empty A

The empty operator is a prefix operator that can be used to determine if a value is null or empty.

To evaluate empty A

  • If A is null, return true
  • Otherwise, if A is the empty string, then return true
  • Otherwise, if A is an empty array, then return true
  • Otherwise, if A is an empty Map, return true
  • Otherwise, if A is an empty Collection, return true
  • Otherwise return false

So, considering the interfaces, it works on Collection and Map only. In your case, I think Collection is the best option. Or, if it's a Javabean-like object, then Map. Either way, under the covers, the isEmpty() method is used for the actual check. On interface methods which you can't or don't want to implement, you could throw UnsupportedOperationException.

Sober answered 6/1, 2013 at 18:4 Comment(3)
Weird, I try to use this on a Long and eclipse (4.4.0) hints that "This empty expression always evaluates to false. Only string, maps, arrays and collection have meaningful values for the empty operator"Gravimetric
Even more weird, it always evaluates to true in my case.Gravimetric
What about if myBean is null? Will true/false still be returned or can it throw an exception?Hunker
C
9

Using BalusC's suggestion of implementing Collection i can now hide my primefaces p:dataTable using not empty operator on my dataModel that extends javax.faces.model.ListDataModel

Code sample:

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import javax.faces.model.ListDataModel;
import org.primefaces.model.SelectableDataModel;

public class EntityDataModel extends ListDataModel<Entity> implements
        Collection<Entity>, SelectableDataModel<Entity>, Serializable {

    public EntityDataModel(List<Entity> data) { super(data); }

    @Override
    public Entity getRowData(String rowKey) {
        // In a real app, a more efficient way like a query by rowKey should be
        // implemented to deal with huge data
        List<Entity> entitys = (List<Entity>) getWrappedData();
        for (Entity entity : entitys) {
            if (Integer.toString(entity.getId()).equals(rowKey)) return entity;
        }
        return null;
    }

    @Override
    public Object getRowKey(Entity entity) {
        return entity.getId();
    }

    @Override
    public boolean isEmpty() {
        List<Entity> entity = (List<Entity>) getWrappedData();
        return (entity == null) || entity.isEmpty();
    }
    // ... other not implemented methods of Collection...
}
Chalkboard answered 7/1, 2013 at 18:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.