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?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74

2 Answers2

160

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 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" – Pieter De Bie Jul 24 '15 at 09:14
  • Even more weird, it always evaluates to true in my case. – Pieter De Bie Jul 24 '15 at 09:26
  • What about if `myBean` is `null`? Will `true`/`false` still be returned or can it throw an exception? – theyuv Oct 24 '18 at 12:06
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...
}
Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228
Aksel Willgert
  • 11,367
  • 5
  • 53
  • 74