Last active
August 29, 2015 14:10
-
-
Save wakim/e118e515fccbc787b73b to your computer and use it in GitHub Desktop.
Implementação do VisitCallback que notifica com todos os componentes de uma determinada linha de um UIData
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package br.com.wakim.teste_jsf.util; | |
import java.util.ArrayList; | |
import java.util.Collection; | |
import java.util.HashMap; | |
import javax.faces.component.UIColumn; | |
import javax.faces.component.UIComponent; | |
import javax.faces.component.UIData; | |
import javax.faces.component.visit.VisitCallback; | |
import javax.faces.component.visit.VisitContext; | |
import javax.faces.component.visit.VisitResult; | |
import javax.faces.context.FacesContext; | |
/*** | |
* Classe que implementa o comportamento de visitar um UIData | |
* e notificar apenas ao termino de visitacao de uma linha | |
* @author wakim | |
*/ | |
public class LineVisitor implements VisitCallback { | |
int lastRowIndex = -1; | |
LineVisitorCallback lineVisitor; | |
UIDataLine line = new UIDataLine(); | |
UIData ancestor; | |
private LineVisitor(LineVisitorCallback lineVisitor){ | |
this.lineVisitor = lineVisitor; | |
} | |
public static void visit(FacesContext context, UIData data, LineVisitorCallback callback) { | |
VisitContext vc = VisitContext.createVisitContext(context); | |
LineVisitor lv = new LineVisitor(callback); | |
lv.ancestor = data; | |
data.visitTree(vc, lv); | |
lv.doLastVisitIfNeeded(); | |
} | |
@Override | |
public VisitResult visit(VisitContext context, UIComponent target) { | |
if(target == ancestor) { | |
return VisitResult.ACCEPT; | |
} | |
int rowIndex = ancestor.getRowIndex(); | |
// Adiciono os componentes da linha na lista | |
line.add(target); | |
// Se houve mudanca na linha atual | |
// Entao podemos notificar o callback | |
// com todos os componentes da linha | |
if(lastRowIndex != rowIndex) { | |
// Caso especial onde a primeira linha vem com os UIColumn's e as Facets. | |
// Precisamos recuperar todos os filhos dos UIColumns e notificar o callback | |
if(lastRowIndex == -1) { | |
line = transferColumnsViews(line, new UIDataLine()); | |
} | |
// Notifico, se ele retornar false | |
// Pode parar o Visitor | |
if(! lineVisitor.visit(ancestor, line, lastRowIndex)) { | |
return VisitResult.COMPLETE; | |
} | |
// O callback foi notificado, entao podemos | |
// limpar a lista para a proxima linha | |
line.clear(); | |
} | |
// Atualizo a ultima linha visitada | |
lastRowIndex = rowIndex; | |
return VisitResult.ACCEPT; | |
} | |
/*** | |
* Transfere todos componentes de todas as UIColumn's | |
* da lista source para a lista target | |
* @param source | |
* @param target | |
*/ | |
UIDataLine transferColumnsViews(UIDataLine source, UIDataLine target) { | |
for(UIComponent component : source) { | |
if(component instanceof UIColumn) { | |
target.addAll(((UIColumn) component).getChildren()); | |
} | |
} | |
return target; | |
} | |
/*** | |
* Faz uma visita apos ter terminado o visit, para notificar sobre a ultima linha | |
*/ | |
public void doLastVisitIfNeeded() { | |
if(lastRowIndex != -1) { | |
lineVisitor.visit(ancestor, line, lastRowIndex); | |
} | |
} | |
public static interface LineVisitorCallback { | |
public boolean visit(UIData ancestor, UIDataLine line, int row); | |
} | |
/*** | |
* Implementacao de lista que guarda uma estrutura de indice | |
* A chave do indice e o ID do componente | |
* @author wakim | |
* | |
*/ | |
public static class UIDataLine extends ArrayList<UIComponent> { | |
private static final long serialVersionUID = -3522555822357988347L; | |
private HashMap<String, UIComponent> index = new HashMap<String, UIComponent>(); | |
public UIComponent findComponentById(String id) { | |
return index.get(id); | |
} | |
@Override | |
public void add(int index, UIComponent element) { | |
super.add(index, element); | |
this.index.put(element.getId(), element); | |
} | |
@Override | |
public boolean add(UIComponent element) { | |
this.index.put(element.getId(), element); | |
return super.add(element); | |
} | |
@Override | |
public boolean addAll(Collection<? extends UIComponent> collection) { | |
for(UIComponent element : collection) { | |
this.index.put(element.getId(), element); | |
} | |
return super.addAll(collection); | |
} | |
@Override | |
public boolean addAll(int index, Collection<? extends UIComponent> collection) { | |
for(UIComponent element : collection) { | |
this.index.put(element.getId(), element); | |
} | |
return super.addAll(index, collection); | |
} | |
@Override | |
public UIComponent remove(int index) { | |
this.index.remove(get(index).getId()); | |
return super.remove(index); | |
} | |
@Override | |
public boolean remove(Object element) { | |
this.index.remove(((UIComponent) element).getId()); | |
return super.remove(element); | |
} | |
@Override | |
public boolean removeAll(Collection<?> collection) { | |
for(Object element : collection) { | |
this.index.remove(((UIComponent) element).getId()); | |
} | |
return super.removeAll(collection); | |
} | |
@Override | |
protected void removeRange(int arg0, int arg1) { | |
for(int i = arg0; i < arg1; ++i) { | |
this.index.remove(get(i).getId()); | |
} | |
super.removeRange(arg0, arg1); | |
} | |
@Override | |
public void clear() { | |
this.index.clear(); | |
super.clear(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment