You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by sa...@apache.org on 2014/04/14 20:31:01 UTC
[59/90] [abbrv] AIRAVATA-1124
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphGUI.java
new file mode 100644
index 0000000..15379bb
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphGUI.java
@@ -0,0 +1,198 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph;
+
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.SwingUtilities;
+
+import org.apache.airavata.workflow.model.graph.Edge;
+import org.apache.airavata.workflow.model.graph.Graph;
+import org.apache.airavata.workflow.model.graph.GraphPiece;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.system.MemoNode;
+import org.apache.airavata.workflow.model.graph.system.StreamSourceNode;
+import org.apache.airavata.workflow.model.graph.util.GraphUtil;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+
+public class GraphGUI implements GraphPieceGUI {
+
+ private Graph graph;
+
+ /**
+ * @param graph
+ */
+ public GraphGUI(Graph graph) {
+ this.graph = graph;
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.GraphPieceGUI#mouseClicked(java.awt.event.MouseEvent,
+ * org.apache.airavata.xbaya.XBayaEngine)
+ */
+ public void mouseClicked(MouseEvent event, XBayaEngine engine) {
+ GraphPiece piece = getGraphPieceAt(event.getPoint());
+ if (piece != null && graph.isEditable()) {
+ NodeController.getGUI(piece).mouseClicked(event, engine);
+ }
+ }
+
+ /**
+ * Gets the bounding Rectangle of this Graph.
+ *
+ * @return A rectangle indicating this component's bounds
+ */
+ protected Rectangle getBounds() {
+ Rectangle bounds = new Rectangle();
+ for (Node node : this.graph.getNodes()) {
+ bounds.add(NodeController.getGUI(node).getBounds());
+ }
+ final int margin = 10;
+ bounds.height += margin;
+ bounds.width += margin;
+ return bounds;
+ }
+
+ /**
+ * @param g
+ */
+ protected void paint(Graphics2D g) {
+
+ // Calcurate the widge of the nodes.
+ for (Node node : this.graph.getNodes()) {
+ NodeController.getGUI(node).calculatePositions(g);
+ }
+
+ LinkedList<Node> nodes = new LinkedList<Node>(this.graph.getNodes());
+ List<MemoNode> memoNodes = GraphUtil.getNodes(this.graph, MemoNode.class);
+ nodes.removeAll(memoNodes);
+
+ // Paints the edges before nodes.
+ for (Edge edge : this.graph.getEdges()) {
+ NodeController.getGUI(edge).paint(g);
+ }
+
+ // Paint regular nodes.
+ // The ports are painted from inside of each node.
+ for (Node node : nodes) {
+ NodeController.getGUI(node).paint(g);
+ }
+
+ // Print memoNodes at last so that they stay on top of everything.
+ for (MemoNode node : memoNodes) {
+ NodeController.getGUI(node).paint(g);
+ }
+ }
+
+ protected StreamSourceNode getStreamSourceAt(Point point) {
+ for (Node node : this.graph.getNodes()) {
+ // Check the node first
+ if (NodeController.getGUI(node).isIn(point) && node instanceof StreamSourceNode) {
+ return (StreamSourceNode) node;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the visible object at the specified location. The object is either a Node, a Port, or an Edge.
+ *
+ * @param point
+ * The location
+ * @return The visible object a the specified location
+ */
+ protected GraphPiece getGraphPieceAt(Point point) {
+
+ GraphPiece piece = null;
+
+ // Starts from edge because it is drawn first, which means it's at the
+ // bottom.
+ double minEdgeDist = Double.MAX_VALUE;
+ Edge closestEdge = null;
+ for (Edge edge : this.graph.getEdges()) {
+ double dist = NodeController.getGUI(edge).getMiddlePosition().distance(point);
+ if (dist < minEdgeDist) {
+ closestEdge = edge;
+ minEdgeDist = dist;
+ }
+ }
+ if (minEdgeDist < 20) {
+ piece = closestEdge;
+ }
+
+ // Then, each node and ports of it.
+ for (Node node : this.graph.getNodes()) {
+ // Check the node first
+ if (NodeController.getGUI(node).isIn(point)) {
+ piece = node;
+ }
+
+ // Find the closest port of this node.
+ double minPortDist = Double.MAX_VALUE;
+ Port closestPort = null;
+ for (Port port : node.getAllPorts()) {
+ double dist = NodeController.getGUI(port).getPosition().distance(point);
+ if (dist < minPortDist) {
+ closestPort = port;
+ minPortDist = dist;
+ }
+ }
+ if (minPortDist <= PortGUI.DATA_PORT_SIZE) {
+ piece = closestPort;
+ }
+
+ // Don't break from this loop because the later ones are drawn at
+ // the top of other nodes.
+ }
+ return piece;
+ }
+
+ /**
+ * Returns the visible object in the specified area. The objects are either a Node, a Port, or an Edge.
+ *
+ * @param rec
+ * area to cover
+ * @return The visible object a the specified location
+ */
+ protected List<Node> getNodesIn(Rectangle rec) {
+ ArrayList<Node> pieces = new ArrayList<Node>();
+
+ // Then, each node and ports of it.
+ for (Node node : this.graph.getNodes()) {
+ Rectangle inter = SwingUtilities.computeIntersection(rec.x, rec.y, rec.width, rec.height, NodeController.getGUI(node)
+ .getBounds());
+ if (inter.width != 0 && inter.height != 0)
+ pieces.add(node);
+ }
+
+ return pieces;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphPieceGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphPieceGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphPieceGUI.java
new file mode 100644
index 0000000..a73b6a0
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphPieceGUI.java
@@ -0,0 +1,36 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph;
+
+import java.awt.event.MouseEvent;
+
+import org.apache.airavata.xbaya.XBayaEngine;
+
+public interface GraphPieceGUI {
+
+ /**
+ * @param event
+ * @param engine
+ */
+ public void mouseClicked(MouseEvent event, XBayaEngine engine);
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/NodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/NodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/NodeGUI.java
new file mode 100644
index 0000000..255a961
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/NodeGUI.java
@@ -0,0 +1,535 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Shape;
+import java.awt.event.MouseEvent;
+import java.awt.geom.AffineTransform;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Node.NodeObserver;
+import org.apache.airavata.workflow.model.graph.Node.NodeUpdateType;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.monitor.MonitorEventHandler.NodeState;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public abstract class NodeGUI implements GraphPieceGUI, NodeObserver {
+
+ /**
+ * BREAK_POINT_BORDER_COLOR
+ */
+ protected static final Color BREAK_POINT_BORDER_COLOR = new Color(53, 103, 157);
+
+ /**
+ * The minimum width of the node.
+ */
+ protected static final int MINIMUM_WIDTH = 100;
+
+ /**
+ * The minimum height of the node
+ */
+ protected static final int MINIMUM_HEIGHT = 37;
+
+ protected static final int TEXT_GAP_X = 5;
+
+ protected static final int TEXT_GAP_Y = 2;
+
+ protected static final Color TEXT_COLOR = Color.black;
+
+ protected static final int PORT_GAP = 13;
+
+ protected static final int PORT_INITIAL_GAP = 10;
+
+ protected static final Color EDGE_COLOR = Color.GRAY;
+
+ protected static final Color DEFAULT_HEAD_COLOR = Color.white;
+
+ protected static final Color SELECTED_HEAD_COLOR = Color.pink;
+
+ /**
+ * The default body color.
+ */
+ public static final Color DEFAULT_BODY_COLOR = new Color(250, 220, 100);
+
+ protected static final Color DRAGGED_BODY_COLOR = Color.lightGray;
+
+ protected static final Color BREAK_POINT_COLOR = new Color(174, 197, 221);
+
+ protected Node node;
+
+ protected Dimension dimension;
+
+ protected int headHeight;
+
+ protected boolean selected = false;
+
+ protected boolean dragged = false;
+
+ protected Color headColor;
+
+ protected Color bodyColor;
+
+ protected List<Paintable> paintables;
+
+ /**
+ * @param node
+ */
+ public NodeGUI(Node node) {
+ this.node = node;
+ this.bodyColor = DEFAULT_BODY_COLOR;
+ this.headColor = DEFAULT_HEAD_COLOR;
+ // The followings are just to make sure that it has some size.
+ this.dimension = new Dimension(MINIMUM_WIDTH, MINIMUM_HEIGHT);
+ this.paintables = new LinkedList<Paintable>();
+ node.registerObserver(this);
+ }
+
+ /**
+ * Sets the color of the body.
+ *
+ * @param color
+ * The color
+ */
+ public void setBodyColor(Color color) {
+ this.bodyColor = color;
+ }
+
+ /**
+ * @return The color of the body.
+ */
+ public Color getBodyColor() {
+ return this.bodyColor;
+ }
+
+ /**
+ * Sets the color of the head.
+ *
+ * @param color
+ * The color to set
+ */
+ public void setHeadColor(Color color) {
+ this.headColor = color;
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.GraphPieceGUI#mouseClicked(java.awt.event.MouseEvent,
+ * org.apache.airavata.xbaya.XBayaEngine)
+ */
+ public void mouseClicked(MouseEvent event, XBayaEngine engine) {
+ // Nothing by default
+ }
+
+ /**
+ * @param paintable
+ */
+ public void addPaintable(Paintable paintable) {
+ this.paintables.add(paintable);
+ }
+
+ /**
+ * @param paintable
+ */
+ public void removePaintable(Paintable paintable) {
+ this.paintables.remove(paintable);
+ }
+
+ /**
+ * @param flag
+ */
+ protected void setSelectedFlag(boolean flag) {
+ this.selected = flag;
+ if (this.selected) {
+ this.headColor = SELECTED_HEAD_COLOR;
+ } else {
+ this.headColor = DEFAULT_HEAD_COLOR;
+ }
+ }
+
+ /**
+ * @param flag
+ */
+ protected void setDraggedFlag(boolean flag) {
+ this.dragged = flag;
+ }
+
+ /**
+ * Returns the position of the node.
+ *
+ * @return the position of the node
+ */
+ protected Point getPosition() {
+ return getNode().getPosition();
+ }
+
+ /**
+ * Gets the bounding Rectangle of this Node.
+ *
+ * @return A rectangle indicating this component's bounds
+ */
+ protected Rectangle getBounds() {
+ return new Rectangle(getNode().getPosition(), this.dimension);
+ }
+
+ /**
+ * Checks if a user's click is to select the node.
+ *
+ * @param point
+ * The location.
+ * @return true if the user's click is to select the node; false otherwise
+ */
+ protected boolean isIn(Point point) {
+ Rectangle bounds = getBounds();
+ return bounds.contains(point);
+ }
+
+ /**
+ * Checks if a user's click is to select the configuration
+ *
+ * @param point
+ * @return true if the user's click is to select the node, false otherwise
+ */
+ @SuppressWarnings("unused")
+ protected boolean isInConfig(Point point) {
+ return false;
+ }
+
+ /**
+ * Calculates the width of the node and x-coordinate of the ports. This method has to be called before painting any
+ * parts of the graph.
+ *
+ * @param g
+ */
+ protected void calculatePositions(Graphics g) {
+ Font oldFont = g.getFont();
+ g.setFont(new Font(oldFont.getFontName(),Font.BOLD,oldFont.getSize()));
+ FontMetrics fm = g.getFontMetrics();
+
+ this.headHeight = fm.getHeight() + TEXT_GAP_Y * 2;
+
+ int maxNumPort = Math.max(getNode().getOutputPorts().size(), getNode().getInputPorts().size());
+ this.dimension.height = Math.max(this.headHeight + PORT_INITIAL_GAP + PORT_GAP * maxNumPort, MINIMUM_HEIGHT);
+ this.dimension.width = Math.max(MINIMUM_WIDTH, fm.stringWidth(getNode().getID()) + TEXT_GAP_X * 5);
+
+ /* Calculates the position of ports */
+ setPortPositions();
+ g.setFont(oldFont);
+ }
+
+ /**
+ * @param g
+ */
+ protected void paint(Graphics2D g) {
+ Shape componentShape = getComponentShape();
+
+ // Draws the body.
+ drawBody(g, componentShape, getComponentBodyColor());
+
+ // Draws the head.
+ drawHeader(g, getComponentHeaderShape(), getComponentHeaderText(), getComponentHeaderColor());
+
+ // Draw a small circle to indicate the break
+ drawBreaks(g, getNode().getPosition());
+
+ // Edge
+ drawEdge(g, componentShape, getComponentEdgeColor());
+
+ // Paint all ports
+ drawPorts(g, getAllPorts());
+
+ // Paint extras
+ drawExtras(g);
+ }
+
+ /** Following functions need to be overridden for if the component shape/text/color is different **/
+
+ protected final Collection<? extends Port> getAllPorts() {
+ return getNode().getAllPorts();
+ }
+
+ protected Node getNode() {
+ return this.node;
+ }
+
+ protected final Color getComponentEdgeColor() {
+ return EDGE_COLOR;
+ }
+
+ protected Color getComponentHeaderColor() {
+ return this.headColor;
+ }
+
+ protected Shape getComponentHeaderShape() {
+ Point position = getNode().getPosition();
+ RoundRectangle2D headerBoundaryRect = new RoundRectangle2D.Double(position.x, position.y, this.dimension.width, this.headHeight,DrawUtils.ARC_SIZE, DrawUtils.ARC_SIZE);
+ return headerBoundaryRect;
+ }
+
+ protected final Color getComponentBodyColor() {
+ Color paintBodyColor;
+ if (this.dragged) {
+ paintBodyColor=DRAGGED_BODY_COLOR;
+ } else {
+ paintBodyColor=this.bodyColor;
+ }
+ return paintBodyColor;
+ }
+
+ protected Shape getComponentShape() {
+ Point position = getNode().getPosition();
+ RoundRectangle2D completeComponentBoundaryRect = new RoundRectangle2D.Float(position.x, position.y, this.dimension.width, this.dimension.height, DrawUtils.ARC_SIZE, DrawUtils.ARC_SIZE);
+ return completeComponentBoundaryRect;
+ }
+
+ protected String getComponentHeaderText() {
+ // XXX it's debatable if we should show the ID or the name.
+ // String headerText = this.node.getName();
+ String headerText = getNode().getID();
+ return headerText;
+ }
+
+ /**---------------------------------------------------------------------------------**/
+
+ protected void drawBody(Graphics2D g,
+ Shape shape, Color paintBodyColor) {
+ DrawUtils.initializeGraphics2D(g);
+ AffineTransform affineTransform = new AffineTransform();
+ affineTransform.translate(5,5);
+ Shape shadow = affineTransform.createTransformedShape(shape);
+ Composite oldComposite = g.getComposite();
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.65F));
+ g.setColor(Color.GRAY);
+ g.fill(shadow);
+ g.setComposite(oldComposite);
+ DrawUtils.gradientFillShape(g, getEndColor(paintBodyColor), paintBodyColor, shape);
+ }
+
+ protected void drawBreaks(Graphics2D g, Point position) {
+ if (getNode().isBreak()) {
+ DrawUtils.initializeGraphics2D(g);
+ g.setColor(BREAK_POINT_COLOR);
+ int r = this.headHeight / 4;
+ g.fillOval(position.x + this.dimension.width - 3 * r, position.y + r, 2 * r, 2 * r);
+ g.setColor(BREAK_POINT_BORDER_COLOR);
+ g.drawOval(position.x + this.dimension.width - 3 * r, position.y + r, 2 * r, 2 * r);
+ }
+ }
+
+ protected void drawExtras(Graphics2D g) {
+ DrawUtils.initializeGraphics2D(g);
+ for (Paintable paintable : this.paintables) {
+ paintable.paint(g, getNode().getPosition());
+ }
+ }
+
+ protected void drawPorts(Graphics2D g, Collection<? extends Port> ports) {
+ DrawUtils.initializeGraphics2D(g);
+ for (Port port : ports) {
+ NodeController.getGUI(port).paint(g);
+ }
+ }
+
+ protected void drawPorts(Graphics2D g, Node node) {
+ drawPorts(g, node.getAllPorts());
+ }
+
+ protected void drawEdge(Graphics2D g,
+ Shape completeComponentBoundaryShape, Color edgeColor) {
+ DrawUtils.initializeGraphics2D(g);
+ g.setColor(edgeColor);
+ //uncomment the commented lines to enable a double line edge
+// g.setStroke(new BasicStroke(4.0f));
+ g.draw(completeComponentBoundaryShape);
+// g.setColor(Color.white);
+// g.setStroke(new BasicStroke(3.0f));
+// g.draw(completeComponentBoundaryShape);
+ }
+ protected void drawHeader(Graphics2D g, Shape shape,
+ String headerText, Color headColor, boolean lowerBorderflat) {
+ drawHeader(g, shape, headerText, headColor, shape, lowerBorderflat);
+ }
+
+ protected void drawHeader(Graphics2D g, Shape shape,
+ String headerText, Color headColor) {
+ drawHeader(g, shape, headerText, headColor, true);
+ }
+
+ protected void drawHeader(Graphics2D g, Shape shape,
+ String headerText, Color headColor,
+ Shape headerDrawBoundaryShape) {
+ drawHeader(g, shape, headerText, headColor, headerDrawBoundaryShape, true);
+ }
+
+ protected void drawHeader(Graphics2D g, Shape shape,
+ String headerText, Color headColor,
+ Shape headerDrawBoundaryShape, boolean lowerBorderflat) {
+ DrawUtils.initializeGraphics2D(g);
+ if (lowerBorderflat) {
+ g.setColor(getEndColor(headColor));
+ Rectangle rect=new Rectangle((int) shape.getBounds().getX()+1, (int) (shape.getBounds()
+ .getY() + shape.getBounds().getHeight() - DrawUtils.ARC_SIZE),
+ (int) shape.getBounds().getWidth(), DrawUtils.ARC_SIZE);
+ DrawUtils.gradientFillShape(g, getEndColor(headColor), headColor, rect);
+ }
+ DrawUtils.gradientFillShape(g, getEndColor(headColor), headColor, headerDrawBoundaryShape);
+
+ // Text
+ g.setColor(TEXT_COLOR);
+ Font oldFont = g.getFont();
+ g.setFont(new Font(oldFont.getFontName(),Font.BOLD,oldFont.getSize()));
+ Rectangle2D bounds = g.getFontMetrics().getStringBounds(headerText, g);
+ g.drawString(headerText, (int)(shape.getBounds().getX() + (shape.getBounds().getWidth()-bounds.getWidth())/2),
+ (int)(shape.getBounds().getY() + (shape.getBounds().getHeight()+bounds.getHeight())/2));
+ g.setFont(oldFont);
+ }
+
+ /**
+ * Sets up the position of ports
+ */
+ protected void setPortPositions() {
+ // inputs
+ List<? extends Port> inputPorts = getNode().getInputPorts();
+ for (int i = 0; i < inputPorts.size(); i++) {
+ Port port = inputPorts.get(i);
+ Point offset = new Point(PortGUI.DATA_PORT_SIZE / 2, this.headHeight + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // outputs
+ List<? extends Port> outputPorts = getNode().getOutputPorts();
+ for (int i = 0; i < outputPorts.size(); i++) {
+ Port port = outputPorts.get(i);
+ // Use getBounds() instead of this.dimension because subclass might
+ // overwrite getBounds() to have different shape.
+ Point offset = new Point(this.getBounds().width - PortGUI.DATA_PORT_SIZE / 2, this.headHeight
+ + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // control-in
+ Port controlInPort = getNode().getControlInPort();
+ if (controlInPort != null) {
+ NodeController.getGUI(controlInPort).setOffset(new Point(0, 0));
+ }
+
+ // control-outs
+ for (Port controlOutPort : getNode().getControlOutPorts()) {
+ // By default, all ports will be drawn at the same place. Subclass
+ // should rearrange them if there are more than one control-out
+ // ports.
+ NodeController.getGUI(controlOutPort).setOffset(new Point(getBounds().width, getBounds().height));
+ }
+ }
+
+ /**
+ * @param workflowName
+ * @param state
+ */
+ public void setToken(String workflowName, NodeState state) {
+ List<DataPort> inputPorts = getNode().getInputPorts();
+ switch (state) {
+ case EXECUTING:
+
+ for (DataPort dataPort : inputPorts) {
+ NodeController.getGUI(((DataPort) dataPort.getFromPort())).removeToken(workflowName);
+ NodeController.getGUI(dataPort).addToken(workflowName);
+ }
+ break;
+ case FINISHED:
+ for (DataPort dataPort : inputPorts) {
+ NodeController.getGUI(dataPort).removeToken(workflowName);
+ }
+
+ List<DataPort> outputPorts = getNode().getOutputPorts();
+ for (DataPort dataPort : outputPorts) {
+ NodeController.getGUI(dataPort).addToken(workflowName);
+ }
+ break;
+ case FAILED:
+
+ break;
+
+ }
+
+ }
+
+ /**
+ *
+ */
+ public void resetTokens() {
+
+ List<DataPort> inputPorts = getNode().getInputPorts();
+ for (DataPort dataPort : inputPorts) {
+ NodeController.getGUI(dataPort).reset();
+ }
+ List<DataPort> outputPorts = getNode().getOutputPorts();
+ for (DataPort dataPort : outputPorts) {
+ NodeController.getGUI(dataPort).reset();
+ }
+ }
+
+ protected Color getEndColor(Color bodyColor){
+ return Color.white;
+ }
+
+ @Override
+ public void nodeUpdated(NodeUpdateType type) {
+ switch(type){
+ case STATE_CHANGED:
+ updateNodeColor();
+ break;
+ default:
+ break;
+ }
+
+ }
+
+ private void updateNodeColor() {
+ switch(node.getState()){
+ case WAITING:
+ setBodyColor(NodeState.DEFAULT.color); break;
+ case EXECUTING:
+ setBodyColor(NodeState.EXECUTING.color); break;
+ case FAILED:
+ setBodyColor(NodeState.FAILED.color); break;
+ case FINISHED:
+ setBodyColor(NodeState.FINISHED.color); break;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/Paintable.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/Paintable.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/Paintable.java
new file mode 100644
index 0000000..ce8c8fb
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/Paintable.java
@@ -0,0 +1,35 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph;
+
+import java.awt.Graphics2D;
+import java.awt.Point;
+
+public interface Paintable {
+
+ /**
+ * @param graphics
+ * @param point
+ * The position of the object.
+ */
+ public void paint(Graphics2D graphics, Point point);
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/PortGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/PortGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/PortGUI.java
new file mode 100644
index 0000000..1efdbe7
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/PortGUI.java
@@ -0,0 +1,274 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Shape;
+import java.awt.event.MouseEvent;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.Port.Kind;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public class PortGUI implements GraphPieceGUI {
+
+ /**
+ * The size of the port (diameter of the triangle)
+ */
+ public static final int DATA_PORT_SIZE = 10;
+
+ /**
+ * CONTROL_PORT_SIZE
+ */
+ public static final int CONTROL_PORT_SIZE = 6;
+
+ private static final Color DATA_IN_COLOR = Color.BLUE;
+
+ private static final Color DATA_OUT_COLOR = Color.GREEN;
+
+ private static final Color CONTROL_IN_COLOR = Color.RED;
+
+ private static final Color CONTROL_OUT_COLOR = Color.RED;
+
+ private static final Color EPR_COLOR = Color.GREEN;
+
+ private static final Color SELECTED_COLOR = Color.PINK;
+
+ protected static final Color TEXT_COLOR = Color.black;
+
+ private static final int TOKEN_SIZE = 22;
+
+ private static final Color TOKEN_COLOR = Color.GREEN;
+
+ private List<String> tokens = new LinkedList<String>();
+
+ private Port port;
+
+ private String portText=null;
+
+ /**
+ * The position of this port relative to the node this port belongs to.
+ */
+ private Point offset;
+
+ private boolean selected = false;
+
+ /**
+ * @param port
+ */
+ public PortGUI(Port port) {
+ this.port = port;
+ this.offset = new Point(); // To avoid null check.
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.GraphPieceGUI#mouseClicked(java.awt.event.MouseEvent,
+ * org.apache.airavata.xbaya.XBayaEngine)
+ */
+ public void mouseClicked(MouseEvent event, XBayaEngine engine) {
+ // Nothing
+ }
+
+ /**
+ * @param g
+ */
+ public void paint(Graphics2D g) {
+
+ Kind kind = this.port.getKind();
+ Color color = null;
+ switch (kind) {
+ case DATA_IN:
+ color = this.selected ? SELECTED_COLOR : DATA_IN_COLOR;
+ break;
+ case DATA_OUT:
+ color = this.selected ? SELECTED_COLOR : DATA_OUT_COLOR;
+ break;
+ case CONTROL_IN:
+ color = this.selected ? SELECTED_COLOR : CONTROL_IN_COLOR;
+ break;
+ case CONTROL_OUT:
+ color = this.selected ? SELECTED_COLOR : CONTROL_OUT_COLOR;
+ break;
+ case EPR:
+ color = this.selected ? SELECTED_COLOR : EPR_COLOR;
+ break;
+ }
+
+ Point point = getPosition();
+ Shape shape = null;
+ switch (kind) {
+ case DATA_IN:
+
+ shape = drawPortArrow(point);
+ int count = 0;
+ String[] tokenArray = new String[this.tokens.size()];
+ this.tokens.toArray(tokenArray);
+ for (String token : tokenArray) {
+ g.setColor(TOKEN_COLOR);
+ g.fill(new Ellipse2D.Double(point.x + TOKEN_SIZE /* +count*5 */, point.y + TOKEN_SIZE * count,
+ TOKEN_SIZE, TOKEN_SIZE / 2));
+ g.setColor(TEXT_COLOR);
+ g.drawString(token, point.x + TOKEN_SIZE * 3 /* +count*5 */, point.y + TOKEN_SIZE * count);
+
+ ++count;
+ }
+
+ break;
+ case DATA_OUT:
+ shape = drawPortArrow(point);
+ count = 0;
+ tokenArray = new String[this.tokens.size()];
+ this.tokens.toArray(tokenArray);
+ for (String token : tokenArray) {
+ g.setColor(TOKEN_COLOR);
+ g.fill(new Ellipse2D.Double(point.x + 5 /* +count*5 */, point.y + TOKEN_SIZE * count, TOKEN_SIZE,
+ TOKEN_SIZE / 2));
+ g.setColor(TEXT_COLOR);
+ g.drawString(token, point.x + TOKEN_SIZE + 10 /* +count*0 */, point.y + TOKEN_SIZE * count);
+
+ ++count;
+ }
+ break;
+ case CONTROL_IN:
+ case CONTROL_OUT:
+ shape = new Ellipse2D.Double(point.x - CONTROL_PORT_SIZE / 2, point.y - CONTROL_PORT_SIZE / 2,
+ CONTROL_PORT_SIZE, CONTROL_PORT_SIZE);
+ break;
+ case EPR:
+ shape = new Ellipse2D.Double(point.x - CONTROL_PORT_SIZE / 2, point.y - CONTROL_PORT_SIZE / 2,
+ CONTROL_PORT_SIZE, CONTROL_PORT_SIZE);
+ break;
+ }
+ DrawUtils.gradientFillShape(g, color.brighter().brighter().brighter().brighter(), color.darker(), shape);
+ if (getPortText()!=null){
+ g.setColor(Color.WHITE);
+ Font oldFont = g.getFont();
+ g.setFont(new Font(oldFont.getFontName(),Font.BOLD,7));
+ Rectangle2D bounds = g.getFontMetrics().getStringBounds(getPortText(), g);
+ g.drawString(getPortText(), (int)(shape.getBounds().getX() + (shape.getBounds().getWidth()-bounds.getWidth())*2/4),
+ (int)(shape.getBounds().getY() + (shape.getBounds().getHeight()+bounds.getHeight())*4/8));
+ g.setFont(oldFont);
+ }
+ }
+
+ /**
+ * @param point
+ * @return
+ */
+ private Shape drawPortArrow(Point point) {
+ Shape shape;
+ Polygon triangle = new Polygon();
+ triangle.addPoint(point.x - DATA_PORT_SIZE / 2, point.y - DATA_PORT_SIZE / 2);
+ triangle.addPoint(point.x + DATA_PORT_SIZE / 2, point.y);
+ triangle.addPoint(point.x - DATA_PORT_SIZE / 2, point.y + DATA_PORT_SIZE / 2);
+// shape = DrawUtils.getRoundedShape(triangle);
+ shape = triangle;
+ return shape;
+ }
+
+ /**
+ * @param offset
+ */
+ public void setOffset(Point offset) {
+ this.offset = offset;
+ }
+
+ /**
+ * @return the absolute position of the port
+ */
+ public Point getPosition() {
+ Point nodePosition = this.port.getNode().getPosition();
+ int offsetX=this.offset.x;
+// if ((PortGUI.DATA_PORT_SIZE / 2) + 1 < this.offset.x){
+// offsetX=this.offset.x+(PortGUI.DATA_PORT_SIZE / 2);
+// }else{
+// offsetX=0;
+// }
+ return new Point(nodePosition.x + offsetX, nodePosition.y + this.offset.y);
+ }
+
+ /**
+ * @param bool
+ */
+ protected void setSelectedFlag(boolean bool) {
+ this.selected = bool;
+ }
+
+ /**
+ * @param workflowName
+ */
+ public void removeToken(String workflowName) {
+ int count = -1;
+ for (String key : this.tokens) {
+ count++;
+ if (workflowName.equals(key)) {
+ break;
+ }
+ }
+ if (count != -1) {
+ this.tokens.remove(count);
+ }
+
+ }
+
+ /**
+ * @param workflowName
+ */
+ public void addToken(String workflowName) {
+ boolean found = false;
+ for (String key : this.tokens) {
+ if (workflowName.equals(key)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ this.tokens.add(workflowName);
+ }
+
+ }
+
+ /**
+ *
+ */
+ public void reset() {
+ this.tokens.clear();
+
+ }
+
+ public String getPortText() {
+ return portText;
+ }
+
+ public void setPortText(String portText) {
+ this.portText = portText;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/InstanceNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/InstanceNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/InstanceNodeGUI.java
new file mode 100644
index 0000000..b2647ac
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/InstanceNodeGUI.java
@@ -0,0 +1,166 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.amazon;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
+import java.awt.geom.RoundRectangle2D;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.amazon.InstanceNode;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.dialogs.graph.amazon.InstanceConfigurationDialog;
+import org.apache.airavata.xbaya.ui.graph.PortGUI;
+import org.apache.airavata.xbaya.ui.graph.system.ConfigurableNodeGUI;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public class InstanceNodeGUI extends ConfigurableNodeGUI {
+
+ private InstanceNode node;
+
+ private Polygon polygon;
+
+ private GeneralPath generalPath;
+
+ private InstanceConfigurationDialog configDialog;
+
+ /**
+ * Constructs a InstanceNodeGUI.
+ *
+ * @param node
+ */
+ public InstanceNodeGUI(InstanceNode node) {
+ super(node);
+ this.node = node;
+ this.polygon = new Polygon();
+ generalPath = new GeneralPath();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.system.ConfigurableNodeGUI#showConfigurationDialog(org.apache.airavata.xbaya.XBayaEngine)
+ */
+ @Override
+ protected void showConfigurationDialog(XBayaGUI xbayaGUI) {
+ if (this.configDialog == null) {
+ this.configDialog = new InstanceConfigurationDialog(this.node, xbayaGUI);
+ }
+ this.configDialog.show();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.system.ConfigurableNodeGUI#calculatePositions(java.awt.Graphics)
+ */
+ @Override
+ protected void calculatePositions(Graphics g) {
+ super.calculatePositions(g);
+ calculatePositions();
+ setPortPositions();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#getBounds()
+ */
+ @Override
+ protected Rectangle getBounds() {
+ return this.getComponentShape().getBounds();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#isIn(java.awt.Point)
+ */
+ @Override
+ protected boolean isIn(Point point) {
+ return this.polygon.contains(point);
+ }
+
+ protected Color getComponentHeaderColor() {
+ return this.headColor;
+ }
+
+ protected String getComponentHeaderText() {
+ return this.node.getName();
+ }
+
+ protected GeneralPath getComponentShape() {
+ return generalPath;
+ }
+
+ protected RoundRectangle2D getComponentHeaderShape() {
+ RoundRectangle2D componentHeaderBoundaryRect = new RoundRectangle2D.Double(getPosition().x, getPosition().y, this.dimension.width, this.headHeight, DrawUtils.ARC_SIZE,DrawUtils.ARC_SIZE);
+ return componentHeaderBoundaryRect;
+ }
+
+ protected Node getNode() {
+ return this.node;
+ }
+
+ /**
+ * Sets up the position of ports
+ */
+ @Override
+ protected void setPortPositions() {
+ // inputs
+ List<? extends Port> inputPorts = this.node.getInputPorts();
+ for (int i = 0; i < inputPorts.size(); i++) {
+ Port port = inputPorts.get(i);
+ Point offset = new Point(PortGUI.DATA_PORT_SIZE / 2, this.headHeight + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // outputs
+ List<? extends Port> outputPorts = this.node.getOutputPorts();
+ for (int i = 0; i < outputPorts.size(); i++) {
+ Port port = outputPorts.get(i);
+ // Use getBounds() instead of this.dimension because subclass might
+ // overwrite getBounds() to have different shape.
+ Point offset = new Point(this.getBounds().width - PortGUI.DATA_PORT_SIZE / 2, this.headHeight
+ + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // control out port
+ List<? extends Port> controlOutPorts = this.node.getControlOutPorts();
+ Port controlOutPort1 = controlOutPorts.get(0);
+ Point offset = new Point(getBounds().width / 2, getBounds().height);
+ NodeController.getGUI(controlOutPort1).setOffset(offset);
+ }
+
+ private void calculatePositions() {
+ // Avoid instantiating a new polygon each time.
+ this.polygon.reset();
+ Point position = getPosition();
+ this.polygon.addPoint(position.x, position.y);
+ this.polygon.addPoint(position.x, position.y + this.dimension.height);
+ this.polygon.addPoint(position.x + this.dimension.width / 2, position.y + this.dimension.height
+ + this.headHeight);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.dimension.height);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y);
+ DrawUtils.setupRoundedGeneralPath(polygon, getComponentShape());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/TerminateInstanceNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/TerminateInstanceNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/TerminateInstanceNodeGUI.java
new file mode 100644
index 0000000..74128da
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/amazon/TerminateInstanceNodeGUI.java
@@ -0,0 +1,160 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.amazon;
+
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.amazon.TerminateInstanceNode;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.graph.NodeGUI;
+import org.apache.airavata.xbaya.ui.graph.PortGUI;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public class TerminateInstanceNodeGUI extends NodeGUI {
+
+ private TerminateInstanceNode node;
+
+ private Polygon polygon;
+
+ private GeneralPath generalPath;
+
+ /**
+ * Constructs a InstanceNodeGUI.
+ *
+ * @param node
+ */
+ public TerminateInstanceNodeGUI(TerminateInstanceNode node) {
+ super(node);
+ this.node = node;
+ this.polygon = new Polygon();
+ generalPath = new GeneralPath();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.system.ConfigurableNodeGUI#calculatePositions(java.awt.Graphics)
+ */
+ @Override
+ protected void calculatePositions(Graphics g) {
+ super.calculatePositions(g);
+ calculatePositions();
+ setPortPositions();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#getBounds()
+ */
+ @Override
+ protected Rectangle getBounds() {
+ return this.polygon.getBounds();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#isIn(java.awt.Point)
+ */
+ @Override
+ protected boolean isIn(Point point) {
+ return this.polygon.contains(point);
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.system.ConfigurableNodeGUI#paint(java.awt.Graphics2D)
+ */
+ @Override
+ protected void paint(Graphics2D g) {
+ Point position = getPosition();
+
+ // Draws the body.
+ if (this.dragged) {
+ g.setColor(DRAGGED_BODY_COLOR);
+ } else {
+ g.setColor(this.bodyColor);
+ }
+ drawBody(g, generalPath, g.getColor());
+
+ // Draws the head.
+ Polygon head = createHeader(position);
+ drawHeader(g, DrawUtils.getRoundedShape(head), node.getName(), headColor);
+
+ // Edge
+ drawEdge(g, generalPath, EDGE_COLOR);
+
+ // Paint all ports
+ drawPorts(g, node);
+ }
+
+ private Polygon createHeader(Point position) {
+ Polygon head = new Polygon();
+ head.addPoint(position.x, position.y);
+ head.addPoint(position.x, position.y + this.headHeight);
+ head.addPoint(position.x + this.dimension.width, position.y + this.headHeight);
+ head.addPoint(position.x + this.dimension.width, position.y + this.headHeight / 2);
+ return head;
+ }
+
+ /**
+ * Sets up the position of ports
+ */
+ @Override
+ protected void setPortPositions() {
+ // inputs
+ List<? extends Port> inputPorts = this.node.getInputPorts();
+ for (int i = 0; i < inputPorts.size(); i++) {
+ Port port = inputPorts.get(i);
+ Point offset = new Point(PortGUI.DATA_PORT_SIZE / 2, this.headHeight + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // outputs
+ List<? extends Port> outputPorts = this.node.getOutputPorts();
+ for (int i = 0; i < outputPorts.size(); i++) {
+ Port port = outputPorts.get(i);
+ // Use getBounds() instead of this.dimension because subclass might
+ // overwrite getBounds() to have different shape.
+ Point offset = new Point(this.getBounds().width - PortGUI.DATA_PORT_SIZE / 2, this.headHeight
+ + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // control in port
+ Port controlInPort = this.node.getControlInPort();
+ NodeController.getGUI(controlInPort).setOffset(new Point(0, 0));
+ }
+
+ private void calculatePositions() {
+ // Avoid instantiating a new polygon each time.
+ this.polygon.reset();
+ Point position = getPosition();
+ this.polygon.addPoint(position.x, position.y);
+ this.polygon.addPoint(position.x, position.y + this.dimension.height + this.headHeight / 2);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.dimension.height + this.headHeight
+ / 2);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.headHeight / 2);
+ DrawUtils.setupRoundedGeneralPath(polygon, generalPath);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/dynamic/DynamicNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/dynamic/DynamicNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/dynamic/DynamicNodeGUI.java
new file mode 100644
index 0000000..4229ba7
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/dynamic/DynamicNodeGUI.java
@@ -0,0 +1,73 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.dynamic;
+
+import java.awt.event.MouseEvent;
+
+import org.apache.airavata.workflow.model.graph.dynamic.DynamicNode;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.ui.dialogs.graph.dynamic.DynamicNodeWindow;
+import org.apache.airavata.xbaya.ui.graph.NodeGUI;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class DynamicNodeGUI extends NodeGUI {
+
+ private final static Logger logger = LoggerFactory.getLogger(DynamicNodeGUI.class);
+
+ private DynamicNode node;
+
+ private DynamicNodeWindow window;
+
+ /**
+ * Creates a WsNodeGui
+ *
+ * @param node
+ */
+ public DynamicNodeGUI(DynamicNode node) {
+ super(node);
+ this.node = node;
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.GraphPieceGUI#mouseClicked(java.awt.event.MouseEvent,
+ * org.apache.airavata.xbaya.XBayaEngine)
+ */
+ @Override
+ public void mouseClicked(MouseEvent event, XBayaEngine engine) {
+ logger.debug(event.toString());
+ if (event.getClickCount() >= 2) {
+ showWindow(engine);
+ }
+ }
+
+ private void showWindow(XBayaEngine engine) {
+ if (this.window == null) {
+ this.window = new DynamicNodeWindow(engine, this.node);
+ }
+ try {
+ this.window.show();
+ } catch (Throwable e) {
+ engine.getGUI().getErrorWindow().error(e);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/subworkflow/SubWorkflowNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/subworkflow/SubWorkflowNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/subworkflow/SubWorkflowNodeGUI.java
new file mode 100644
index 0000000..4ad9796
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/subworkflow/SubWorkflowNodeGUI.java
@@ -0,0 +1,89 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.subworkflow;
+
+import java.awt.Color;
+import java.awt.event.MouseEvent;
+
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.subworkflow.SubWorkflowNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.graph.NodeGUI;
+import org.apache.airavata.xbaya.ui.utils.ErrorMessages;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SubWorkflowNodeGUI extends NodeGUI {
+
+ private final static Logger logger = LoggerFactory.getLogger(SubWorkflowNodeGUI.class);
+
+ private SubWorkflowNode node;
+
+ private static final Color HEAD_COLOR = new Color(138, 43, 226);
+
+ /**
+ * Constructs a SubWorkflowNodeGUI.
+ *
+ * @param node
+ */
+ public SubWorkflowNodeGUI(SubWorkflowNode node) {
+ super(node);
+ this.node = node;
+ this.setHeadColor(HEAD_COLOR);
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.GraphPieceGUI#mouseClicked(java.awt.event.MouseEvent,
+ * org.apache.airavata.xbaya.XBayaEngine)
+ */
+ @Override
+ public void mouseClicked(MouseEvent event, XBayaEngine engine) {
+ logger.debug(event.toString());
+ if (event.getClickCount() >= 2) {
+ openWorkflowTab(engine.getGUI());
+ }
+ }
+
+ protected void setSelectedFlag(boolean flag) {
+ this.selected = flag;
+ if (this.selected) {
+ this.headColor = SELECTED_HEAD_COLOR;
+ } else {
+ this.headColor = HEAD_COLOR;
+ }
+ }
+
+ public void openWorkflowTab(XBayaGUI xbayaGUI) {
+ try {
+ Workflow workflow = this.node.getComponent().getWorkflow();
+ xbayaGUI.selectOrCreateGraphCanvas(workflow);
+ } catch (GraphException e) {
+ xbayaGUI.getErrorWindow().error(ErrorMessages.GRAPH_FORMAT_ERROR, e);
+ } catch (ComponentException e) {
+ xbayaGUI.getErrorWindow().error(ErrorMessages.COMPONENT_FORMAT_ERROR, e);
+ }
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/BlockNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/BlockNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/BlockNodeGUI.java
new file mode 100644
index 0000000..f7692f5
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/BlockNodeGUI.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.system.BlockNode;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.graph.NodeGUI;
+
+public class BlockNodeGUI extends NodeGUI {
+
+ private static final int HEIGHT = 100;
+
+ private BlockNode node;
+
+ /**
+ * @param node
+ */
+ public BlockNodeGUI(BlockNode node) {
+ super(node);
+ this.node = node;
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#calculatePositions(java.awt.Graphics)
+ */
+ @Override
+ protected void calculatePositions(Graphics g) {
+ FontMetrics fm = g.getFontMetrics();
+ this.headHeight = fm.getHeight() + TEXT_GAP_Y * 2;
+
+ this.dimension.height = this.headHeight + PORT_INITIAL_GAP + HEIGHT;
+ this.dimension.width = fm.stringWidth(this.node.getID() + TEXT_GAP_X * 2);
+
+ /* Calculates the position of ports */
+ setPortPositions();
+ }
+
+ /**
+ * Sets up the position of ports
+ */
+ @Override
+ protected void setPortPositions() {
+ // No input ports
+
+ Port controlInPort = this.node.getControlInPort();
+ if (controlInPort != null) {
+ NodeController.getGUI(controlInPort).setOffset(new Point(0, 0));
+ }
+
+ // There are two controlOutPorts.
+ List<? extends Port> controlOutPorts = this.node.getControlOutPorts();
+ Port controlOutPort1 = controlOutPorts.get(0);
+ Point offset = new Point(getBounds().width, +getBounds().height / 2);
+ NodeController.getGUI(controlOutPort1).setOffset(offset);
+
+ Port controlOutPort2 = controlOutPorts.get(1);
+ offset = new Point(this.getBounds().width, getBounds().height);
+ NodeController.getGUI(controlOutPort2).setOffset(offset);
+
+ // No outputs
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConfigurableNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConfigurableNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConfigurableNodeGUI.java
new file mode 100644
index 0000000..9601f56
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConfigurableNodeGUI.java
@@ -0,0 +1,140 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import java.awt.Color;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import java.awt.geom.Rectangle2D;
+import java.awt.geom.RoundRectangle2D;
+
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.graph.NodeGUI;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public abstract class ConfigurableNodeGUI extends NodeGUI {
+
+ protected static final Color CONFIG_AREA_COLOR = new Color(220, 220, 220);
+
+ protected static final String DEFAULT_CONFIG_AREA_TEXT = "Config";
+
+ protected static final int CONFIG_AREA_GAP_X = 20;
+
+ protected String configurationText;
+
+ protected RoundRectangle2D configurationArea;
+
+ /**
+ * @param node
+ */
+ public ConfigurableNodeGUI(NodeImpl node) {
+ super(node);
+ this.configurationText = DEFAULT_CONFIG_AREA_TEXT;
+// this.configurationArea = new RoundRectangle2D();
+
+ }
+
+ /**
+ * Sets the text shown on the configuration area.
+ *
+ * @param text
+ * The text to set
+ */
+ public void setConfigurationText(String text) {
+ this.configurationText = text;
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.GraphPieceGUI#mouseClicked(java.awt.event.MouseEvent,
+ * org.apache.airavata.xbaya.XBayaEngine)
+ */
+ @Override
+ public void mouseClicked(MouseEvent event, XBayaEngine engine) {
+ if (isInConfig(event.getPoint())) {
+ showConfigurationDialog(engine.getGUI());
+ }
+ }
+
+ /**
+ * @param engine
+ */
+ protected abstract void showConfigurationDialog(XBayaGUI xbayaGUI);
+
+ /**
+ * Checks if a user's click is to select the configuration
+ *
+ * @param point
+ * @return true if the user's click is to select the node, false otherwise
+ */
+ @Override
+ protected boolean isInConfig(Point point) {
+ return this.configurationArea.contains(point);
+ }
+
+ @Override
+ protected void calculatePositions(Graphics g) {
+ super.calculatePositions(g);
+
+ Point position = this.node.getPosition();
+ FontMetrics fm = g.getFontMetrics();
+
+ int h = fm.getHeight() + TEXT_GAP_Y * 2+1;
+ int w = this.dimension.width - CONFIG_AREA_GAP_X * 2;
+ int x = position.x + CONFIG_AREA_GAP_X;
+ int y = position.y
+ + this.headHeight
+ + (this.dimension.height - this.headHeight - h)
+ / 2;
+ this.configurationArea=new RoundRectangle2D.Float(x,y,w,h,DrawUtils.ARC_SIZE, DrawUtils.ARC_SIZE);
+ }
+
+ /**
+ * Paints the config area
+ *
+ * @param g
+ */
+ @Override
+ protected final void paint(Graphics2D g) {
+ super.paint(g);
+ drawComponentConfiguration(g);
+ }
+
+ /**
+ * @param g
+ */
+ protected void drawComponentConfiguration(Graphics2D g) {
+ String s = this.configurationText;
+ g.setColor(CONFIG_AREA_COLOR);
+ g.fill(this.configurationArea);
+ g.setColor(TEXT_COLOR);
+ Rectangle2D bounds = g.getFontMetrics().getStringBounds(s, g);
+
+ g.drawString(s,
+ (int)(this.configurationArea.getX() + (this.configurationArea.getWidth()-bounds.getWidth())/2),
+ (int)(this.configurationArea.getY() + (this.configurationArea.getHeight()+bounds.getHeight()/2)/2));
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConstantNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConstantNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConstantNodeGUI.java
new file mode 100644
index 0000000..5f45161
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/ConstantNodeGUI.java
@@ -0,0 +1,63 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import org.apache.airavata.workflow.model.graph.system.ConstantNode;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.dialogs.graph.system.ConstantConfigurationDialog;
+import org.apache.airavata.xbaya.ui.utils.ErrorMessages;
+
+public class ConstantNodeGUI extends ConfigurableNodeGUI {
+
+ private static final String CONFIG_AREA_STRING = "Value";
+
+ private ConstantNode node;
+
+ private ConstantConfigurationDialog configurationWindow;
+
+ /**
+ * @param node
+ */
+ public ConstantNodeGUI(ConstantNode node) {
+ super(node);
+ this.node = node;
+ setConfigurationText(CONFIG_AREA_STRING);
+ }
+
+ /**
+ * Shows a configuration window when a user click the configuration area.
+ *
+ * @param engine
+ */
+ @Override
+ protected void showConfigurationDialog(XBayaGUI xbayaGUI) {
+ if (this.node.isConnected()) {
+ if (this.configurationWindow == null) {
+ this.configurationWindow = new ConstantConfigurationDialog(this.node, xbayaGUI);
+ }
+ this.configurationWindow.show();
+
+ } else {
+ xbayaGUI.getErrorWindow().info(ErrorMessages.CONSTANT_NOT_CONNECTED_WARNING);
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputHandler.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputHandler.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputHandler.java
new file mode 100644
index 0000000..ad1e673
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputHandler.java
@@ -0,0 +1,87 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.system.DifferedInputNode;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+
+public class DifferedInputHandler {
+
+
+ public static void handleDifferredInputsofDependentNodes(Node node, final XBayaGUI xbayaGUI){
+ List<DataPort> inputPorts = node.getInputPorts();
+ for (DataPort dataPort : inputPorts) {
+ Node fromNode = dataPort.getFromNode();
+ if(isDifferedInputNode(fromNode)){
+ final DifferedInputNode differedInputNode = (DifferedInputNode)fromNode;
+ if(!differedInputNode.isConfigured()){
+ //not configured differed node this is what we are looking for
+ //set the flag and ensure all the rest is finished
+ Runnable task = new Runnable() {
+
+ @Override
+ public void run() {
+ ((DifferedInputNodeGUI)NodeController.getGUI(differedInputNode)).showConfigurationDialog(xbayaGUI);
+ }
+ };
+ new Thread(task).start();
+
+
+
+ }
+ }
+ }
+ }
+
+
+
+ public static boolean onlyWaitingOnIncompleteDifferedInputNode(Node node){
+ List<DataPort> inputPorts = node.getInputPorts();
+ boolean atleadOneDifferedInputNodeIsIncomplete = false;
+ for (DataPort dataPort : inputPorts) {
+ Node fromNode = dataPort.getFromNode();
+ if(NodeController.isFinished(fromNode)){
+ //no op
+ }else if(isDifferedInputNode(fromNode)){
+ //not finished
+ if(!((DifferedInputNode)node).isConfigured()){
+ //not configured differed node this is what we are looking for
+ //set the flag and ensure all the rest is finished
+ atleadOneDifferedInputNodeIsIncomplete = true;
+ }
+ }else{
+ //there is a not finished non differed input node
+ return false;
+ }
+ }
+ //if not finished nodes were found we wil not be here so
+ return atleadOneDifferedInputNodeIsIncomplete;
+ }
+ public static boolean isDifferedInputNode(Node node){
+ return node instanceof DifferedInputNode;
+ }
+
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputNodeGUI.java
new file mode 100644
index 0000000..e0571fc
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DifferedInputNodeGUI.java
@@ -0,0 +1,101 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import java.awt.Color;
+
+import org.apache.airavata.workflow.model.graph.system.DifferedInputNode;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.dialogs.graph.system.DifferedInputConfigurationDialog;
+import org.apache.airavata.xbaya.ui.utils.ErrorMessages;
+
+public class DifferedInputNodeGUI extends ConfigurableNodeGUI {
+
+ // private static final MLogger logger = MLogger.getLogger();
+
+ private static final String CONFIG_AREA_STRING = "Config";
+
+ private static final Color HEAD_COLOR = new Color(153, 204, 255);
+
+ private DifferedInputNode inputNode;
+
+ private DifferedInputConfigurationDialog configurationWindow;
+
+ private volatile boolean configCanBeDisplayed = true;
+
+ /**
+ * @param node
+ */
+ public DifferedInputNodeGUI(DifferedInputNode node) {
+ super(node);
+ this.inputNode = node;
+ setConfigurationText(CONFIG_AREA_STRING);
+ this.headColor = HEAD_COLOR;
+ }
+
+ /**
+ * Shows a configuration window when a user click the configuration area.
+ *
+ * @param engine
+ */
+ @Override
+ public void showConfigurationDialog(XBayaGUI xbayaGUI) {
+ if (testAndSetConfigDisplay()) {
+ if (this.inputNode.isConnected()) {
+ if (this.configurationWindow == null) {
+ this.configurationWindow = new DifferedInputConfigurationDialog(
+ this.inputNode, xbayaGUI);
+ }
+ this.configurationWindow.show();
+
+ } else {
+ xbayaGUI.getErrorWindow().info(
+ ErrorMessages.INPUT_NOT_CONNECTED_WARNING);
+ }
+ }
+ }
+
+ protected synchronized boolean testAndSetConfigDisplay() {
+ if (this.configCanBeDisplayed) {
+ this.configCanBeDisplayed = false;
+ return true;
+ }
+ return false;
+ }
+
+ public synchronized void closingDisplay() {
+ this.configCanBeDisplayed = true;
+ }
+
+ public DifferedInputNode getInputNode() {
+ return this.inputNode;
+ }
+
+ @Override
+ protected void setSelectedFlag(boolean flag) {
+ this.selected = flag;
+ if (this.selected) {
+ this.headColor = SELECTED_HEAD_COLOR;
+ } else {
+ this.headColor = HEAD_COLOR;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DoWhileNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DoWhileNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DoWhileNodeGUI.java
new file mode 100644
index 0000000..e4c94f7
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/DoWhileNodeGUI.java
@@ -0,0 +1,191 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.impl.PortImpl;
+import org.apache.airavata.workflow.model.graph.system.DoWhileNode;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.dialogs.graph.system.DoWhileConfigrationDialog;
+import org.apache.airavata.xbaya.ui.graph.PortGUI;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public class DoWhileNodeGUI extends ConfigurableNodeGUI {
+
+ private static final String CONFIG_AREA_STRING = "Config";
+
+ private DoWhileNode node;
+
+ private DoWhileConfigrationDialog configurationWindow;
+
+ private Polygon polygon;
+
+ private GeneralPath generalPath;
+
+ /**
+ * Constructs a DoWhileNodeGUI.
+ *
+ * @param node
+ */
+ public DoWhileNodeGUI(DoWhileNode node) {
+ super(node);
+ this.node = node;
+ setConfigurationText(CONFIG_AREA_STRING);
+ this.polygon = new Polygon();
+ generalPath = new GeneralPath();
+ }
+
+ /**
+ * Shows a configuration window when a user click the configuration area.
+ *
+ * @param engine
+ */
+ @Override
+ protected void showConfigurationDialog(XBayaGUI xbayaGUI) {
+ if (this.configurationWindow == null) {
+ this.configurationWindow = new DoWhileConfigrationDialog(this.node, xbayaGUI);
+ }
+ this.configurationWindow.show();
+ }
+
+
+ /**
+ * @see edu.indiana.extreme.xbaya.graph.system.gui.ConfigurableNodeGUI#calculatePositions(java.awt.Graphics)
+ */
+ @Override
+ protected void calculatePositions(Graphics g) {
+ super.calculatePositions(g);
+ calculatePositions();
+ setPortPositions();
+ }
+
+ /**
+ * @see edu.indiana.extreme.xbaya.graph.gui.NodeGUI#getBounds()
+ */
+ @Override
+ protected Rectangle getBounds() {
+ return this.polygon.getBounds();
+ }
+
+ /**
+ * @see edu.indiana.extreme.xbaya.graph.gui.NodeGUI#isIn(java.awt.Point)
+ */
+ @Override
+ protected boolean isIn(Point point) {
+ return this.polygon.contains(point);
+ }
+
+ protected GeneralPath getComponentHeaderShape() {
+ return DrawUtils.getRoundedShape(createHeader(getPosition()));
+ }
+
+ protected String getComponentHeaderText() {
+ return node.getName();
+ }
+
+ protected Color getComponentHeaderColor() {
+ return headColor;
+ }
+
+ protected GeneralPath getComponentShape() {
+ return generalPath;
+ }
+
+ protected Node getNode() {
+ return this.node;
+ }
+
+ private Polygon createHeader(Point position) {
+ Polygon head = new Polygon();
+ head.addPoint(position.x, position.y + this.headHeight / 2);
+ head.addPoint(position.x, position.y + this.headHeight);
+ head.addPoint(position.x + this.dimension.width, position.y + this.headHeight);
+ head.addPoint(position.x + this.dimension.width, position.y + this.headHeight / 2);
+ head.addPoint(position.x + this.dimension.width / 2, position.y);
+ return head;
+ }
+
+ /**
+ * Sets up the position of ports
+ */
+ @Override
+ protected void setPortPositions() {
+ List<? extends Port> inputPorts = this.node.getInputPorts();
+ for (int i = 0; i < inputPorts.size(); i++) {
+ Port port = inputPorts.get(i);
+ Point offset = new Point(PortGUI.DATA_PORT_SIZE / 2, this.headHeight + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // outputs
+ List<? extends Port> outputPorts = this.node.getOutputPorts();
+ for (int i = 0; i < outputPorts.size(); i++) {
+ Port port = outputPorts.get(i);
+ // Use getBounds() instead of this.dimension because subclass might
+ // overwrite getBounds() to have different shape.
+ Point offset = new Point(this.getBounds().width
+ - PortGUI.DATA_PORT_SIZE / 2, this.headHeight
+ + PORT_INITIAL_GAP + PORT_GAP * i);
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ PortImpl controlInPort = this.node.getControlInPort();
+ if (controlInPort != null) {
+ Point offset = new Point(0, this.headHeight / 2);
+ NodeController.getGUI(controlInPort).setOffset(offset);
+ }
+
+ // There are two controlOutPorts.
+ List<? extends Port> controlOutPorts = this.node.getControlOutPorts();
+ Port controlOutPort1 = controlOutPorts.get(0);
+ Point offset = new Point(getBounds().width, +this.headHeight / 2);
+ NodeController.getGUI(controlOutPort1).setOffset(offset);
+
+ Port controlOutPort2 = controlOutPorts.get(1);
+ offset = new Point(this.getBounds().width, getBounds().height - this.headHeight / 2);
+ NodeController.getGUI(controlOutPort2).setOffset(offset);
+ }
+
+ private void calculatePositions() {
+ // Avoid instantiating a new polygon each time.
+ this.polygon.reset();
+ Point position = getPosition();
+ this.polygon.addPoint(position.x, position.y + this.headHeight / 2);
+ this.polygon.addPoint(position.x, position.y + this.dimension.height);
+ this.polygon.addPoint(position.x + this.dimension.width / 2, position.y + this.dimension.height
+ + this.headHeight / 2);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.dimension.height);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.headHeight / 2);
+ this.polygon.addPoint(position.x + this.dimension.width / 2, position.y);
+ DrawUtils.setupRoundedGeneralPath(polygon, getComponentShape());
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata/blob/9c47eec8/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/EndBlockNodeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/EndBlockNodeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/EndBlockNodeGUI.java
new file mode 100644
index 0000000..b6d0e8b
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/system/EndBlockNodeGUI.java
@@ -0,0 +1,176 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.xbaya.ui.graph.system;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Polygon;
+import java.awt.Rectangle;
+import java.awt.geom.GeneralPath;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.system.EndBlockNode;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.XBayaGUI;
+import org.apache.airavata.xbaya.ui.dialogs.graph.system.EndBlockConfigurationDialog;
+import org.apache.airavata.xbaya.ui.graph.PortGUI;
+import org.apache.airavata.xbaya.ui.utils.DrawUtils;
+
+public class EndBlockNodeGUI extends ConfigurableNodeGUI {
+
+ private EndBlockConfigurationDialog configurationWindow;
+
+ private EndBlockNode node;
+
+ private Polygon polygon;
+
+ private GeneralPath generalPath;
+
+ /**
+ * @param node
+ */
+ public EndBlockNodeGUI(EndBlockNode node) {
+ super(node);
+ this.node = node;
+ this.polygon = new Polygon();
+ generalPath = new GeneralPath();
+ }
+
+ /**
+ * Shows a configuration window when a user click the configuration area.
+ *
+ * @param engine
+ */
+ @Override
+ protected void showConfigurationDialog(XBayaGUI xbayaGUI) {
+ if (this.configurationWindow == null) {
+ this.configurationWindow = new EndBlockConfigurationDialog(this.node, xbayaGUI);
+ }
+ this.configurationWindow.show();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#calculatePositions(java.awt.Graphics)
+ */
+ @Override
+ protected void calculatePositions(Graphics g) {
+ super.calculatePositions(g);
+ calculatePositions();
+ setPortPositions();
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#getBounds()
+ */
+ @Override
+ protected Rectangle getBounds() {
+ return this.polygon.getBounds();
+ }
+
+ @Override
+ protected boolean isIn(Point point) {
+ return this.polygon.contains(point);
+ }
+
+ protected GeneralPath getComponentHeaderShape() {
+ return DrawUtils.getRoundedShape(createHeader(getPosition()));
+ }
+
+ protected String getComponentHeaderText() {
+ return node.getName();
+ }
+
+ protected Color getComponentHeaderColor() {
+ return headColor;
+ }
+
+ protected GeneralPath getComponentShape() {
+ return generalPath;
+ }
+
+ protected Node getNode() {
+ return this.node;
+ }
+
+ protected Polygon createHeader(Point position) {
+ Polygon head = new Polygon();
+ head.addPoint(position.x, position.y);
+ head.addPoint(position.x, position.y + this.headHeight);
+ head.addPoint(position.x + this.dimension.width, position.y + this.headHeight);
+ head.addPoint(position.x + this.dimension.width, position.y + this.headHeight / 2);
+ return head;
+ }
+
+ /**
+ * @see org.apache.airavata.xbaya.ui.graph.NodeGUI#setPortPositions()
+ */
+ @Override
+ protected void setPortPositions() {
+ // inputs
+ List<? extends Port> inputPorts = this.node.getInputPorts();
+ for (int i = 0; i < inputPorts.size(); i++) {
+ Port port = inputPorts.get(i);
+ Point offset;
+ if (i < inputPorts.size() / 2) {
+ offset = new Point(PortGUI.DATA_PORT_SIZE / 2, this.headHeight + PORT_INITIAL_GAP + PORT_GAP * i);
+ } else {
+ offset = new Point(PortGUI.DATA_PORT_SIZE / 2, this.headHeight + PORT_INITIAL_GAP + PORT_GAP * (i + 1));
+ }
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // outputs
+ List<? extends Port> outputPorts = this.node.getOutputPorts();
+ for (int i = 0; i < outputPorts.size(); i++) {
+ Port port = outputPorts.get(i);
+ Point offset = new Point(this.getBounds().width - PortGUI.DATA_PORT_SIZE / 2, (int) (this.headHeight
+ + PORT_INITIAL_GAP + PORT_GAP * (outputPorts.size() / 2.0 + i)));
+ NodeController.getGUI(port).setOffset(offset);
+ }
+
+ // control-in
+ Port controlInPort = this.node.getControlInPort();
+ if (controlInPort != null) {
+ NodeController.getGUI(controlInPort).setOffset(new Point(0, 0));
+ }
+
+ // control-out
+ for (Port controlOutPort : this.node.getControlOutPorts()) {
+ NodeController.getGUI(controlOutPort).setOffset(new Point(getBounds().width, getBounds().height - this.headHeight / 2));
+ break; // Has only one
+ }
+
+ }
+
+ private void calculatePositions() {
+ this.polygon.reset();
+ Point position = getPosition();
+ this.polygon.addPoint(position.x, position.y);
+ this.polygon.addPoint(position.x, position.y + this.dimension.height + this.headHeight / 2);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.dimension.height);
+ this.polygon.addPoint(position.x + this.dimension.width, position.y + this.headHeight / 2);
+ DrawUtils.setupRoundedGeneralPath(polygon, getComponentShape());
+ }
+}
\ No newline at end of file