/*
* This software is Copyright 2005,2006,2007,2008 Langdale Consultants.
* Langdale Consultants can be contacted at: http://www.langdale.com.au
*/
package au.com.langdale.ui.plumbing;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* Delegates Binding events to Binding implementations.
*
* Bindings are invoked in the reverse of the order they
* are added by the push() method.
*
*/
public class Bindings implements Binding {
public static class GuardedList {
private int guard = 0;
private ArrayList contents = new ArrayList();
public List get() {
return contents;
}
public GuardedList use() {
guard++;
return this;
}
public void release() {
guard--;
}
public GuardedList copy() {
if(guard > 0) {
GuardedList clone = new GuardedList();
clone.contents.addAll(contents);
return clone;
}
else
return this;
}
}
private GuardedList delegates = new GuardedList();
public void refresh() {
GuardedList stable = delegates.use();
try {
Iterator it = stable.get().iterator();
while(it.hasNext()) {
((Binding)it.next()).refresh();
}
}
finally {
stable.release();
}
}
public void update() {
GuardedList stable = delegates.use();
try {
Iterator it = stable.get().iterator();
while(it.hasNext()) {
((Binding)it.next()).update();
}
}
finally {
stable.release();
}
}
public String validate() {
GuardedList stable = delegates.use();
try {
Iterator it = stable.get().iterator();
while(it.hasNext()) {
String result = ((Binding)it.next()).validate();
if( result != null )
return result;
}
return null;
}
finally {
stable.release();
}
}
public void reset() {
GuardedList stable = delegates.use();
try {
Iterator it = stable.get().iterator();
while(it.hasNext()) {
((Binding)it.next()).reset();
}
}
finally {
stable.release();
}
}
/**
* Add a delegate Binding to the top of the binding stack.
* It will receive events before all previously added delegates.
*/
public void push(Binding bind) {
delegates = delegates.copy();
delegates.get().add(0, bind);
}
/**
* Add a delegate Binding at a specific position in the stack.
* It will receive events immediately after the given reference.
*/
public void push(Binding bind, Object after) {
delegates = delegates.copy();
int ix = after != null? delegates.get().indexOf(after) + 1: 0;
delegates.get().add(ix, bind);
}
/**
* Remove a delegate Binding.
*/
public void remove(Binding bind) {
delegates = delegates.copy();
delegates.get().remove(bind);
}
}