package org.vaadin.smartgwt.client.core;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
import com.vaadin.terminal.gwt.client.UIDL;
/**
* Manages client side paintable references that were registered on the server with ComponentPropertyPainter. By default, paintables will be created when
* updating from UIDL. Further behavior can be defined through listener registration, like adding or removing paintables from their respective parent.
*/
public class PaintablePropertyUpdater {
private final List<PaintableProperty> properties = new ArrayList<PaintableProperty>();
/**
* Registers a listener to be notified when the specified property reference is modified.
*
* @param propertyName the name of the property to watch. it must match with the server-side property registration.
* @param listener the listener to notify.
*/
public void addPaintableReferenceListener(String propertyName, PaintableReferenceListener listener) {
((PaintableReference) getOrCreateProperty(propertyName, "Reference")).addPaintableReferenceListener(listener);
}
public void addPaintableArrayListener(String propertyName, PaintableArrayListener listener) {
((PaintableArray) getOrCreateProperty(propertyName, "Array")).addPaintableArrayListener(listener);
}
/**
* Registers a listener to be notified when the specified list property elements are modified.
*
* @param propertyName the name of the property to watch. it must match with the server-side property registration.
* @param listener the listener to be notified.
*/
public void addPaintableListListener(String propertyName, PaintableListListener listener) {
((PaintableList) getOrCreateProperty(propertyName, "List")).addPaintableListListener(listener);
}
/**
* Equivalent of Paintable.updateFromUIDL. It must be called when updating the client-side component that uses this instance.
*
* @param uidl the client-side component uidl
* @param client the application connection
*/
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
for (UIDL propertyUIDL : filterUIDLPropertyChildren(uidl.getChildIterator())) {
final String name = propertyUIDL.getTag().substring(1);
final String type = propertyUIDL.hasAttribute("type") ? propertyUIDL.getStringAttribute("type") : null;
getOrCreateProperty(name, type).updateFromUIDL(propertyUIDL, client);
}
}
private PaintableProperty getOrCreateProperty(String name, String type) {
for (PaintableProperty property : properties) {
if (name.equals(property.getName())) {
return property;
}
}
final PaintableProperty property = newPaintableProperty(name, type);
properties.add(property);
return property;
}
private static List<UIDL> filterUIDLPropertyChildren(Iterator<Object> childrenIterator) {
final List<UIDL> children = new ArrayList<UIDL>();
while (childrenIterator.hasNext()) {
final Object next = childrenIterator.next();
if (next instanceof UIDL && ((UIDL) next).getTag().startsWith("$")) {
children.add((UIDL) next);
}
}
return children;
}
private static PaintableProperty newPaintableProperty(final String name, final String type) {
if ("List".equals(type)) {
return new PaintableList(name);
} else if ("Reference".equals(type)) {
return new PaintableReference(name);
} else if ("Array".equals(type)) {
return new PaintableArray(name);
} else {
throw new UnsupportedOperationException("unknow paintable property type.");
}
}
}