/******************************************************************************* * Copyright (c) 2008 Red Hat, Inc. * Distributed under license by Red Hat, Inc. All rights reserved. * This program is made available under the terms of the * Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Red Hat, Inc. - initial API and implementation ******************************************************************************/ package org.jboss.tools.smooks.gef.model; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeSupport; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import org.eclipse.swt.graphics.Image; import org.jboss.tools.smooks.configuration.editors.xml.TagList; import org.jboss.tools.smooks.configuration.editors.xml.TagObject; import org.jboss.tools.smooks.configuration.editors.xml.TagPropertyObject; import org.jboss.tools.smooks.gef.common.RootModel; import org.jboss.tools.smooks.gef.tree.model.IConnectableNode; import org.jboss.tools.smooks.gef.tree.model.TreeNodeConnection; import org.jboss.tools.smooks.gef.tree.model.TreeNodeModel; import org.jboss.tools.smooks.graphical.editors.model.IValidatableModel; import org.jboss.tools.smooks.graphical.editors.model.InputDataTreeNodeModel; import org.w3c.dom.Node; /** * @author Dart * */ public class AbstractSmooksGraphicalModel implements IConnectableNode, IValidatableModel { private int severity = NONE; private List<String> messages = null; public static final String PRO_ADD_CHILD = "_pro_add_child"; //$NON-NLS-1$ public static final String PRO_MOVE_CHILD = "_pro_move_child"; //$NON-NLS-1$ public static final String PRO_REMOVE_CHILD = "_pro_remove_child"; //$NON-NLS-1$ public static final String PRO_ADD_SOURCE_CONNECTION = "_pro_add_source_connected"; //$NON-NLS-1$ public static final String PRO_SEVERITY_CHANGED = "_pro_severity_changed"; //$NON-NLS-1$ public static final String PRO_ADD_TARGET_CONNECTION = "_pro_add_target_connected"; //$NON-NLS-1$ public static final String PRO_REMOVE_SOURCE_CONNECTION = "_pro_remove_source_connected"; //$NON-NLS-1$ public static final String PRO_REMOVE_TARGET_CONNECTION = "_pro_remove_target_connected"; //$NON-NLS-1$ public static final String PRO_TEXT_CHANGED = "_pro_text_changed"; //$NON-NLS-1$ public static final String PRO_FORCE_VISUAL_CHANGED = "_pro_force_text_changed"; //$NON-NLS-1$ public static final String PRO_FORCE_CHIDLREN_CHANGED = "_pro_force_children_changed"; //$NON-NLS-1$ public static final String PRO_FORCE_CONNECTION_CHANGED = "_pro_force_connection_changed"; //$NON-NLS-1$ protected Object data = null; private boolean linkable = true; private AbstractSmooksGraphicalModel parent = null; private HashMap<String, Object> userDataMap = new HashMap<String, Object>(); protected PropertyChangeSupport support = new PropertyChangeSupport(this); protected List<AbstractSmooksGraphicalModel> children = null; protected List<TreeNodeConnection> sourceConnections = new ArrayList<TreeNodeConnection>(); protected List<TreeNodeConnection> targetConnections = new ArrayList<TreeNodeConnection>(); public AbstractSmooksGraphicalModel(Object data) { setData(data); } public boolean hasChildren() { return true; } public AbstractSmooksGraphicalModel getParent() { return parent; } public void setParent(AbstractSmooksGraphicalModel parent) { this.parent = parent; } public AbstractSmooksGraphicalModel getModelRootNode() { if(parent != null && !(parent instanceof RootModel)) { return parent.getModelRootNode(); } return this; } // // protected AbstractSmooksGraphicalModel createChildModel(Object model, // ITreeContentProvider contentProvider, // ILabelProvider labelProvider) { // return new TreeNodeModel(model, contentProvider, labelProvider); // } /** * @return the severity */ public int getSeverity() { return severity; } /** * @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(PRO_SEVERITY_CHANGED, old, this.severity); } public Node getNode() { if (data instanceof TagObject) { return ((TagObject) data).getReferenceElement(); } if (data instanceof TagPropertyObject) { return ((TagPropertyObject) data).getReferenceAttibute(); } return null; } public List<AbstractSmooksGraphicalModel> getChildren() { if (children == null) { children = new ArrayList<AbstractSmooksGraphicalModel>(); } return children; } public List<AbstractSmooksGraphicalModel> getChildrenWithoutDynamic() { if (children == null) { children = new ArrayList<AbstractSmooksGraphicalModel>(); } return children; } public static void disconnectAllConnections(AbstractSmooksGraphicalModel node) { disconnectAllConnections(node, null); } public static void disconnectAllConnections(AbstractSmooksGraphicalModel node, List<TreeNodeConnection> deletedConnections) { List<TreeNodeConnection> sourceConnections = node.getSourceConnections(); List<TreeNodeConnection> targetConnections = node.getTargetConnections(); List<TreeNodeConnection> tempSourceConnections = new ArrayList<TreeNodeConnection>(sourceConnections); List<TreeNodeConnection> tempTargetConnections = new ArrayList<TreeNodeConnection>(targetConnections); for (Iterator<?> iterator2 = tempTargetConnections.iterator(); iterator2.hasNext();) { TreeNodeConnection treeNodeConnection = (TreeNodeConnection) iterator2.next(); AbstractSmooksGraphicalModel sourceNode = treeNodeConnection.getSourceNode(); sourceNode.getSourceConnections().remove(treeNodeConnection); sourceNode.fireConnectionChanged(); if (deletedConnections != null) { deletedConnections.add(treeNodeConnection); } } for (Iterator<?> iterator2 = tempSourceConnections.iterator(); iterator2.hasNext();) { TreeNodeConnection treeNodeConnection = (TreeNodeConnection) iterator2.next(); // treeNodeConnection.disconnectTarget(); AbstractSmooksGraphicalModel targetNode = treeNodeConnection.getTargetNode(); targetNode.getTargetConnections().remove(treeNodeConnection); targetNode.fireConnectionChanged(); if (deletedConnections != null) { deletedConnections.add(treeNodeConnection); } } tempSourceConnections.clear(); tempTargetConnections.clear(); tempSourceConnections = null; tempTargetConnections = null; List<AbstractSmooksGraphicalModel> children = node.getChildren(); for (Iterator<?> iterator = children.iterator(); iterator.hasNext();) { TreeNodeModel treeNodeModel = (TreeNodeModel) iterator.next(); disconnectAllConnections(treeNodeModel, deletedConnections); } } public static void disconnectAllConnectionsWithEvent(AbstractSmooksGraphicalModel node, List<TreeNodeConnection> deletedConnections) { List<TreeNodeConnection> sourceConnections = node.getSourceConnections(); List<TreeNodeConnection> targetConnections = node.getTargetConnections(); List<TreeNodeConnection> tempSourceConnections = new ArrayList<TreeNodeConnection>(sourceConnections); List<TreeNodeConnection> tempTargetConnections = new ArrayList<TreeNodeConnection>(targetConnections); for (Iterator<?> iterator2 = tempTargetConnections.iterator(); iterator2.hasNext();) { TreeNodeConnection treeNodeConnection = (TreeNodeConnection) iterator2.next(); // AbstractSmooksGraphicalModel sourceNode = treeNodeConnection.getSourceNode(); treeNodeConnection.disconnect(); // sourceNode.getSourceConnections().remove(treeNodeConnection); // sourceNode.fireConnectionChanged(); if (deletedConnections != null) { deletedConnections.add(treeNodeConnection); } } for (Iterator<?> iterator2 = tempSourceConnections.iterator(); iterator2.hasNext();) { TreeNodeConnection treeNodeConnection = (TreeNodeConnection) iterator2.next(); treeNodeConnection.disconnect(); // AbstractSmooksGraphicalModel targetNode = treeNodeConnection.getTargetNode(); // targetNode.getTargetConnections().remove(treeNodeConnection); // targetNode.fireConnectionChanged(); if (deletedConnections != null) { deletedConnections.add(treeNodeConnection); } } tempSourceConnections.clear(); tempTargetConnections.clear(); tempSourceConnections = null; tempTargetConnections = null; List<AbstractSmooksGraphicalModel> children = node.getChildren(); for (Iterator<?> iterator = children.iterator(); iterator.hasNext();) { TreeNodeModel treeNodeModel = (TreeNodeModel) iterator.next(); disconnectAllConnectionsWithEvent(treeNodeModel, deletedConnections); } } protected boolean graphicalChildExist(Object model, Object[] models) { for (int i = 0; i < models.length; i++) { if (model == models[i]) { return true; } } return false; } protected boolean childExsit(Object model) { if (children != null) { for (Iterator<?> iterator = children.iterator(); iterator.hasNext();) { TreeNodeModel node = (TreeNodeModel) iterator.next(); if (node.getData() == model) { return true; } } } return false; } public void addPropertyChangeListener(PropertyChangeListener listener) { support.addPropertyChangeListener(listener); } public void removePropertyChangeListener(PropertyChangeListener listener) { support.removePropertyChangeListener(listener); } public void addSourceConnection(TreeNodeConnection connection) { if (this.sourceConnections.indexOf(connection) == -1) { this.sourceConnections.add(connection); support.firePropertyChange(PRO_ADD_SOURCE_CONNECTION, null, connection); } } public void removeSourceConnection(TreeNodeConnection connection) { if (this.sourceConnections.indexOf(connection) != -1) { this.sourceConnections.remove(connection); support.firePropertyChange(PRO_REMOVE_SOURCE_CONNECTION, connection, null); } } public void addTargetConnection(TreeNodeConnection connection, AbstractSmooksGraphicalModel sourceNode) { if (this.targetConnections.indexOf(connection) == -1) { this.targetConnections.add(connection); support.firePropertyChange(PRO_ADD_TARGET_CONNECTION, null, connection); } } public void removeTargetConnection(TreeNodeConnection connection) { if (this.targetConnections.indexOf(connection) != -1) { this.targetConnections.remove(connection); support.firePropertyChange(PRO_REMOVE_TARGET_CONNECTION, connection, null); } } public void addChild(AbstractSmooksGraphicalModel node) { if (getChildrenWithoutDynamic().indexOf(node) == -1) { getChildrenWithoutDynamic().add(node); node.setParent(this); support.firePropertyChange(PRO_ADD_CHILD, null, node); } } public void addChild(int index, AbstractSmooksGraphicalModel node) { this.addChild(node); this.moveChild(index, node); } public void moveChild(int index, AbstractSmooksGraphicalModel node) { int oldIndex = getChildrenWithoutDynamic().indexOf(node); if (index >= 0 && index <= getChildrenWithoutDynamic().size() - 1) { if (oldIndex != -1 && index != oldIndex) { getChildrenWithoutDynamic().remove(node); getChildrenWithoutDynamic().add(index, node); support.firePropertyChange(PRO_MOVE_CHILD, oldIndex, index); } } } public void removeChild(AbstractSmooksGraphicalModel node) { if (getChildrenWithoutDynamic().indexOf(node) != -1) { getChildrenWithoutDynamic().remove(node); node.setParent(null); support.firePropertyChange(PRO_REMOVE_CHILD, node, null); } } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public void setUserData(String key, Object data) { userDataMap.put(key, data); } public Object getUserData(String key) { return userDataMap.get(key); } public String getText() { // if (data != null && labelProvider != null) { // return labelProvider.getText(data); // } return null; } public Image getImage() { // if (data != null && labelProvider != null) { // return labelProvider.getImage(data); // } return null; } public boolean isLinkable(Class<?> connectionType) { return linkable; } public void setLinkable(boolean linkable) { this.linkable = linkable; } public boolean canLinkWithSource(Object model) { return true; } public boolean canLinkWithTarget(Object model) { return true; } public void setText(String text) { } public List<TreeNodeConnection> getSourceConnections() { return sourceConnections; } public List<TreeNodeConnection> getTargetConnections() { return targetConnections; } public void fireChildrenChanged() { support.firePropertyChange(PRO_FORCE_CHIDLREN_CHANGED, new Object(), null); } public void fireConnectionChanged() { support.firePropertyChange(PRO_FORCE_CONNECTION_CHANGED, new Object(), null); } public void fireVisualChanged() { support.firePropertyChange(PRO_FORCE_VISUAL_CHANGED, new Object(), null); } public void addMessage(String message) { getMessage().add(message); } public List<String> getMessage() { if(messages == null){ messages = new ArrayList<String>(); } return messages; } public TreeNodeModel getModelNode(String srcPath) { String[] pathTokens = srcPath.split("/"); if(pathTokens.length > 0) { return getModeNode(pathTokens, 0); } return null; } public TreeNodeModel getModelNode(Node queryNode) { List<AbstractSmooksGraphicalModel> thisNodeChildren = getChildren(); if(thisNodeChildren != null) { for(AbstractSmooksGraphicalModel childNode : thisNodeChildren) { if(!(childNode instanceof TreeNodeModel)) { continue; } Object childData = childNode.getData(); if(queryNode.getNodeType() == Node.ELEMENT_NODE) { if(childData instanceof TagObject && ((TagObject)childData).getReferenceElement() == queryNode) { return (TreeNodeModel) childNode; } } else if(queryNode.getNodeType() == Node.ATTRIBUTE_NODE) { if(childData instanceof TagPropertyObject && ((TagPropertyObject)childData).getReferenceAttibute() == queryNode) { return (TreeNodeModel) childNode; } } if(childData instanceof TagObject || childData instanceof TagList) { TreeNodeModel matchedNode = childNode.getModelNode(queryNode); if(matchedNode != null) { return matchedNode; } } } } return null; } public TreeNodeModel getModeNode(String[] pathTokens, int checkNodeIndex) { String nodeName = pathTokens[checkNodeIndex]; boolean isAttribute = (nodeName.charAt(0) == '@'); if(isAttribute) { nodeName = nodeName.substring(1); } List<AbstractSmooksGraphicalModel> thisNodeChildren = getChildren(); if(thisNodeChildren != null) { for(AbstractSmooksGraphicalModel childNode : thisNodeChildren) { if(!(childNode instanceof TreeNodeModel)) { continue; } Object childData = childNode.getData(); boolean isMatch = false; if(isAttribute) { if(childData instanceof TagPropertyObject) { TagPropertyObject tagProp = (TagPropertyObject) childData; if(tagProp.getName().equals(nodeName)) { isMatch = true; } } } else { if(childData instanceof TagObject) { TagObject tagObj = (TagObject) childData; if(tagObj.getName().equals(nodeName)) { isMatch = true; } } } if(isMatch) { if(checkNodeIndex == pathTokens.length - 1) { // This is the node... return it... return (TreeNodeModel) childNode; } else { // Drill into this child node and continue searching... return childNode.getModeNode(pathTokens, checkNodeIndex + 1); } } } } return null; } }