/** * */ package org.jboss.tools.smooks.gef.tree.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.Assert; import org.jboss.tools.smooks.configuration.editors.IFieldMarker; import org.jboss.tools.smooks.configuration.editors.IXMLStructuredObject; import org.jboss.tools.smooks.configuration.editors.utils.SmooksUIUtils; import org.jboss.tools.smooks.gef.model.AbstractSmooksGraphicalModel; import org.jboss.tools.smooks.graphical.editors.model.IValidatableModel; import org.jboss.tools.smooks.templating.template.CollectionMapping; import org.jboss.tools.smooks.templating.template.result.RemoveResult; import org.milyn.xml.DomUtils; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.Node; /** * @author DartPeng * */ public class TreeNodeConnection implements IValidatableModel{ protected int severity = IFieldMarker.TYPE_NONE; protected Object data; protected AbstractSmooksGraphicalModel sourceNode; protected AbstractSmooksGraphicalModel targetNode; protected List<String> markerMessages = null; protected PropertyChangeSupport support = new PropertyChangeSupport(this); public TreeNodeConnection() { } /** * @return the data */ public Object getData() { return data; } /** * @param data the data to set */ public void setData(Object data) { this.data = data; } public TreeNodeConnection(AbstractSmooksGraphicalModel sourceNode, AbstractSmooksGraphicalModel targetNode) { this.sourceNode = sourceNode; this.targetNode = targetNode; Assert.isNotNull(sourceNode); Assert.isNotNull(targetNode); } public void connect() { connectSource(); connectTarget(); } public void disconnect() { disconnectSource(); disconnectTarget(); } public void connectSource() { sourceNode.addSourceConnection(this); } public void connectTarget() { // if(data instanceof RemoveResult) { // ((TreeNodeModel)targetNode.getModelRootNode()).reAddMappingConnections(((RemoveResult)data).getRemoveMappings()); // } targetNode.addTargetConnection(this, sourceNode); } public void disconnectSource() { sourceNode.removeSourceConnection(this); } public void disconnectTarget() { targetNode.removeTargetConnection(this); // if(data instanceof RemoveResult) { // ((TreeNodeModel)targetNode.getModelRootNode()).removeMappingConnections(((RemoveResult)data).getRemoveMappings()); // } } public AbstractSmooksGraphicalModel getSourceNode() { return sourceNode; } public void setSourceNode(AbstractSmooksGraphicalModel sourceNode) { this.sourceNode = sourceNode; } public AbstractSmooksGraphicalModel getTargetNode() { return targetNode; } public void setTargetNode(AbstractSmooksGraphicalModel targetNode) { this.targetNode = targetNode; } public void addMessage(String message) { this.getMessage().add(message); } public List<String> getMessage() { if(markerMessages == null){ markerMessages = new ArrayList<String>(); } return markerMessages; } /** * @return the severity */ public int getSeverity() { return severity; } public void addPropertyChangeListener(PropertyChangeListener listener){ support.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener){ support.removePropertyChangeListener(listener); } /** * @param severity the severity to set */ public void setSeverity(int severity) { int old = this.severity; if (severity == this.severity){ old = -1; } this.severity = severity; support.firePropertyChange(AbstractSmooksGraphicalModel.PRO_SEVERITY_CHANGED, old, this.severity); } public String getTargetConnectionObjectRef() { TreeNodeModel sourceNodeModel = (TreeNodeModel) sourceNode; TreeNodeModel targetNodeModel = (TreeNodeModel) targetNode; Node sourceDOMNode = sourceNodeModel.getNode(); // This will only work for sources that are modeled hierarchically with TagObjects etc i.e. not Java if(sourceDOMNode == null) { throw new IllegalStateException("Invalid call to getTargetConnectionObjectRef() for non AbstractXMLObject connection source."); //$NON-NLS-1$ } StringBuilder builder = new StringBuilder(); // We first need to determine whether or not there's a parent Collection connection // on target side of the mapping... TreeNodeConnection parentConnection = targetNodeModel.getParentCollectionConnection(); if(parentConnection != null) { // If there's a parent Collection connection on the target side of the mapping, // we need to locate the other side of that connection on the source model // and then create an objectRef string based on the nodes between the source side of the parent // connection and the source side of the connection associated with this node connection. CollectionMapping collectionMapping = (CollectionMapping) parentConnection.getData(); Node sourceCollectionDomNode = ((TreeNodeModel)parentConnection.getSourceNode()).getNode(); // Work back to collection node... Node currentNode = sourceDOMNode; while(currentNode != null && currentNode != sourceCollectionDomNode) { if(currentNode.getNodeType() != Node.ATTRIBUTE_NODE && currentNode.getNodeType() != Node.ELEMENT_NODE) { currentNode = currentNode.getParentNode(); continue; } if(builder.length() > 0) { builder.insert(0, '/'); } if(currentNode.getNodeType() == Node.ATTRIBUTE_NODE) { builder.insert(0, "@" + ((Attr)currentNode).getNodeName()); currentNode = ((Attr)currentNode).getOwnerElement(); continue; } else if(currentNode.getNodeType() == Node.ELEMENT_NODE) { builder.insert(0, DomUtils.getName((Element)currentNode)); } currentNode = currentNode.getParentNode(); } if(currentNode == sourceCollectionDomNode) { builder.insert(0, collectionMapping.getCollectionItemName() + "/"); } } else { // No parent connection... just use the connection source path... builder.append(SmooksUIUtils.generateFullPath((IXMLStructuredObject) sourceNodeModel.getData(), "/")); } if(builder.length() > 1 && builder.charAt(0) == '.') { builder.deleteCharAt(0); } return builder.toString(); } }