I think this will do unless you can think of a way to avoid having to add the
VCL tag to every component.
This is when you may consider a PhaseListener, or component binding.
You could surf the entire component tree recursively, and add your VCL
to all components implementing EditableValueHolder.
public class VCLPhaseListener implement PhaseListener {
public void afterPhase(PhaseEvent event) { }
public void beforePhase(PhaseEvent event) {
UIViewRoot viewRoot = event.getFacesContext().getViewRoot();
if (viewRoot != null) {
addVCL(viewRoot);
}
}
public PhaseId getPhaseId() {
return PhaseId.PROCESS_VALIDATIONS;
}
private void addVCL(UIComponent component) {
if (component instanceof EditableValueHolder &&
!hasVCL((EditableValueHolder)component)) {
((EditableValueHolder)component).addValueChangeListener(this);
}
for (Iterator iter = component.getFacetsAndChildren(); iter.hasNext(); ) {
addVCL(iter.next());
}
}
private boolean hasVCL(EditableValueHolder holder) {
for (ValueChangeListener listener : holder.getValueChangeListeners()) {
if (VCLPhaseListener.class.assignableFrom(listener.getClass())) {
return true;
}
}
return false;
}
... VCL Code
}