/**
* <copyright>
* </copyright>
*
* $Id$
*/
package org.jboss.tools.seam.ui.pages.editor.ecore.pages.impl;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.swt.widgets.Display;
import org.jboss.tools.common.model.XModelObject;
import org.jboss.tools.common.model.event.XModelTreeEvent;
import org.jboss.tools.common.model.event.XModelTreeListener;
import org.jboss.tools.seam.pages.xml.model.SeamPagesConstants;
import org.jboss.tools.seam.pages.xml.model.helpers.SeamPagesDiagramStructureHelper;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.Link;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.Page;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.PagesElement;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.PagesFactory;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.PagesModel;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.PagesPackage;
import org.jboss.tools.seam.ui.pages.editor.ecore.pages.PageException;
/**
* <!-- begin-user-doc -->
* An implementation of the model object '<em><b>Model</b></em>'.
* <!-- end-user-doc -->
* <p>
* </p>
*
* @generated
*/
public class PagesModelImpl extends PagesElementImpl implements PagesModel {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
SeamPagesDiagramStructureHelper h = SeamPagesDiagramStructureHelper.getInstance();
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
Map<String, PagesElement> elementsByPath = null;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
Map<String, Link> linksByPath = null;
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
XModelTreeListener modelListener = new ML();
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
protected PagesModelImpl() {
super();
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated
*/
@Override
protected EClass eStaticClass() {
return PagesPackage.Literals.PAGES_MODEL;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public PagesModel getPagesModel() {
return this;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public PagesElement findElement(Object data) {
if(data instanceof XModelObject) {
data = ((XModelObject)data).getPath();
}
if(data instanceof String) {
PagesElement result = elementsByPath.get(data);
return result;
}
return null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void bindElement(Object data, PagesElement element) {
element.setData(data);
if(data instanceof XModelObject) {
addElement((XModelObject)data, element);
} else if(data != null) {
elementsByPath.put(data.toString(), element);
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
void addElement(XModelObject data, PagesElement element) {
elementsByPath.put(data.getPath(), element);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public Link findLink(Object data) {
if(data instanceof XModelObject) {
data = ((XModelObject)data).getPath();
}
if(data instanceof String) {
Link result = linksByPath.get(data);
return result;
}
return null;
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void bindLink(Object data, Link link) {
link.setData(data);
if(data instanceof XModelObject) {
linksByPath.put(((XModelObject)data).getPath(), link);
} else if(data != null) {
linksByPath.put(data.toString(), link);
}
}
void unbind(String path) {
Iterator<String> it = elementsByPath.keySet().iterator();
while(it.hasNext()) {
String p = it.next();
if(p.equals(path) || p.startsWith(path + "/")) {
it.remove();
}
}
it = linksByPath.keySet().iterator();
while(it.hasNext()) {
String p = it.next();
if(p.equals(path) || path.startsWith(p + "/")) {
it.remove();
}
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void load() {
XModelObject diagramXML = (XModelObject)getData();
if(diagramXML == null) return;
elementsByPath = new HashMap<String, PagesElement>();
linksByPath = new HashMap<String, Link>();
addElement(diagramXML, this);
XModelObject[] is = h.getItems(diagramXML);
for (int i = 0; i < is.length; i++) {
addItem(is[i]);
}
for (int i = 0; i < is.length; i++) {
addItemLinks(is[i]);
}
diagramXML.getModel().removeModelTreeListener(modelListener);
diagramXML.getModel().addModelTreeListener(modelListener);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void childAdded(Object childData) {
if(childData instanceof XModelObject) {
XModelObject added = (XModelObject)childData;
addItem(added);
addItemLinks(added);
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
private void addItem(XModelObject item) {
String type = item.getAttributeValue(SeamPagesConstants.ATTR_TYPE);
if(SeamPagesConstants.TYPE_PAGE.equals(type)) {
Page page = PagesFactory.eINSTANCE.createPage();
bindElement(item, page);
page.dataChanged();
getChildren().add(page);
} else if(SeamPagesConstants.TYPE_EXCEPTION.equals(type)) {
PageException exc = PagesFactory.eINSTANCE.createPageException();
bindElement(item, exc);
exc.dataChanged();
getChildren().add(exc);
} else {
//TODO
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
private void addItemLinks(XModelObject item) {
String type = item.getAttributeValue(SeamPagesConstants.ATTR_TYPE);
if(SeamPagesConstants.TYPE_PAGE.equals(type)
|| SeamPagesConstants.TYPE_EXCEPTION.equals(type)) {
PagesElement from = findElement(item);
if(from == null) {
//TODO report failure
return;
}
XModelObject[] os = h.getOutputs(item);
for (int j = 0; j < os.length; j++) {
from.childAdded(os[j]);
}
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void dispose() {
XModelObject diagramXML = (XModelObject)getData();
if(diagramXML == null) return;
diagramXML.getModel().removeModelTreeListener(modelListener);
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
class ML implements XModelTreeListener {
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void nodeChanged(final XModelTreeEvent event) {
if(Display.getCurrent() != null){
nodeChangedInternal(event);
}else{
Display.getDefault().asyncExec(new Runnable(){
public void run(){
nodeChangedInternal(event);
}
});
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
private void nodeChangedInternal(XModelTreeEvent event) {
if(getData() == null) return;
XModelObject diagramXML = (XModelObject)getData();
String newPath = event.getModelObject().getPath();
if(diagramXML.getPath() == null) {
//FIXME Should not be, this a problem. Listener should be removed earlier
//diagramXML.getModel().removeModelTreeListener(this);
return;
}
if(!newPath.startsWith(diagramXML.getPath())) {
return;
}
String oldPath = event.getInfo().toString();
PagesElement item = findElement(oldPath);
if(item != null) {
if(!oldPath.equals(newPath)){
elementsByPath.remove(oldPath);
elementsByPath.put(newPath, item);
String[] keys = (String[])linksByPath.keySet().toArray(new String[0]);
for (int i = 0; i < keys.length; i++) {
if(keys[i].startsWith(oldPath + "/")) {
Link o = linksByPath.get(keys[i]);
if(o == null) continue;
String key = newPath + keys[i].substring(oldPath.length());
linksByPath.put(key, o);
}
}
}
item.dataChanged();
}
Link link = findLink(event.getInfo().toString());
if(link != null) {
link.dataChanged();
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void structureChanged(final XModelTreeEvent event) {
if(Display.getCurrent() != null){
structureChangedInternal(event);
}else{
Display.getDefault().asyncExec(new Runnable(){
public void run(){
structureChangedInternal(event);
}
});
}
}
/**
* <!-- begin-user-doc -->
* <!-- end-user-doc -->
* @generated NOT
*/
public void structureChangedInternal(XModelTreeEvent event) {
if(getData() == null) return;
XModelObject diagramXML = (XModelObject)getData();
XModelObject target = event.getModelObject();
if(diagramXML.getPath() == null) {
//FIXME Should not be, this a problem. Listener should be removed earlier
//diagramXML.getModel().removeModelTreeListener(this);
return;
}
if(!target.getPath().startsWith(diagramXML.getPath())) {
//FIXME Should not be, this a problem. Listener should be removed earlier
//diagramXML.getModel().removeModelTreeListener(this);
return;
}
if(event.kind() == XModelTreeEvent.CHILD_ADDED) {
XModelObject added = (XModelObject)event.getInfo();
if(target == diagramXML) {
childAdded(added);
} else {
PagesElement item = findElement(target);
item.childAdded(added);
}
} else if(event.kind() == XModelTreeEvent.CHILD_REMOVED) {
if(target == diagramXML) {
PagesElement removed = findElement(event.getInfo());
if(removed != null) {
Link[] ls = removed.getOutputLinks().toArray(new Link[0]);
Set<Link> r = new HashSet<Link>();
for (int i = 0; i < ls.length; i++) {
ls[i].setFromElement(null);
ls[i].setToElement(null);
r.add(ls[i]);
}
ls = removed.getInputLinks().toArray(new Link[0]);
for (int i = 0; i < ls.length; i++) {
// ls[i].setFromElement(null);
ls[i].setToElement(null);
// r.add(ls[i]);
}
if(!r.isEmpty()) {
Iterator<Link> it = linksByPath.values().iterator();
while(it.hasNext()) {
Link l = it.next();
if(r.contains(l)) {
it.remove();
}
}
}
getChildren().remove(removed);
}
} else if(findElement(target) != null) {
Link removed = findLink(event.getInfo());
if(removed != null) {
removed.setToElement(null);
removed.setFromElement(null);
linksByPath.remove(event.getInfo());
}
}
unbind(event.getInfo().toString());
}
}
}
} //PagesModelImpl