com.jsftoolkit.base.UIDataProcessor Maven / Gradle / Ivy
package com.jsftoolkit.base;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.faces.component.UIComponent;
import javax.faces.component.UIData;
import javax.faces.context.FacesContext;
/**
* Callback used in conjunction with
* {@link #iterate(FacesContext, UIData, UIDataProcessor)}.
*
* Facets will be processed (via
* {@link #processFacet(FacesContext, UIComponent, String)}) first (in no
* particular order) and then children (via
* {@link #processChild(FacesContext, UIComponent)}).
*
* @author noah
*
*/
public abstract class UIDataProcessor {
/**
* Processes the next child of the UIData component. Called for each child
* (in order), for each row.
*
* @param context
* @param child
* @throws IOException
*/
public abstract void processChild(FacesContext context, UIComponent child);
/**
* Also called for every row, although the order is unspecified. The default
* behavior is to ignore any facets.
*
* @param context
* @param facet
* @param name
*/
public void processFacet(FacesContext context, UIComponent facet,
String name) {
}
/**
* Iterates over the given UIData, letting the callback process each child
* in order.
*
*
* This code will have no side effects when it finishes, although the
* callback might.
*
* @param context
* @param data
* @param callback
* @throws IOException
*/
public static void iterate(FacesContext context, JsfIterator data,
UIDataProcessor callback) {
// save the current index
final int originalIndex = data.getRowIndex();
final int first = data.getFirst(); // first row requested
final int requested = data.getRows(); // # rows requested
// requested == 0 means render all remaining rows
try {
for (int count = 0; requested == 0 || count < requested; count++) {
// set the current row
data.setRowIndex(first + count);
if (!data.isRowAvailable()) {
break;
// no more rows. This is the only way to get out of the
// loop if requested is 0
}
// process the facets
for (Entry entry : data.getFacets()
.entrySet()) {
UIComponent facet = entry.getValue();
facet.setId(facet.getId());
String name = entry.getKey();
callback.processFacet(context, facet, name);
}
// let the children encode themselves
for (UIComponent child : data.getChildren()) {
child.setId(child.getId());
callback.processChild(context, child);
}
}
} finally {
// reset the UIData to where it was before
data.setRowIndex(originalIndex);
}
}
public static void iterate(FacesContext context, UIData data,
UIDataProcessor callback) {
iterate(context, new UIDataWrapper(data), callback);
}
public static class UIDataWrapper implements JsfIterator {
private final UIData wrapped;
public UIDataWrapper(UIData wrapped) {
super();
this.wrapped = wrapped;
}
public UIData getWrapped() {
return wrapped;
}
public Map getFacets() {
return wrapped.getFacets();
}
public List getChildren() {
return wrapped.getChildren();
}
public int getFirst() {
return wrapped.getFirst();
}
public int getRowIndex() {
return wrapped.getRowIndex();
}
public int getRows() {
return wrapped.getRows();
}
public boolean isRowAvailable() {
return wrapped.isRowAvailable();
}
public void setRowIndex(int rowIndex) {
wrapped.setRowIndex(rowIndex);
}
}
}