| /******************************************************************************* |
| * Copyright (c) 2001, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are 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: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.wst.wsdl.ui.internal.actions; |
| |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| |
| import javax.wsdl.OperationType; |
| |
| import org.eclipse.draw2d.IFigure; |
| import org.eclipse.draw2d.Polyline; |
| import org.eclipse.draw2d.geometry.Point; |
| import org.eclipse.draw2d.geometry.PointList; |
| import org.eclipse.draw2d.geometry.Rectangle; |
| import org.eclipse.gef.EditPart; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.wst.wsdl.Fault; |
| import org.eclipse.wst.wsdl.Input; |
| import org.eclipse.wst.wsdl.Message; |
| import org.eclipse.wst.wsdl.Output; |
| import org.eclipse.wst.wsdl.Part; |
| import org.eclipse.wst.wsdl.WSDLElement; |
| import org.eclipse.wst.wsdl.internal.impl.OperationImpl; |
| import org.eclipse.wst.wsdl.ui.internal.WSDLEditor; |
| import org.eclipse.wst.wsdl.ui.internal.graph.WSDLComponentViewer; |
| import org.eclipse.wst.wsdl.ui.internal.graph.editparts.WSDLTreeNodeEditPart; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| |
| |
| public class WSDLDragReorderAction extends WSDLDragAction |
| { |
| protected WSDLEditor wsdlEditor; |
| protected WSDLElement movingChild; |
| protected WSDLElement newParent; |
| protected WSDLTreeNodeEditPart leftSiblingEditPart; |
| protected WSDLTreeNodeEditPart rightSiblingEditPart; |
| protected WSDLElement leftSibElement; |
| protected WSDLElement rightSibElement; |
| protected boolean canNeverExecute = false; |
| |
| public WSDLDragReorderAction(WSDLTreeNodeEditPart movingChildEditPart, EditPart pointerEditPart, Point pointerLocation) { |
| this.movingChildEditPart = movingChildEditPart; |
| this.pointerLocation = pointerLocation; |
| |
| EditPart possibleParent = getParentEditPart(pointerEditPart); |
| |
| if (!(possibleParent instanceof WSDLTreeNodeEditPart)) { |
| canNeverExecute = true; |
| return; |
| } |
| |
| WSDLTreeNodeEditPart targetParentEditPart = (WSDLTreeNodeEditPart) possibleParent; |
| wsdlEditor = ((WSDLComponentViewer) possibleParent.getViewer()).getWSDLEditor(); |
| |
| if (pointerEditPart.getParent() != null) { |
| // Sort the siblings (and itself) |
| List targetEditPartSiblings = pointerEditPart.getParent().getChildren(); |
| Collections.sort(targetEditPartSiblings, new VerticalEditPartComparator()); |
| |
| // Get 'left' and 'right' siblings |
| leftSiblingEditPart = getVerticalLeftSibling(targetEditPartSiblings, movingChildEditPart, pointerLocation); |
| rightSiblingEditPart = getVerticalRightSibling(targetEditPartSiblings, movingChildEditPart, pointerLocation); |
| |
| if (movingChildEditPart != null) |
| movingChild = (WSDLElement) movingChildEditPart.getModel(); |
| if (leftSiblingEditPart != null) |
| leftSibElement = (WSDLElement) leftSiblingEditPart.getModel(); |
| if (rightSiblingEditPart != null) |
| rightSibElement = (WSDLElement) rightSiblingEditPart.getModel(); |
| |
| newParent = (WSDLElement) targetParentEditPart.getModel(); |
| } |
| else { |
| newParent = (WSDLElement) targetParentEditPart.getModel(); |
| leftSibElement = null; |
| rightSibElement= null; |
| } |
| } |
| |
| public boolean canExecute() |
| { |
| boolean result = false; |
| |
| if (canNeverExecute || newParent == null || movingChild == null) { |
| return false; |
| } |
| |
| if (movingChild instanceof Input) { |
| if (!(leftSibElement instanceof Fault) && newParent.equals(movingChild.eContainer())) { |
| result = true; |
| } |
| } |
| else if (movingChild instanceof Output) { |
| if (!(leftSibElement instanceof Fault) && newParent.equals(movingChild.eContainer())) { |
| result = true; |
| } |
| } |
| else if (movingChild instanceof Part) { |
| if (newParent instanceof Message && newParent.equals(movingChild.eContainer())) { |
| result = true; |
| } |
| } |
| |
| return result; |
| } |
| |
| |
| /* |
| * @see IAction#run() |
| */ |
| public void run() |
| { |
| // beginRecording(); |
| if (canExecute()) { |
| if (movingChild instanceof Input) { |
| Input input = (Input) movingChild; |
| OperationImpl operation = (OperationImpl) input.eContainer(); |
| |
| if (leftSiblingEditPart == null) { |
| // Input/Output style |
| setInputOutputOrder(operation, true); |
| } |
| else { |
| // Output/Input style |
| setInputOutputOrder(operation, false); |
| } |
| } |
| else if (movingChild instanceof Output) { |
| Output output = (Output) movingChild; |
| OperationImpl operation = (OperationImpl) output.eContainer(); |
| |
| if (leftSiblingEditPart == null) { |
| // Output/Input style |
| setInputOutputOrder(operation, false); |
| } |
| else { |
| // Input/Output style |
| setInputOutputOrder(operation, true); |
| } |
| } |
| else if (movingChild instanceof Part) { |
| Message message = (Message) newParent; |
| List parts = message.getEParts(); |
| |
| parts.remove(movingChild); |
| |
| int leftIndex = -1, rightIndex = -1; |
| if (leftSibElement != null) { |
| leftIndex = parts.indexOf(leftSibElement); |
| } |
| if (rightSibElement != null) { |
| rightIndex = parts.indexOf(rightSibElement); |
| } |
| |
| if (leftIndex == -1) { |
| // Add moving child to the front |
| parts.add(0, movingChild); |
| } |
| else if (rightIndex == -1) { |
| // Add moving child to the end |
| parts.add(movingChild); |
| } |
| else { |
| // Add moving child after the occurence of the left sibling |
| parts.add(leftIndex + 1, movingChild); |
| } |
| } |
| wsdlEditor.getSelectionManager().setSelection(new StructuredSelection(movingChild)); |
| } |
| // endRecording(); |
| } |
| |
| public IFigure getFeedbackFigure() { |
| IFigure feedbackFigure = null; |
| if (feedbackFigure == null && movingChildEditPart instanceof WSDLTreeNodeEditPart) |
| { |
| feedbackFigure = new Polyline(); |
| // polyLine.setLineStyle(Graphics.LINE_DASHDOT); |
| ((Polyline)feedbackFigure).setLineWidth(2); |
| drawLines((Polyline) feedbackFigure); |
| } |
| |
| return feedbackFigure; |
| } |
| |
| /* Return a PointList which will be used to add a feedback figure. The feedback figure will be a |
| * Polyline composed of the Points in the PointList |
| */ |
| private PointList drawLines(Polyline polyLine) { |
| PointList pointList = new PointList(); |
| |
| if (leftSiblingEditPart != null) { |
| Rectangle leftRectangle = leftSiblingEditPart.getFigure().getBounds(); |
| int xCoord = leftRectangle.x + 15; |
| int yCoord = leftRectangle.y; |
| int height = leftRectangle.height; |
| int width = leftRectangle.width - 15; |
| |
| // Draw left end line |
| addLineToPolyline(polyLine, xCoord, yCoord + height + 3, xCoord, yCoord + height - 3); |
| addLineToPolyline(polyLine, xCoord, yCoord + height - 3, xCoord, yCoord + height); |
| |
| // Draw horizontal line |
| addLineToPolyline(polyLine, xCoord, yCoord + height, xCoord + width, yCoord + height); |
| |
| // Draw right end line |
| addLineToPolyline(polyLine, xCoord + width, yCoord + height, xCoord + width, yCoord + height - 3); |
| addLineToPolyline(polyLine, xCoord + width, yCoord + height, xCoord + width, yCoord + height + 3); |
| } |
| else if (rightSiblingEditPart != null) { |
| Rectangle rightRectangle = rightSiblingEditPart.getFigure().getBounds(); |
| int xCoord = rightRectangle.x + 15; |
| int yCoord = rightRectangle.y; |
| int height = rightRectangle.height; |
| int width = rightRectangle.width - 15; |
| |
| // Draw left end line |
| addLineToPolyline(polyLine, xCoord, yCoord + 3, xCoord, yCoord - 3); |
| addLineToPolyline(polyLine, xCoord, yCoord - 3, xCoord, yCoord); |
| |
| // Draw horizontal line |
| addLineToPolyline(polyLine, xCoord, yCoord, xCoord + width, yCoord); |
| |
| // Draw right end line |
| addLineToPolyline(polyLine, xCoord + width, yCoord, xCoord + width, yCoord - 3); |
| addLineToPolyline(polyLine, xCoord + width, yCoord, xCoord + width, yCoord + 3); |
| } |
| |
| return pointList; |
| } |
| |
| protected Polyline addLineToPolyline(Polyline polyline, int x1, int y1, int x2, int y2) { |
| polyline.addPoint(new Point(x1, y1)); |
| polyline.addPoint(new Point(x2, y2)); |
| |
| return polyline; |
| } |
| |
| /* |
| * Pre-condition: The List siblings should be sorted by it's y-coordinate |
| */ |
| private WSDLTreeNodeEditPart getVerticalRightSibling(List siblings, WSDLTreeNodeEditPart movingEditPart, Point pointerLocation) { |
| WSDLTreeNodeEditPart rightSibling = null; |
| int pointerYLocation = pointerLocation.y; |
| |
| for (int index = 0; index < siblings.size(); index++) { |
| WSDLTreeNodeEditPart sibling = (WSDLTreeNodeEditPart) siblings.get(index); |
| int siblingYLocation = sibling.getSelectionFigure().getBounds().getCenter().y; |
| |
| if (siblingYLocation > pointerYLocation) { |
| rightSibling = sibling; |
| break; |
| } |
| } |
| |
| return rightSibling; |
| } |
| |
| /* |
| * Pre-condition: The List siblings should be sorted by it's y-coordinate |
| */ |
| private WSDLTreeNodeEditPart getVerticalLeftSibling(List siblings, WSDLTreeNodeEditPart movingEditPart, Point pointerLocation) { |
| WSDLTreeNodeEditPart leftSibling = null; |
| int pointerYLocation = pointerLocation.y; |
| |
| int index; |
| for (index = 0; index < siblings.size(); index++) { |
| WSDLTreeNodeEditPart sibling = (WSDLTreeNodeEditPart) siblings.get(index); |
| int siblingYLocation = sibling.getSelectionFigure().getBounds().getCenter().y; |
| |
| if (siblingYLocation > pointerYLocation) { |
| if (index > 0) { |
| leftSibling = (WSDLTreeNodeEditPart) siblings.get(index - 1); |
| } |
| |
| break; |
| } |
| } |
| |
| if (index == siblings.size()) { |
| leftSibling = (WSDLTreeNodeEditPart) siblings.get(index - 1); |
| } |
| |
| return leftSibling; |
| } |
| |
| protected EditPart getParentEditPart(EditPart target) |
| { |
| return target.getParent(); |
| } |
| |
| // boolean inputFirst = true if the Input is the first in the order of Input and Output |
| private void setInputOutputOrder(OperationImpl operation, boolean inputFirst) { |
| // We need to determine more info before we can set the style |
| if (inputFirst && operation.getEInput() != null) { |
| // Check if there is an Output |
| if (operation.getEOutput() != null) { |
| // Order is: Input, Output |
| /* |
| Node operationNode = operation.getElement(); |
| NodeList childNodeList = operationNode.getChildNodes(); |
| |
| Node inputNode = operation.getEInput().getElement(); |
| Node outputNode = operation.getEOutput().getElement(); |
| |
| Node inputTextNode = inputNode.getNextSibling(); |
| Node outputTextNode = outputNode.getNextSibling(); |
| |
| int inputNodeIndex = getNodeIndex(childNodeList, inputNode); |
| int outputNodeIndex = getNodeIndex(childNodeList, outputNode); |
| |
| if (inputNodeIndex > outputNodeIndex) { |
| // We need to swap Input and Output |
| operationNode.removeChild(inputNode); |
| operationNode.removeChild(outputNode); |
| |
| operationNode.insertBefore(inputNode, outputTextNode); |
| operationNode.insertBefore(outputNode, inputTextNode); |
| } |
| */ |
| |
| setOperationStyle(operation, OperationType.REQUEST_RESPONSE); |
| } |
| /* |
| else { |
| // Order is: Input |
| setOperationStyle(operation, OperationType.ONE_WAY); |
| } |
| */ |
| } |
| else if (operation.getEOutput() != null) { |
| // Check if there is an Input |
| if (operation.getEInput() != null) { |
| // Order is: Output, Input |
| /* |
| Node operationNode = operation.getElement(); |
| NodeList childNodeList = operationNode.getChildNodes(); |
| |
| Node inputNode = operation.getEInput().getElement(); |
| Node outputNode = operation.getEOutput().getElement(); |
| |
| Node inputTextNode = inputNode.getNextSibling(); |
| Node outputTextNode = outputNode.getNextSibling(); |
| |
| int inputNodeIndex = getNodeIndex(childNodeList, inputNode); |
| int outputNodeIndex = getNodeIndex(childNodeList, outputNode); |
| |
| if (outputNodeIndex > inputNodeIndex) { |
| // We need to swap Input and Output |
| operationNode.removeChild(inputNode); |
| operationNode.removeChild(outputNode); |
| |
| operationNode.insertBefore(inputNode, outputTextNode); |
| operationNode.insertBefore(outputNode, inputTextNode); |
| } |
| */ |
| setOperationStyle(operation, OperationType.SOLICIT_RESPONSE); |
| } |
| /* |
| else { |
| // Order is: Output |
| setOperationStyle(operation, OperationType.NOTIFICATION); |
| } |
| */ |
| } |
| } |
| |
| /* |
| * return -1 if node is not found in the given nodeList |
| */ |
| private int getNodeIndex(NodeList nodeList, Node node) { |
| int index = 0; |
| while (index < nodeList.getLength() && !(nodeList.item(index).equals(node))) { |
| index++; |
| } |
| |
| if (index >= nodeList.getLength()) { |
| index = -1; |
| } |
| |
| return index; |
| } |
| |
| private void setOperationStyle(OperationImpl operation, OperationType operationType) { |
| // If there is no style to begin with, don't set one now |
| if (operation.getStyle() == null) { |
| return; |
| } |
| |
| operation.setStyle(operationType); |
| } |
| |
| private class VerticalEditPartComparator implements Comparator { |
| |
| public VerticalEditPartComparator() { |
| } |
| |
| public int compare(Object part1, Object part2) { |
| int compareValue = 0; |
| |
| if (part1 instanceof WSDLTreeNodeEditPart && part2 instanceof WSDLTreeNodeEditPart) { |
| WSDLTreeNodeEditPart editPart1 = (WSDLTreeNodeEditPart) part1; |
| WSDLTreeNodeEditPart editPart2 = (WSDLTreeNodeEditPart) part2; |
| |
| int editPart1Y = editPart1.getSelectionFigure().getBounds().getCenter().y; |
| int editPart2Y = editPart2.getSelectionFigure().getBounds().getCenter().y; |
| |
| Integer integerPart1 = new Integer(editPart1Y); |
| Integer integerPart2 = new Integer(editPart2Y); |
| |
| compareValue = integerPart1.compareTo(integerPart2); |
| } |
| |
| return compareValue; |
| } |
| } |
| } |