My JSF Books/Videos My JSF Tutorials OmniFaces/JSF PPTs
JSF 2.3 Tutorial
JSF Caching Tutorial
JSF Navigation Tutorial
JSF Scopes Tutorial
JSF Page Author Beginner's Guide
OmniFaces 2.3 Tutorial Examples
OmniFaces 2.2 Tutorial Examples
JSF Events Tutorial
OmniFaces Callbacks Usages
JSF State Tutorial
JSF and Design Patterns
JSF 2.3 New Features (2.3-m04)
Introduction to OmniFaces
25+ Reasons to use OmniFaces in JSF
OmniFaces Validators
OmniFaces Converters
JSF Design Patterns
Mastering OmniFaces
Reusable and less-verbose JSF code

My JSF Resources ...

Java EE Guardian
Member of JCG Program
Member MVB DZone
Blog curated on ZEEF
OmniFaces is an utility library for JSF, including PrimeFaces, RichFaces, ICEfaces ...

[OmniFaces Utilities] - Find the right JSF OmniFaces 2 utilities methods/functions

Search on blog

Petition by Java EE Guardians

Twitter

sâmbătă, 18 iulie 2015

JSF 2.3 new feature: registrable DataModels

Before reading this article I strongly recommend you to read the below two articles of Arjan Tijms:

JSF 2.3 new feature: registrable DataModels



With @FacesDataModel custom DataModel wrappers can be registered, but those wrappers can not (yet) override any of the build-in types.

Usage involve two steps:
 - register your wrapper by annotating it with @FacesDataModel
 - designates the type this wrapper is able to handle via forClass attribute

WRAPPER MODEL

@FacesDataModel(forClass = fooCollection.class)
public class FooCollectionModel<E> extends DataModel<E> {
    
 @Override
 public E getRowData() {
  // access FooCollection here
 }

 @Override
 public void setWrappedData(Object fooCollection) {
  // likely just store fooCollection
 }

 // Other methods omitted for brevity
}

USE COLLECTION IN YOUR BEANS

@Named
public class FooBean {
 public FooCollection<Foo> getFoo() {
  // return fooCollection
 }
}

IN DATA TABLE IT WORKS OUT OF THE BOX

<h:dataTable value="#{fooBean.foo}" var="t">
 <h:column>
  #{t} | #{t.property}
 </h:column>
</h:dataTable>

For example, let's define an ArraySet as below:

public class ArraySet<T> implements Cloneable, Serializable {

 private ArrayList list;

 public ArraySet() {
  list = new ArrayList();
 }

 public ArraySet(Collection collection) {
  list = new ArrayList();

  Iterator iterator = collection.iterator();
  if (collection instanceof Set) {
      while (iterator.hasNext()) {
             list.add(iterator.next());
      }
  } else {
      while (iterator.hasNext()) {
             add(iterator.next());
      }
  }
 }

 public Iterator iterator() {
  return list.iterator();
 }

 public int size() {
  return list.size();
 }

 public final boolean add(Object element) {
  boolean modified;
  if (modified = !list.contains(element)) {
      list.add(element);
  }
  return modified;
 }

 public boolean remove(Object element) {
  return list.remove(element);
 }

 public boolean isEmpty() {
  return list.isEmpty();
 }

 public boolean contains(Object element) {
  return list.contains(element);
 }

 public void clear() {
  list.clear();
 }

 public Object get(int index) {
  return list.get(index);
 }

 @Override
 public Object clone() throws CloneNotSupportedException {
  try {
      ArraySet newSet = (ArraySet) super.clone();
      newSet.list = (ArrayList) list.clone();
      return newSet;
  } catch (CloneNotSupportedException e) {
      throw new InternalError();
  }
 }
}

For this collection we can write a sortable model, as below:

@FacesDataModel(forClass = ArraySet.class)
public final class SortDataModel<T> extends DataModel<T> {

 private static final Logger LOG = Logger.getLogger(SortDataModel.class.getName());

 private int index = -1;
 private ArraySet list;
 private Integer[] rows;

 public SortDataModel() {
  LOG.info("Using the SortDataModel !");
 }

 public SortDataModel(List<T> list) {
  super();
  LOG.info("Using the SortDataModel !");
  setWrappedData(list);
 }

 @Override
 public boolean isRowAvailable() {
  if (list == null) {
      return (false);
  } else if ((index >= 0) && (index < list.size())) {
      return (true);
  } else {
      return (false);
  }
 }

 @Override
 public int getRowCount() {
  if (list == null) {
      return (-1);
  }
  return (list.size());
 }

 @Override
 public T getRowData() {

  if (list == null) {
      return (null);
  } else if (!isRowAvailable()) {
      try {
          throw new Exception();
      } catch (Exception ex) {
          Logger.getLogger(SortDataModel.class.getName()).log(Level.SEVERE, null, ex);
      }
  } else {
      return ((T) list.get(index));
  }
  return (null);
 }

 @Override
 public int getRowIndex() {
  return (index);
 }

 @Override
 public void setRowIndex(int rowIndex) {

  if (rowIndex < -1) {
      throw new IllegalArgumentException();
  }
  int old = index;

  if ((0 <= rowIndex) && (rowIndex < rows.length)) {
       index = rows[rowIndex];
  } else {
       index = rowIndex;
  }

  if (list == null) {
      return;
  }

  DataModelListener[] listeners = getDataModelListeners();
  if ((old != index) && (listeners != null)) {
       Object rowData = null;
       if (isRowAvailable()) {
           rowData = getRowData();
       }
       DataModelEvent event = new DataModelEvent(this, index, rowData);
       int n = listeners.length;
       for (int i = 0; i < n; i++) {
            if (null != listeners[i]) {
                listeners[i].rowSelected(event);
            }
       }
  }
 }

 @Override
 public Object getWrappedData() {
  return (this.list);
 }

 @Override
 public void setWrappedData(Object data) {

  if (data == null) {
      list = null;
      setRowIndex(-1);
  } else {
      list = (ArraySet) data;

      initRows();

      index = -1;
      setRowIndex(0);
      sortThis((T key_1, T key_2) -> {
       if (key_1 == null ? key_2 == null : key_1.equals(key_2)) {
           return 1;
       }
       if (key_1 == null) {
           return -1;
       }
       if (key_2 == null) {
           return 1;
       }
       return String.valueOf(key_1).compareTo(String.valueOf(key_2));
      });
  }
 }

 public void sortThis(final Comparator<T> comparator) {
  Comparator<Integer> rowc = (Integer key_1, Integer key_2) -> {
   T key_1_data = getData(key_1);
   T key_2_data = getData(key_2);
   return comparator.compare(key_1_data, key_2_data);
  };
  Arrays.sort(rows, rowc);
 }

 private T getData(int row) {
  int baseRowIndex = getRowIndex();
  setRowIndex(row);
  T newRowData = getRowData();
  setRowIndex(baseRowIndex);

  return newRowData;
 }

 private void initRows() {
  int rowCount = getRowCount();
  if (rowCount != -1) {
      this.rows = new Integer[rowCount];
      for (int i = 0; i < rowCount; ++i) {
           rows[i] = i;
      }
  }
 }
}

Now, let's fill up an ArraySet:

String players[] = {"Rafa", "Federer", "Tonga", "Novak", "Murray"};
ArraySet arraySet = new ArraySet(Arrays.asList(players));

And, in the JSF page we can used it like below:

<h:dataTable value="#{playerBean.arraySet}" var="t" border="1">               
 <h:column>
  <f:facet name="header">Player:</f:facet>
  #{t}
 </h:column>
</h:dataTable>

And, the output will be:

The complete application is available here (I've tested with Mojarra 2.3.0-m04 under Payara 4).

Niciun comentariu :

Trimiteți un comentariu

JSF BOOKS COLLECTION

Postări populare

OmniFaces/JSF Fans

Follow by Email

Visitors Starting 4 September 2015

Locations of Site Visitors