package com.tibco.as.spacebar.ui.model; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.eclipse.core.databinding.beans.BeanProperties; import org.eclipse.core.databinding.observable.list.IListChangeListener; import org.eclipse.core.databinding.observable.list.ListChangeEvent; import org.eclipse.core.databinding.observable.list.ListDiffEntry; import org.eclipse.core.runtime.PlatformObject; public abstract class AbstractElement extends PlatformObject implements IElement { private PropertyChangeSupport changeSupport = new PropertyChangeSupport( this); protected void fireNameChange(String oldName, String newName) { firePropertyChange("name", oldName, newName); } protected void fireChildrenChange(List<?> oldList, List<?> newList) { firePropertyChange("children", oldList, newList); } public void addPropertyChangeListener(PropertyChangeListener listener) { changeSupport.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { changeSupport.removePropertyChangeListener(listener); } @Override public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { changeSupport.addPropertyChangeListener(propertyName, listener); } public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { changeSupport.removePropertyChangeListener(propertyName, listener); } protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { changeSupport.firePropertyChange(propertyName, oldValue, newValue); } public List<? extends IElement> getChildren() { return Collections.emptyList(); } @Override public boolean addChild(IElement child) { IElement existing = getChild(child); if (existing == null) { List<IElement> oldValue = new ArrayList<IElement>(getChildren()); if (add(child)) { fireChildrenChange(oldValue, getChildren()); return true; } return false; } copyChild(existing, child); return true; } protected boolean add(IElement child) { return false; } protected boolean remove(IElement child) { return false; } protected void copyChild(IElement source, IElement target) { } @Override public boolean removeChild(String name) { IElement existing = getChild(name); if (existing == null) { return false; } List<IElement> oldValue = new ArrayList<IElement>(getChildren()); if (remove(existing)) { fireChildrenChange(oldValue, getChildren()); return true; } return false; } @Override public boolean removeChild(IElement element) { return removeChild(element.getName()); } @Override public IElement getChild(String name) { for (IElement child : getChildren()) { if (child.getName().equals(name)) { return child; } } return null; } @Override public IElement getChild(IElement child) { return getChild(child.getName()); } @Override public String toString() { return getName(); } @Override public void addListener(final IModelListener listener) { BeanProperties.list("children").observe(this) .addListChangeListener(new IListChangeListener() { @Override public void handleListChange(ListChangeEvent event) { for (ListDiffEntry entry : event.diff.getDifferences()) { IElement element = (IElement) entry.getElement(); if (entry.isAddition()) { element.addListener(listener); listener.added(element); } else { listener.removed(element); } } } }); changeSupport.addPropertyChangeListener(new PropertyChangeListener() { @Override public void propertyChange(PropertyChangeEvent evt) { listener.changed(AbstractElement.this, evt.getPropertyName(), evt.getOldValue(), evt.getNewValue()); } }); for (IElement element : getChildren()) { element.addListener(listener); } } public abstract AbstractElement clone(); }