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:02 UTC

[60/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/experiment/RegistrySearchResult.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistrySearchResult.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistrySearchResult.java
new file mode 100644
index 0000000..c17eb4e
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistrySearchResult.java
@@ -0,0 +1,131 @@
+/*
+ *
+ * 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.experiment;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.xbaya.ui.widgets.TableRenderable;
+
+public class RegistrySearchResult implements TableRenderable {
+
+    private static String[] columnName = { "Name", "Description" };
+
+    private QName qname;
+
+    private QName resourceID;
+
+    private String resourceName;
+
+    private String description;
+
+    /**
+     * Constructs a RegistrySearchResult.
+     * 
+     * @param node
+     */
+
+    public RegistrySearchResult(Workflow workflow) {
+        //Never user so far during the project lifetime, thus assumption will never need
+//            String property = node.getProperty("Type").getString();
+//            if (property.equals(XBayaConstants.REGISTRY_TYPE_HOST_DESC)) {
+//                // todo
+//            } else if (property.equals(XBayaConstants.REGISTRY_TYPE_APPLICATION_DESC)) {
+//                // todo
+//            } else if (property.equals(XBayaConstants.REGISTRY_TYPE_SERVICE_DESC)) {
+//                // todo
+//            } else if (property.equals(XBayaConstants.REGISTRY_TYPE_WORKFLOW)) {
+		    // this.qname = new ;
+		    this.resourceID = workflow.getQname();
+		    this.description = workflow.getDescription();
+		    this.resourceName = workflow.getName();
+//            }
+    }
+
+    /**
+     * Returns the qname.
+     * 
+     * @return The resourceID
+     */
+    public QName getQname() {
+        return this.qname;
+    }
+
+    /**
+     * Returns the resourceId.
+     * 
+     * @return The resourceID
+     */
+    public QName getResourceId() {
+        return this.resourceID;
+    }
+
+    /**
+     * Returns the description.
+     * 
+     * @return The description
+     */
+    public String getDescription() {
+        return this.description;
+    }
+
+    /**
+     * Returns the resourceName.
+     * 
+     * @return The resourceName
+     */
+    public String getResourceName() {
+        return this.resourceName;
+    }
+
+    /**
+     * @see org.apache.airavata.xbaya.ui.widgets.TableRenderable#getColumnCount()
+     */
+    @Override
+    public int getColumnCount() {
+        return 2;
+    }
+
+    /**
+     * @see org.apache.airavata.xbaya.ui.widgets.TableRenderable#getColumnTitle(int)
+     */
+    @Override
+    public String getColumnTitle(int index) {
+        return columnName[index];
+    }
+
+    /**
+     * @see org.apache.airavata.xbaya.ui.widgets.TableRenderable#getValue(int)
+     */
+    @Override
+    public Object getValue(int index) {
+        switch (index) {
+        case 0:
+            return getResourceName();
+        case 1:
+            return getDescription();
+        default:
+            return null;
+        }
+    }
+
+}
\ 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/experiment/RegistryWorkflowPublisherWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java
new file mode 100644
index 0000000..8835be0
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/RegistryWorkflowPublisherWindow.java
@@ -0,0 +1,144 @@
+/*
+ *
+ * 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.experiment;
+
+import java.awt.event.ActionEvent;
+
+import javax.swing.AbstractAction;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JPanel;
+import javax.swing.border.EtchedBorder;
+import javax.swing.border.TitledBorder;
+
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.ui.dialogs.XBayaDialog;
+import org.apache.airavata.xbaya.ui.graph.GraphCanvas;
+import org.apache.airavata.xbaya.ui.widgets.GridPanel;
+import org.apache.airavata.xbaya.ui.widgets.XBayaLabel;
+import org.apache.airavata.xbaya.ui.widgets.XBayaTextArea;
+import org.apache.airavata.xbaya.ui.widgets.XBayaTextField;
+
+public class RegistryWorkflowPublisherWindow {
+
+    private XBayaEngine engine;
+
+    private XBayaDialog dialog;
+
+    private JButton okButton;
+
+    private boolean makePublic = false;
+
+    private JCheckBox chkMakePublic;
+
+    private XBayaTextArea descriptionTextArea;
+
+    private XBayaTextField nameTextField;
+
+    private Workflow workflow;
+
+    /**
+     * Constructs a OGCEXRegistryWorkflowPublisherWindow.
+     * 
+     * @param engine
+     */
+    public RegistryWorkflowPublisherWindow(XBayaEngine engine) {
+        this.engine = engine;
+        initGUI();
+    }
+
+    private void ok() {
+        String name = this.nameTextField.getText();
+        String description = this.descriptionTextArea.getText();
+
+        GraphCanvas graphCanvas = this.engine.getGUI().getGraphCanvas();
+        graphCanvas.setNameAndDescription(name, description);
+        hide();
+    }
+
+    /**
+     * Show the workflow name and description
+     */
+    public void show() {
+        this.workflow = this.engine.getGUI().getWorkflow();
+        String name = this.workflow.getName();
+        this.nameTextField.setText(name);
+
+        String description = this.workflow.getDescription();
+        this.descriptionTextArea.setText(description);
+
+        this.dialog.show();
+    }
+
+    /**
+     * Hide the workflow name and description
+     */
+    public void hide() {
+        this.dialog.hide();
+    }
+
+    /**
+     * Intialize UI
+     */
+    private void initGUI() {
+
+        this.nameTextField = new XBayaTextField();
+        XBayaLabel nameLabel = new XBayaLabel("Name", this.nameTextField);
+
+        this.descriptionTextArea = new XBayaTextArea();
+        XBayaLabel descriptionLabel = new XBayaLabel("Description", this.descriptionTextArea);
+
+        JPanel buttonPanel = new JPanel();
+        this.okButton = new JButton("OK");
+        this.okButton.addActionListener(new AbstractAction() {
+            public void actionPerformed(ActionEvent e) {
+                ok();
+            }
+
+        });
+        buttonPanel.add(this.okButton);
+
+        GridPanel mainPanel = new GridPanel();
+        TitledBorder border = new TitledBorder(new EtchedBorder(), "Save Workflow to Registry");
+        mainPanel.getSwingComponent().setBorder(border);
+        mainPanel.add(nameLabel);
+        mainPanel.add(this.nameTextField);
+        mainPanel.add(descriptionLabel);
+        mainPanel.add(this.descriptionTextArea);
+        chkMakePublic = new JCheckBox("Make public");
+        mainPanel.add(chkMakePublic);
+        mainPanel.layout(2, 2, 0, 0);
+
+        this.dialog = new XBayaDialog(this.engine.getGUI(), "Save Workflow to Registry", mainPanel, buttonPanel);
+        this.dialog.setDefaultButton(this.okButton);
+    }
+
+    /**
+     * Verify if the public checkbox is selected or not
+     * 
+     * @return true or false
+     */
+    public boolean isMakePublic() {
+        return this.chkMakePublic.isSelected();
+    }
+}
\ 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/experiment/WorkflowInterpreterLaunchWindow.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
new file mode 100644
index 0000000..68fc482
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/experiment/WorkflowInterpreterLaunchWindow.java
@@ -0,0 +1,350 @@
+/*
+ *
+ * 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.experiment;
+
+import java.awt.event.ActionEvent;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+//import org.apache.airavata.registry.api.AiravataRegistry2;
+
+import javax.swing.AbstractAction;
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.border.EtchedBorder;
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.client.api.AiravataAPI;
+import org.apache.airavata.client.api.ExperimentAdvanceOptions;
+import org.apache.airavata.common.utils.StringUtil;
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.graph.system.InputNode;
+import org.apache.airavata.workflow.model.graph.util.GraphUtil;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.ode.ODEClient;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.workflow.model.wf.WorkflowInput;
+import org.apache.airavata.ws.monitor.MonitorConfiguration;
+import org.apache.airavata.ws.monitor.MonitorException;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.core.amazon.AmazonCredential;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.jython.script.JythonScript;
+import org.apache.airavata.xbaya.ui.dialogs.XBayaDialog;
+import org.apache.airavata.xbaya.ui.graph.ws.WSNodeGUI;
+import org.apache.airavata.xbaya.ui.utils.ErrorMessages;
+import org.apache.airavata.xbaya.ui.widgets.GridPanel;
+import org.apache.airavata.xbaya.ui.widgets.XBayaLabel;
+import org.apache.airavata.xbaya.ui.widgets.XBayaTextField;
+import org.apache.airavata.xbaya.util.XBayaUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+import org.xmlpull.v1.builder.XmlInfosetBuilder;
+
+import xsul.XmlConstants;
+
+public class WorkflowInterpreterLaunchWindow {
+
+    private static final Logger logger = LoggerFactory.getLogger(WorkflowInterpreterLaunchWindow.class);
+
+    private XBayaEngine engine;
+
+    private Workflow workflow;
+
+    private XBayaDialog dialog;
+
+    private GridPanel parameterPanel;
+
+//    private XBayaTextField topicTextField;
+
+    private List<XBayaTextField> parameterTextFields = new ArrayList<XBayaTextField>();
+
+//    private XBayaTextField workflowInterpreterTextField;
+
+//    private XBayaTextField RegistryTextField;
+
+//    private XBayaTextField gfacTextField;
+
+	private XBayaTextField instanceNameTextField;
+
+    protected final static XmlInfosetBuilder builder = XmlConstants.BUILDER;
+
+    /**
+     * Constructs a WorkflowInterpreterLaunchWindow.
+     * 
+     * @param engine
+     * 
+     */
+    public WorkflowInterpreterLaunchWindow(XBayaEngine engine) {
+        this.engine = engine;
+        if (XBayaUtil.acquireJCRRegistry(engine)) {
+            initGUI();
+        }
+    }
+
+    /**
+     * Shows the dialog.
+     */
+    public void show() {
+        this.workflow = this.engine.getGUI().getWorkflow();
+
+        MonitorConfiguration notifConfig = this.engine.getMonitor().getConfiguration();
+        if (notifConfig.getBrokerURL() == null) {
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.BROKER_URL_NOT_SET_ERROR);
+            return;
+        }
+
+        // Create input fields
+        Collection<InputNode> inputNodes = GraphUtil.getInputNodes(this.workflow.getGraph());
+        for (InputNode node : inputNodes) {
+            String id = node.getID();
+            QName parameterType = node.getParameterType();
+            JLabel nameLabel = new JLabel(id);
+            JLabel typeField = new JLabel(parameterType.getLocalPart());
+            XBayaTextField paramField = new XBayaTextField();
+            Object value = node.getDefaultValue();
+
+            String valueString;
+            if (value == null) {
+                valueString = "";
+            } else {
+                if (value instanceof XmlElement) {
+                    XmlElement valueElement = (XmlElement) value;
+                    valueString = XMLUtil.xmlElementToString(valueElement);
+                } else {
+                    // Only string comes here for now.
+                    valueString = value.toString();
+                }
+            }
+            paramField.setText(valueString);
+            this.parameterPanel.add(nameLabel);
+            this.parameterPanel.add(typeField);
+            this.parameterPanel.add(paramField);
+            this.parameterTextFields.add(paramField);
+        }
+        this.parameterPanel.layout(inputNodes.size(), 3, GridPanel.WEIGHT_NONE, 2);
+//        this.instanceNameTextField.setText(workflow.getName()+"_"+Calendar.getInstance().getTime().toString());
+//        this.topicTextField.setText(UUID.randomUUID().toString());
+
+//        XBayaConfiguration config = this.engine.getConfiguration();
+//        this.gfacTextField.setText(config.getGFacURL().toString());
+//        URI workflowInterpreterURL = config.getWorkflowInterpreterURL();
+//        if (null != workflowInterpreterURL) {
+//            this.workflowInterpreterTextField.setText(workflowInterpreterURL.toString());
+//        } else {
+//            this.workflowInterpreterTextField.setText(XBayaConstants.DEFAULT_WORKFLOW_INTERPRETER_URL);
+//        }
+
+//        AiravataAPI airavataAPI = config.getAiravataAPI();
+//        if (null != airavataAPI) {
+//            this.RegistryTextField.setText(config.getRegistryURL());
+//        } else {
+//            this.RegistryTextField.setText(XBayaConstants.REGISTRY_URL.toASCIIString());
+//        }
+
+        this.dialog.show();
+    }
+
+    /**
+     * Hides the dialog.
+     */
+    public void hide() {
+        this.dialog.hide();
+
+        this.parameterPanel.getContentPanel().removeAll();
+        this.parameterTextFields.clear();
+    }
+
+    private void initGUI() {
+        this.parameterPanel = new GridPanel(true);
+
+        this.instanceNameTextField = new XBayaTextField();
+        XBayaLabel instanceNameLabel = new XBayaLabel("Experiment name", this.instanceNameTextField);
+        
+//        this.topicTextField = new XBayaTextField();
+//        XBayaLabel topicLabel = new XBayaLabel("Notification topic", this.topicTextField);
+//        this.workflowInterpreterTextField = new XBayaTextField();
+//        XBayaLabel workflowInterpreterLabel = new XBayaLabel("Workflow Interpreter URL",
+//                this.workflowInterpreterTextField);
+//        this.RegistryTextField = new XBayaTextField();
+//        XBayaLabel RegistryLabel = new XBayaLabel("Registry URL", this.RegistryTextField);
+//        this.gfacTextField = new XBayaTextField();
+//        XBayaLabel gfacLabel = new XBayaLabel("GFac URL", this.gfacTextField);
+
+        GridPanel infoPanel = new GridPanel();
+        infoPanel.add(instanceNameLabel);
+        infoPanel.add(this.instanceNameTextField);
+//        infoPanel.add(topicLabel);
+//        infoPanel.add(this.topicTextField);
+//        infoPanel.add(workflowInterpreterLabel);
+//        infoPanel.add(this.workflowInterpreterTextField);
+//        infoPanel.add(gfacLabel);
+//        infoPanel.add(this.gfacTextField);
+//        infoPanel.add(RegistryLabel);
+//        infoPanel.add(this.RegistryTextField);
+
+        infoPanel.layout(1, 2, GridPanel.WEIGHT_NONE, 1);
+
+        GridPanel mainPanel = new GridPanel();
+        mainPanel.getContentPanel().setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
+        mainPanel.add(infoPanel);
+        mainPanel.add(this.parameterPanel);
+        mainPanel.layout(2, 1, 0, 0);
+
+        JButton okButton = new JButton("Run");
+        okButton.addActionListener(new AbstractAction() {
+            public void actionPerformed(ActionEvent e) {
+                execute();
+            }
+        });
+
+        JButton cancelButton = new JButton("Cancel");
+        cancelButton.addActionListener(new AbstractAction() {
+            public void actionPerformed(ActionEvent e) {
+                hide();
+            }
+        });
+
+        JPanel buttonPanel = new JPanel();
+        buttonPanel.add(okButton);
+        buttonPanel.add(cancelButton);
+        buttonPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
+        this.dialog = new XBayaDialog(this.engine.getGUI(), "Launch  workflow", mainPanel, buttonPanel);
+        this.dialog.setDefaultButton(okButton);
+    }
+
+    private void execute() {
+        final List<String> arguments = new ArrayList<String>();
+
+        String topic = UUID.randomUUID().toString();//this.topicTextField.getText();
+        String instanceName = this.instanceNameTextField.getText();
+        if (instanceName.trim().equals("")){
+        	JOptionPane.showMessageDialog(engine.getGUI().getFrame(),
+        		    "Experiment name cannot be empty",
+        		    "Experiment Name",
+        		    JOptionPane.ERROR_MESSAGE);
+        	return;
+        }
+
+        //previous instance name
+        if (!instanceNameTextField.getText().equals("")){
+            this.instanceNameTextField.setText("");
+        }
+        final String instanceNameFinal=instanceName;
+        if (topic.length() == 0) {
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.TOPIC_EMPTY_ERROR);
+            return;
+        }
+
+        // Use topic as a base of workflow instance ID so that the monitor can
+        // find it.
+        URI workfowInstanceID = URI.create(StringUtil.convertToJavaIdentifier(topic));
+        this.workflow.setGPELInstanceID(workfowInstanceID);
+
+        MonitorConfiguration notifConfig = this.engine.getMonitor().getConfiguration();
+        engine.getMonitor().resetEventData();
+        notifConfig.setTopic(topic);
+        arguments.add("-" + JythonScript.TOPIC_VARIABLE);
+        arguments.add(topic);
+        Collection<WSNode> wsNodes = GraphUtil.getWSNodes(this.engine.getGUI().getWorkflow().getGraph());
+        for (WSNode node : wsNodes) {
+            ((WSNodeGUI) NodeController.getGUI(node)).setInteractiveMode(false);
+        }
+
+        // TODO error check for user inputs
+
+        final List<InputNode> inputNodes = GraphUtil.getInputNodes(this.workflow.getGraph());
+        builder.newFragment("inputs");
+        new ODEClient();
+        for (int i = 0; i < inputNodes.size(); i++) {
+            InputNode inputNode = inputNodes.get(i);
+            XBayaTextField parameterTextField = this.parameterTextFields.get(i);
+            inputNode.getID();
+            String value = parameterTextField.getText();
+            inputNode.setDefaultValue(value);
+        }
+
+//        final String workflowInterpreterUrl = this.workflowInterpreterTextField.getText();
+//        if (null != workflowInterpreterUrl && !"".equals(workflowInterpreterUrl)) {
+//            try {
+//                this.engine.getConfiguration().setWorkflowInterpreterURL(new URI(workflowInterpreterUrl));
+//            } catch (URISyntaxException e) {
+//                this.engine.getGUI().getErrorWindow().error(e);
+//            }
+//        }
+
+//        final String gFacUrl = this.gfacTextField.getText();
+//        if (null != gFacUrl && !"".equals(gFacUrl)) {
+//            try {
+//                this.engine.getConfiguration().setGFacURL(new URI(gFacUrl));
+//            } catch (URISyntaxException e) {
+//                this.engine.getGUI().getErrorWindow().error(e);
+//            }
+//        }
+        this.engine.getConfiguration().setTopic(topic);
+
+        new Thread() {
+            @Override
+            public void run() {
+
+                try {
+                    List<WorkflowInput> workflowInputs=new ArrayList<WorkflowInput>();
+                    for (int i = 0; i < inputNodes.size(); i++) {
+                    	InputNode inputNode = inputNodes.get(i);
+                    	workflowInputs.add(new WorkflowInput(inputNode.getID(), inputNode.getDefaultValue().toString()));
+                    }
+                    AiravataAPI api = engine.getConfiguration().getAiravataAPI();
+                    
+                    ExperimentAdvanceOptions options = api.getExecutionManager().createExperimentAdvanceOptions(instanceNameFinal, api.getCurrentUser(), null);
+                    if (AmazonCredential.getInstance().getAwsAccessKeyId() != null) {
+                        options.getCustomSecuritySettings().getAmazonWSSettings().setAccessKeyId(AmazonCredential.getInstance().getAwsAccessKeyId());
+                        options.getCustomSecuritySettings().getAmazonWSSettings().setSecretAccessKey(AmazonCredential.getInstance().getAwsSecretAccessKey());
+                    }
+
+                    //TODO get the token id from UI
+                    // For the moment hard code it
+                    // TODO Build UI to get the token id
+                    //options.getCustomSecuritySettings().getCredentialStoreSecuritySettings().setTokenId("1234");
+
+
+                    String experimentId = api.getExecutionManager().runExperiment(api.getWorkflowManager().getWorkflowAsString(workflow), workflowInputs,options);
+                    try {
+                        WorkflowInterpreterLaunchWindow.this.engine.getMonitor().getConfiguration().setTopic(experimentId);
+                        WorkflowInterpreterLaunchWindow.this.engine.getMonitor().start();
+                    } catch (MonitorException e1) {
+                        WorkflowInterpreterLaunchWindow.this.engine.getGUI().getErrorWindow().error(e1);
+                    }
+                } catch (Exception e) {
+                    WorkflowInterpreterLaunchWindow.this.engine.getGUI().getErrorWindow().error(e);
+                }
+            }
+        }.start();
+
+        hide();
+    }
+}
\ 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/EdgeGUI.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/EdgeGUI.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/EdgeGUI.java
new file mode 100644
index 0000000..1c94620
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/EdgeGUI.java
@@ -0,0 +1,142 @@
+/*
+ *
+ * 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.BasicStroke;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Stroke;
+import java.awt.event.MouseEvent;
+import java.awt.geom.CubicCurve2D;
+
+import org.apache.airavata.workflow.model.graph.ControlEdge;
+import org.apache.airavata.workflow.model.graph.Edge;
+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.utils.DrawUtils;
+
+public class EdgeGUI implements GraphPieceGUI {
+
+    /**
+     * CONTROL_EDGE_STROKE
+     */
+    public static final Stroke CONTROL_EDGE_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE,
+            BasicStroke.JOIN_MITER, 10.0f, new float[] { 5.0f }, 0.0f);
+
+    public static final Stroke STREAM_EDGE_STROKE = new BasicStroke(4.0f, BasicStroke.CAP_SQUARE,
+            BasicStroke.JOIN_MITER, 10.0f, new float[] { 5.0f }, 0.0f);
+
+    private static final Color lineColor = Color.black;
+
+    private static final Color pointColor = Color.pink;
+
+    private static final Color selectedPointColor = Color.red;
+
+    private static final int POINT_SIZE = 8;
+
+    private Edge edge;
+
+    private boolean selected = false;
+
+    private static Color STREAM_EDGE_COLOR = new Color(51, 255, 204);
+
+    /**
+     * @param edge
+     * 
+     */
+    public EdgeGUI(Edge edge) {
+        this.edge = edge;
+    }
+
+    /**
+     * @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 bool
+     */
+    protected void setSelectedFlag(boolean bool) {
+        this.selected = bool;
+    }
+
+    /**
+     * @return the middle point of the edge
+     */
+    protected Point getMiddlePosition() {
+        Point point1 = getFromPosition();
+        Point point2 = getToPosition();
+
+        Point midPoint = new Point((point1.x + point2.x) / 2, (point1.y + point2.y) / 2);
+        return midPoint;
+    }
+
+    /**
+     * @param g
+     */
+    protected void paint(Graphics2D g) {
+    	DrawUtils.initializeGraphics2D(g);
+        Point point1 = getFromPosition();
+        Point point2 = getToPosition();
+
+            g.setColor(lineColor);
+
+        Stroke originalStroke = g.getStroke();
+        if (this.edge instanceof ControlEdge) {
+            g.setStroke(EdgeGUI.CONTROL_EDGE_STROKE);
+        } 
+        paintLine(point1, point2, g);
+        g.setStroke(originalStroke);
+
+        g.setColor(this.selected ? pointColor : selectedPointColor);
+
+        Point midPoint = getMiddlePosition();
+        g.fillArc(midPoint.x - POINT_SIZE / 2, midPoint.y - POINT_SIZE / 2, POINT_SIZE, POINT_SIZE, 0, 360);
+    }
+
+
+    protected static void paintLine(Point point1, Point point2, Graphics2D g) {
+        int d = 100;
+        int dist = (int) point1.distance(point2);
+        if (dist < d) {
+            d = dist;
+        }
+        CubicCurve2D line = new CubicCurve2D.Double(point1.x, point1.y, point1.x + d, point1.y, point2.x - d, point2.y,
+                point2.x, point2.y);
+        g.draw(line);
+    }
+
+    private Point getFromPosition() {
+        Port port = this.edge.getFromPort();
+        return NodeController.getGUI(port).getPosition();
+    }
+
+    private Point getToPosition() {
+        Port port = this.edge.getToPort();
+        return NodeController.getGUI(port).getPosition();
+    }
+}
\ 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/GraphCanvas.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvas.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvas.java
new file mode 100644
index 0000000..de960c2
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvas.java
@@ -0,0 +1,1375 @@
+/*
+ *
+ * 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.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Stroke;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.awt.dnd.DnDConstants;
+import java.awt.dnd.DropTarget;
+import java.awt.dnd.DropTargetAdapter;
+import java.awt.dnd.DropTargetDropEvent;
+import java.awt.dnd.DropTargetListener;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.AbstractAction;
+import javax.swing.JComponent;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+
+import org.apache.airavata.common.utils.SwingUtil;
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.component.Component;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.component.ComponentReference;
+import org.apache.airavata.workflow.model.component.ComponentRegistryException;
+import org.apache.airavata.workflow.model.component.system.InputComponent;
+import org.apache.airavata.workflow.model.component.system.OutputComponent;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.Edge;
+import org.apache.airavata.workflow.model.graph.Graph;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.GraphPiece;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Node.NodeExecutionState;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.Port.Kind;
+import org.apache.airavata.workflow.model.graph.dynamic.DynamicNode;
+import org.apache.airavata.workflow.model.graph.dynamic.PortAddable;
+import org.apache.airavata.workflow.model.graph.system.InputNode;
+import org.apache.airavata.workflow.model.graph.system.StreamSourceNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.apache.airavata.workflow.model.wf.WorkflowExecutionState;
+import org.apache.airavata.xbaya.XBayaConfiguration;
+import org.apache.airavata.xbaya.XBayaConfiguration.XBayaExecutionMode;
+import org.apache.airavata.xbaya.XBayaEngine;
+import org.apache.airavata.xbaya.core.ide.XBayaExecutionModeListener;
+import org.apache.airavata.xbaya.graph.controller.NodeController;
+import org.apache.airavata.xbaya.ui.utils.ErrorMessages;
+import org.apache.airavata.xbaya.ui.widgets.component.ComponentSourceTransferable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+
+
+/**
+ * A canvas to display a graph (workflow).
+ * 
+ */
+public class GraphCanvas implements XBayaExecutionModeListener{
+
+    private static final Logger logger = LoggerFactory.getLogger(GraphCanvas.class);
+
+    private XBayaEngine engine;
+
+    private JPanel panel;
+
+    private JScrollPane scrollPane;
+
+    private List<GraphCanvasListener> listeners;
+
+    private Workflow workflow;
+
+    private Graph graph;
+
+    private Node selectedNode;
+
+    private Node draggedNode;
+
+    private Port selectedOutputPort;
+
+    private Port selectedInputPort;
+
+    private Edge selectedEdge;
+
+    private Port draggedPort;
+
+    private Dimension graphDimention;
+
+    private JPopupMenu edgePopup;
+
+    private JPopupMenu nodePopup;
+
+    private Point mousePoint;
+
+    private JMenuItem rerunItem;
+
+    private JMenuItem breakPointItem;
+
+    private PortAddable dynamicNodeWithFreePort;
+
+    private File workflowFile;
+    
+    /*
+     * For multiple selection
+     */
+    private boolean crtlPressed;
+
+    private Point mousePointForSelection;
+
+    private List<Node> multipleSelectedNodes;
+
+    private XmlElement originalWorkflowElement;
+    
+    boolean editable=false;
+    /**
+     * Creates a GraphPanel.
+     * 
+     * @param engine
+     *            The XBayaEngine
+     */
+    public GraphCanvas(XBayaEngine engine) {
+
+        this.engine = engine;
+
+        this.listeners = new LinkedList<GraphCanvasListener>();
+
+        // To avoid null check. Do not call newWorkflow() here because something
+        // are not initialized yet at this point.
+        this.workflow = new Workflow();
+        this.graph = this.workflow.getGraph();
+        engine.getConfiguration().registerExecutionModeChangeListener(this);
+        graph.setName(generateNewWorkflowName());
+        initGUI();
+        executionModeChanged(engine.getConfiguration());
+    }
+
+	private String generateNewWorkflowName() {
+		String baseName="Workflow";
+        List<String> existingNames=new ArrayList<String>();
+        if (this.engine.getGUI() != null) {
+            List<GraphCanvas> graphCanvases = this.engine.getGUI().getGraphCanvases();
+            for (GraphCanvas graphCanvas : graphCanvases) {
+                existingNames.add(graphCanvas.getWorkflow().getName());
+            }
+        }
+        int i=1;
+        String newName=baseName+i;
+        while(existingNames.contains(newName)){
+        	i++;
+        	newName=baseName+i;
+        }
+		return newName;
+	}
+
+    /**
+     * @return The panel.
+     */
+    public JComponent getSwingComponent() {
+        return this.scrollPane;
+    }
+
+    /**
+     * @return The workflow
+     */
+    public Workflow getWorkflow() {
+        return this.workflow;
+    }
+
+    /**
+     * Returns the workflow.
+     * 
+     * @return The workflow
+     */
+    public synchronized Workflow getWorkflowWithImage() {
+        BufferedImage image = createImage();
+        this.workflow.setImage(image);
+        return this.workflow;
+    }
+
+    /**
+     * @return the current graph
+     */
+    public synchronized Graph getGraph() {
+        return this.graph;
+    }
+
+    /**
+     * Sets workflow.
+     * 
+     * @param workflow
+     *            The workflow to set.
+     */
+    public synchronized void setWorkflow(Workflow workflow) {
+        reset();
+        this.workflow = workflow;
+        this.graph = this.workflow.getGraph();
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.GRAPH_LOADED, this, this.workflow));
+        updateSize();
+        this.panel.repaint();
+        updateOriginalWorkflowElement();
+        executionModeChanged(engine.getConfiguration());
+    }
+
+    /**
+     * Creates a new graph.
+     */
+    public synchronized void newWorkflow() {
+        Workflow newWorkflow = new Workflow();
+        setWorkflow(newWorkflow);
+    }
+
+    /**
+     * @param name
+     * @param description
+     */
+    public void setNameAndDescription(String name, String description) {
+        this.workflow.setName(name);
+        this.workflow.setDescription(description);
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.NAME_CHANGED, this, this.workflow));
+    }
+
+    /**
+     * Creates a new Node from a specified Component and adds it.
+     * 
+     * @param component
+     *            The Component to add.
+     * @param location
+     *            The location to add the node.
+     */
+    public synchronized Node addNode(Component component, Point location) {
+        if (component != null) {
+            Node node = this.workflow.addNode(component);
+            node.setPosition(location);
+            selectNode(node);
+            updateSize();
+            this.panel.repaint();
+            return node;
+        }
+        return null;
+    }
+
+    /**
+     * Creates a new Node from a specified Component and adds it.
+     * 
+     * @param component
+     *            The Component to add.
+     */
+    public Node addNode(Component component) {
+        Point location = getRandomPosition();
+        return addNode(component, location);
+    }
+
+    /**
+     * Removes the selected graph piece if any.
+     * 
+     * @throws GraphException
+     */
+    public synchronized void removeSelected() throws GraphException {
+        removeSelectedEdge();
+        removeSelectedNode();
+    }
+
+    /**
+     * Removes the selected Node if any
+     * 
+     * @throws GraphException
+     */
+    public synchronized void removeSelectedNode() throws GraphException {
+        if (this.selectedNode != null) {
+
+            // deselect ports if they belong to this node.
+            if (this.selectedNode.containsPort(this.selectedInputPort)) {
+                deselectInputPort();
+            }
+            if (this.selectedNode.containsPort(this.selectedOutputPort)) {
+                deselectOutputPort();
+            }
+
+            this.workflow.removeNode(this.selectedNode);
+            deselectNode();
+
+            updateSize();
+            this.panel.repaint();
+        }
+
+        /*
+         * Delete multiple nodes as well
+         */
+        if (this.multipleSelectedNodes != null) {
+
+            for (Node node : this.multipleSelectedNodes) {
+                // deselect ports if they belong to this node.
+                if (node.containsPort(this.selectedInputPort)) {
+                    deselectInputPort();
+                }
+                if (node.containsPort(this.selectedOutputPort)) {
+                    deselectOutputPort();
+                }
+
+                this.workflow.removeNode(node);
+            }
+            deselectNode();
+
+            updateSize();
+            this.panel.repaint();
+        }
+    }
+
+    /**
+     * Removes the selected edge if any.
+     */
+    public synchronized void removeSelectedEdge() {
+        try {
+            if (this.selectedEdge != null) {
+                this.graph.removeEdge(this.selectedEdge);
+                deselectEdge();
+                this.panel.repaint();
+            }
+        } catch (GraphException e) {
+            // Should not happen
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+        } catch (RuntimeException e) {
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+        } catch (Error e) {
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+
+        }
+    }
+
+    /**
+     * 
+     */
+    public synchronized void addOrRemoveEdge() {
+
+        try {
+            if (this.selectedEdge != null) {
+                this.graph.removeEdge(this.selectedEdge);
+                deselectEdge();
+
+            } else if ((this.selectedOutputPort != null) && (this.selectedInputPort != null)) {
+
+                if (this.graph.containsEdge(this.selectedOutputPort, this.selectedInputPort)) {
+                    // If both ports are selected and they are connected
+                    // already, the edge will be deleted.
+                    this.graph.removeEdge(this.selectedOutputPort, this.selectedInputPort);
+                    deselectEdge();
+
+                } else {
+                    // Create a new edge
+                    connect(this.selectedOutputPort, this.selectedInputPort);
+                }
+            }
+            this.panel.repaint();
+        } catch (GraphException e) {
+            // Should not happen
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+        } catch (RuntimeException e) {
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+        } catch (Error e) {
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+
+        }
+    }
+
+    /**
+     * Returns the selectedNode.
+     * 
+     * @return The selectedNode
+     */
+    public Node getSelectedNode() {
+        return this.selectedNode;
+    }
+
+    /**
+     * Returns the selectedInputPort.
+     * 
+     * @return The selectedInputPort
+     */
+    public Port getSelectedInputPort() {
+        return this.selectedInputPort;
+    }
+
+    /**
+     * Returns the selectedOutputPort.
+     * 
+     * @return The selectedOutputPort
+     */
+    public Port getSelectedOutputPort() {
+        return this.selectedOutputPort;
+    }
+
+    /**
+     * Repaints the panel.
+     */
+    public void repaint() {
+        this.panel.repaint();
+    }
+
+    /**
+     * @param listener
+     */
+    public synchronized void addGraphCanvasListener(GraphCanvasListener listener) {
+        this.listeners.add(listener);
+    }
+
+    /**
+     * @param listener
+     */
+    public synchronized void removeGraphCanvasListener(GraphCanvasListener listener) {
+        this.listeners.remove(listener);
+    }
+
+    private void mouseClicked(MouseEvent event) {
+        /*
+         * If there is multi-selected and a click on a node, switch to that node or deselect node if it is already
+         * selected
+         */
+        Point point = event.getPoint();
+        GraphPiece clicked = NodeController.getGUI(this.graph).getGraphPieceAt(point);
+        if ((clicked instanceof Node) && this.multipleSelectedNodes != null) {
+            Node node = (Node) clicked;
+            if (!this.crtlPressed) {
+                selectNode(node);
+            }
+            return;
+        }else if ((clicked instanceof Port) && event.getClickCount()==2){
+        	//double click to add Input/Output nodes and connect with them when a DataPort is double clicked
+        	Port port=(Port)clicked;
+        	Point pos = port.getNode().getPosition();
+        	Node node=null;
+        	int xgap = (int)(1.5 * NodeGUI.MINIMUM_WIDTH);
+        	int ygap = (int)(NodeGUI.MINIMUM_HEIGHT/2);
+        	Point nodePos = null;
+			switch (port.getKind()){
+        	case DATA_IN:
+        		if (port.getFromNode()==null) {
+					nodePos = new Point(Math.max(0, pos.x - xgap), Math.max(0, pos.y - ygap));
+					node = addNode(new InputComponent(), nodePos);
+					connect(node.getOutputPorts().get(0), port);
+				}
+				break;
+        	case DATA_OUT:
+				nodePos = new Point(pos.x + NodeGUI.MINIMUM_WIDTH + xgap, pos.y + ygap);
+				node = addNode(new OutputComponent(), nodePos);
+				connect(port, node.getInputPorts().get(0));
+				break;
+        		default:
+        	}
+        }
+
+        // delegate the event.
+        NodeController.getGUI(this.graph).mouseClicked(event, this.engine);
+    }
+
+    private void mousePressed(MouseEvent event) {
+        Point point = event.getPoint();
+
+        // Get focus to handle key board events
+        this.panel.requestFocusInWindow();
+
+        // Get select item
+        GraphPiece selected = NodeController.getGUI(this.graph).getGraphPieceAt(point);
+
+        /*
+         * Doing Nothing if pressed is on the selected node
+         */
+        if (this.multipleSelectedNodes != null) {
+            maybeShowPopup(event);
+            if (this.crtlPressed && this.multipleSelectedNodes.contains(selected)) {
+                deselectNode((Node) selected);
+                return;
+            } else if (this.multipleSelectedNodes.contains(selected)) {
+                this.mousePoint = point;
+                this.panel.setCursor(SwingUtil.MOVE_CURSOR);
+                return;
+            } else if ((selected instanceof Node) && this.crtlPressed) {
+                this.mousePoint = point;
+                this.multipleSelectedNodes.add((Node) selected);
+                this.panel.setCursor(SwingUtil.MOVE_CURSOR);
+                selectNodes(this.multipleSelectedNodes);
+                return;
+            }
+        }
+        // control selection
+        if ((selected instanceof Node) && this.crtlPressed) {
+            this.multipleSelectedNodes = new ArrayList<Node>();
+            if (this.selectedNode != null) {
+                this.multipleSelectedNodes.add(this.selectedNode);
+            }
+            this.multipleSelectedNodes.add((Node) selected);
+            this.panel.setCursor(SwingUtil.MOVE_CURSOR);
+            selectNodes(this.multipleSelectedNodes);
+            return;
+        }
+
+        deselectNode();
+        deselectEdge();
+
+        if (selected instanceof Node) {
+            Node node = (Node) selected;
+            selectNode(node);
+            if (!NodeController.getGUI(node).isInConfig(point)) {
+                this.draggedNode = node;
+                NodeController.getGUI(node).setDraggedFlag(true);
+                this.panel.setCursor(SwingUtil.MOVE_CURSOR);
+            }
+
+        } else if (selected instanceof Port) {
+            Port port = (Port) selected;
+            NodeController.getGUI(port).setSelectedFlag(true);
+            switch (port.getKind()) {
+            case DATA_IN:
+            case CONTROL_IN:
+                selectInputPort(port);
+                break;
+            case CONTROL_OUT:
+            case DATA_OUT:
+            case EPR:
+                selectOutputPort(port);
+                break;
+            }
+
+            this.draggedPort = port;
+
+        } else if (selected instanceof Edge) {
+            Edge edge = (Edge) selected;
+            selectEdge(edge);
+        } else {
+            /*
+             * If nothing is selected
+             */
+            this.mousePointForSelection = event.getPoint();
+        }
+
+        maybeShowPopup(event);
+
+        this.mousePoint = point;
+        this.panel.repaint();
+        event.consume();
+    }
+
+    private void mouseReleased(MouseEvent event) {
+        Point point = event.getPoint();
+        if (this.draggedNode != null) {
+            NodeController.getGUI(this.draggedNode).setDraggedFlag(false);
+            this.panel.setCursor(SwingUtil.DEFAULT_CURSOR);
+
+            // Check if it s stream grouping
+            if (draggedNode instanceof InputNode) {
+                StreamSourceNode streamNode = NodeController.getGUI(this.graph).getStreamSourceAt(point);
+                if (streamNode != null) {
+                    streamNode.addInputNode((InputNode) draggedNode);
+                }
+
+            }
+            this.draggedNode = null;
+
+        }
+
+        if (this.draggedPort != null) {
+            GraphPiece graphPiece = NodeController.getGUI(this.graph).getGraphPieceAt(point);
+            if (graphPiece instanceof DynamicNode) {
+                if (this.draggedPort.getKind() == Kind.DATA_OUT && draggedPort instanceof DataPort) {
+                    this.panel.setCursor(SwingUtil.CROSSHAIR_CURSOR);
+                    DynamicNode dynamicNode = (DynamicNode) graphPiece;
+                    dynamicNode.getComponent();
+                    DataPort freePort = dynamicNode.getFreeInPort();
+                    try {
+                        freePort.copyType((DataPort) draggedPort);
+                    } catch (GraphException e) {
+                        engine.getGUI().getErrorWindow().error(e);
+                        return;
+                    }
+                    // selectInputPort(freePort);
+                    connect(this.draggedPort, freePort);
+                    this.dynamicNodeWithFreePort = null;
+                }
+
+            } else if (graphPiece instanceof Port) {
+                Port port = (Port) graphPiece;
+                if (this.draggedPort.getKind() == Kind.DATA_OUT && port.getKind() == Kind.DATA_IN) {
+                    connect(this.draggedPort, port);
+                } else if (port.getKind() == Kind.DATA_OUT && this.draggedPort.getKind() == Kind.DATA_IN) {
+                    connect(port, this.draggedPort);
+                } else if (this.draggedPort.getKind() == Kind.CONTROL_OUT && port.getKind() == Kind.CONTROL_IN) {
+                    connect(this.draggedPort, port);
+                } else if (this.draggedPort.getKind() == Kind.CONTROL_IN && port.getKind() == Kind.CONTROL_OUT) {
+                    connect(port, this.draggedPort);
+                } else if (this.draggedPort.getKind() == Kind.EPR && port.getKind() == Kind.DATA_IN) {
+                    connect(this.draggedPort, port);
+                } else if (this.draggedPort.getKind() == Kind.DATA_IN && port.getKind() == Kind.EPR) {
+                    connect(port, this.draggedPort);
+                }
+            }
+            this.draggedPort = null;
+        }
+
+        if (this.dynamicNodeWithFreePort != null) {
+            try {
+                this.dynamicNodeWithFreePort.removeLastDynamicallyAddedInPort();
+            } catch (GraphException e) {
+                this.engine.getGUI().getErrorWindow().error(e);
+            }
+        }
+
+        /*
+         * Multiple selected
+         */
+        if (this.mousePointForSelection != null) {
+            double width = Math.abs(this.mousePoint.getX() - this.mousePointForSelection.getX());
+            double height = Math.abs(this.mousePoint.getY() - this.mousePointForSelection.getY());
+            int x = (int) (this.mousePoint.getX() > this.mousePointForSelection.getX() ? this.mousePointForSelection
+                    .getX() : this.mousePoint.getX());
+            int y = (int) (this.mousePoint.getY() > this.mousePointForSelection.getY() ? this.mousePointForSelection
+                    .getY() : this.mousePoint.getY());
+
+            this.multipleSelectedNodes = NodeController.getGUI(this.graph).getNodesIn(new Rectangle(x, y, (int) width, (int) height));
+            selectNodes(this.multipleSelectedNodes);
+
+            // clear mousepoint
+            this.mousePointForSelection = null;
+        }
+
+        if (this.multipleSelectedNodes != null) {
+            this.panel.setCursor(SwingUtil.DEFAULT_CURSOR);
+        }
+
+        maybeShowPopup(event);
+
+        updateSize();
+        this.panel.repaint();
+        event.consume();
+    }
+
+    private void mouseDragged(MouseEvent event) {
+        Point point = event.getPoint();
+
+        if (editable) {
+			/*
+			 * Move nodes
+			 */
+			if (this.multipleSelectedNodes != null) {
+				if (point.x < 0) {
+					point.x = 0;
+				}
+				if (point.y < 0) {
+					point.y = 0;
+				}
+				int diffX = point.x - this.mousePoint.x;
+				int diffY = point.y - this.mousePoint.y;
+				for (Node node : this.multipleSelectedNodes) {
+					Point newPoint = new Point();
+					Point currentPoint = node.getPosition();
+					newPoint.x = currentPoint.x + diffX;
+					if (newPoint.x < 0) {
+						newPoint.x = 0;
+					}
+					newPoint.y = currentPoint.y + diffY;
+					if (newPoint.y < 0) {
+						newPoint.y = 0;
+					}
+					node.setPosition(newPoint);
+				}
+				this.panel.repaint();
+				event.consume();
+			}
+			if (this.draggedNode != null) {
+				if (point.x < 0) {
+					point.x = 0;
+				}
+				if (point.y < 0) {
+					point.y = 0;
+				}
+				int diffX = point.x - this.mousePoint.x;
+				int diffY = point.y - this.mousePoint.y;
+				Point newPoint = new Point();
+				Point currentPoint = this.draggedNode.getPosition();
+				newPoint.x = currentPoint.x + diffX;
+				if (newPoint.x < 0) {
+					newPoint.x = 0;
+				}
+				newPoint.y = currentPoint.y + diffY;
+				if (newPoint.y < 0) {
+					newPoint.y = 0;
+				}
+				this.draggedNode.setPosition(newPoint);
+
+				this.panel.repaint();
+				event.consume();
+			}
+			if (this.draggedPort != null) {
+				GraphPiece piece = NodeController.getGUI(this.graph).getGraphPieceAt(point);
+				if (piece instanceof Port) {
+					Port port = (Port) piece;
+					// Display the information of port that is close to the mouse
+					// pointer.
+					if (this.draggedPort.getKind() == Kind.DATA_IN
+							&& port.getKind() == Kind.DATA_OUT) {
+						this.panel.setCursor(SwingUtil.CROSSHAIR_CURSOR);
+						selectOutputPort(port);
+					} else if (this.draggedPort.getKind() == Kind.DATA_OUT
+							&& port.getKind() == Kind.DATA_IN) {
+						this.panel.setCursor(SwingUtil.CROSSHAIR_CURSOR);
+						selectInputPort(port);
+					} else if (this.draggedPort.getKind() == Kind.DATA_IN
+							&& port.getKind() == Kind.EPR) {
+						this.panel.setCursor(SwingUtil.CROSSHAIR_CURSOR);
+						selectOutputPort(port);
+					} else if (this.draggedPort.getKind() == Kind.EPR
+							&& port.getKind() == Kind.DATA_IN) {
+						this.panel.setCursor(SwingUtil.CROSSHAIR_CURSOR);
+						selectInputPort(port);
+					} else {
+						this.panel.setCursor(SwingUtil.DEFAULT_CURSOR);
+					}
+				} else if (piece instanceof PortAddable) {
+					PortAddable dynamicNode = (PortAddable) piece;
+					dynamicNode.getFreeInPort();
+					this.dynamicNodeWithFreePort = dynamicNode;
+				} else {
+
+					this.panel.setCursor(SwingUtil.DEFAULT_CURSOR);
+				}
+
+				this.panel.repaint();
+				event.consume();
+			}
+			this.mousePoint = point;
+			// draw rectangle
+			if (this.mousePointForSelection != null) {
+				this.panel.repaint();
+			}
+		}
+
+    }
+
+    private void mouseMoved(MouseEvent event) {
+        Point point = event.getPoint();
+        GraphPiece graphPiece = NodeController.getGUI(this.graph).getGraphPieceAt(point);
+        if (graphPiece instanceof Node) {
+            Node node = (Node) graphPiece;
+            if (NodeController.getGUI(node).isInConfig(point)) {
+                this.panel.setCursor(SwingUtil.HAND_CURSOR);
+            } else {
+                this.panel.setCursor(SwingUtil.DEFAULT_CURSOR);
+            }
+        } else if (graphPiece instanceof Port) {
+            this.panel.setCursor(SwingUtil.CROSSHAIR_CURSOR);
+        } else {
+            this.panel.setCursor(SwingUtil.DEFAULT_CURSOR);
+        }
+
+    }
+
+    private void keyPressed(KeyEvent event) {
+        int keyCode = event.getKeyCode();
+        if (editable && keyCode == KeyEvent.VK_DELETE) {
+            try {
+                removeSelected();
+            } catch (GraphException e) {
+                // Should not happen
+                logger.error(e.getMessage(), e);
+                this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+            } catch (RuntimeException e) {
+                logger.error(e.getMessage(), e);
+                this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+            } catch (Error e) {
+                logger.error(e.getMessage(), e);
+                this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+            }
+        }
+
+        /*
+         * Multiple select with shift
+         */
+        if (keyCode == KeyEvent.VK_CONTROL) {
+            this.crtlPressed = true;
+        }
+    }
+
+    private void keyReleased(KeyEvent event) {
+        int keyCode = event.getKeyCode();
+
+        if (keyCode == KeyEvent.VK_CONTROL) {
+            this.crtlPressed = false;
+        }
+    }
+
+    private void drop(final DropTargetDropEvent event) {
+        logger.debug("Event:" + event);
+        Transferable transferable = event.getTransferable();
+        try {
+            // Cannot cast transferable.
+            final ComponentReference componentReference = (ComponentReference) transferable
+                    .getTransferData(ComponentSourceTransferable.FLAVOR);
+            final Point location = event.getLocation();
+
+            // The component might not have loaded if the network is slow.
+            new Thread() {
+                @Override
+                public void run() {
+                    try {
+                        Component component = componentReference.getComponent();
+                        addNode(component, location);
+                        // To be able to delete the added node by the keyboard.
+                        GraphCanvas.this.panel.requestFocusInWindow();
+                        // XXX this sometimes throws exception.
+                        event.dropComplete(true);
+                    } catch (ComponentException e) {
+                        // If there is any error, the component tree viewer
+                        // shows the error dialog.
+                        logger.error(e.getMessage(), e);
+                        event.dropComplete(false);
+                    } catch (ComponentRegistryException e) {
+                        logger.error(e.getMessage(), e);
+                        event.dropComplete(false);
+                    }
+                }
+            }.start();
+
+        } catch (UnsupportedFlavorException e) {
+            // Should not happen.
+            logger.error(e.getMessage(), e);
+        } catch (IOException e) {
+            // Should not happen.
+            logger.error(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * @return The image
+     */
+    private BufferedImage createImage() {
+        Rectangle bounds = NodeController.getGUI(this.graph).getBounds();
+        BufferedImage image = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D graphics = image.createGraphics();
+
+        // Background
+        final Color background = new Color(226, 226, 222);
+        graphics.setBackground(background);
+        graphics.clearRect(0, 0, bounds.width, bounds.height);
+
+        paintComponent(graphics);
+
+        return image;
+    }
+
+    /**
+     * Connects two ports specified.
+     * 
+     * @param fromPort
+     * @param toPort
+     */
+    private void connect(Port fromPort, Port toPort) {
+        try {
+            // check the validity of the connection.
+            Edge edge = this.graph.addEdge(fromPort, toPort);
+            selectEdge(edge);
+        } catch (GraphException e) {
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().warning(e.getMessage());
+        } catch (RuntimeException e) {
+            logger.error(e.getMessage(), e);
+            this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR);
+        }
+    }
+
+    private void paintComponent(Graphics2D g) {
+        NodeController.getGUI(this.graph).paint(g);
+
+        // Draws a creating edge.
+        if (this.draggedPort != null) {
+            Point p1, p2;
+            Kind kind = this.draggedPort.getKind();
+            if (kind == Kind.DATA_OUT || kind == Kind.CONTROL_OUT || kind == Kind.EPR) {
+                p1 = NodeController.getGUI(this.draggedPort).getPosition();
+                p2 = this.mousePoint;
+            } else if (kind == Kind.DATA_IN || kind == Kind.CONTROL_IN) {
+                p1 = this.mousePoint;
+                p2 = NodeController.getGUI(this.draggedPort).getPosition();
+            } else {
+                // This should not happen.
+                throw new WorkflowRuntimeException();
+            }
+            g.setColor(Color.RED);
+
+            Stroke originalStroke = g.getStroke();
+            if (kind == Kind.CONTROL_IN || kind == Kind.CONTROL_OUT) {
+                g.setStroke(EdgeGUI.CONTROL_EDGE_STROKE);
+            }
+            EdgeGUI.paintLine(p1, p2, g);
+            g.setStroke(originalStroke);
+
+        }
+
+        // Draw rectangular for selection
+        if (this.mousePointForSelection != null) {
+            double width = Math.abs(this.mousePoint.getX() - this.mousePointForSelection.getX());
+            double height = Math.abs(this.mousePoint.getY() - this.mousePointForSelection.getY());
+            int x = (int) (this.mousePoint.getX() > this.mousePointForSelection.getX() ? this.mousePointForSelection
+                    .getX() : this.mousePoint.getX());
+            int y = (int) (this.mousePoint.getY() > this.mousePointForSelection.getY() ? this.mousePointForSelection
+                    .getY() : this.mousePoint.getY());
+            g.setColor(Color.RED);
+            g.setStroke(new BasicStroke(1.0f, BasicStroke.CAP_ROUND, // End cap
+                                                                     // style
+                    BasicStroke.JOIN_MITER, // Join style
+                    15.0f, // Miter limit
+                    new float[] { 5.0f, 5.0f }, // Dash pattern
+                    3.0f)); // Dash phase
+            g.drawRect(x, y, (int) width, (int) height);
+        }
+    }
+
+    /**
+     * Gets an random position of for a new node. This method is called when a new node is added to the graph.
+     * 
+     * @return The position
+     */
+    private Point getRandomPosition() {
+        Rectangle area = this.panel.getVisibleRect();
+        int x = (int) (area.x + (area.width - NodeGUI.MINIMUM_WIDTH) * Math.random());
+        int y = (int) (area.y + (area.height - NodeGUI.MINIMUM_HEIGHT) * Math.random());
+        return new Point(x, y);
+    }
+
+    /**
+     * Updates the size of this Panel.
+     */
+    private void updateSize() {
+
+        Rectangle bounds = NodeController.getGUI(this.graph).getBounds();
+        Dimension newDimention = new Dimension(bounds.width, bounds.height);
+
+        if (!newDimention.equals(this.graphDimention)) {
+
+            // Updates this Panel's preferred size because the area taken up by
+            // the graph has changed.
+            this.panel.setPreferredSize(newDimention);
+
+            // Let the scroll pane know to update itself and its scrollbars.
+            this.panel.revalidate();
+
+            this.graphDimention = newDimention;
+        }
+    }
+
+    /**
+     * Sets the selected node.
+     * 
+     * Use this method to send the event to the listeners.
+     * 
+     * @param node
+     */
+    private void setSelectedNode(Node node) {
+        this.selectedNode = node;
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.NODE_SELECTED, this, this.workflow));
+    }
+
+    /**
+     * Selects a node. The selected node changes its color.
+     * 
+     * @param node
+     *            The node to select.
+     */
+    private void selectNode(Node node) {
+        deselectNode();
+        NodeController.getGUI(node).setSelectedFlag(true);
+        setSelectedNode(node);
+    }
+
+    private void selectNodes(List<Node> nodes) {
+        deselectNode();
+        for (Node node : nodes) {
+            NodeController.getGUI(node).setSelectedFlag(true);
+            NodeController.getGUI(node).setDraggedFlag(true);
+        }
+        this.multipleSelectedNodes = nodes;
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.NODE_SELECTED, this, this.workflow));
+    }
+
+    /**
+     * Deselects a node that is currently selected if any.
+     */
+    private void deselectNode() {
+        if (this.selectedNode != null) {
+            NodeController.getGUI(this.selectedNode).setSelectedFlag(false);
+            NodeController.getGUI(this.selectedNode).setDraggedFlag(false);
+            setSelectedNode(null);
+        }
+        if (this.multipleSelectedNodes != null) {
+            for (Node node : this.multipleSelectedNodes) {
+                NodeController.getGUI(node).setSelectedFlag(false);
+                NodeController.getGUI(node).setDraggedFlag(false);
+            }
+            this.multipleSelectedNodes = null;
+        }
+    }
+
+    private void deselectNode(Node node) {
+        if (this.multipleSelectedNodes != null && this.multipleSelectedNodes.contains(node)) {
+            NodeController.getGUI(node).setSelectedFlag(false);
+            NodeController.getGUI(node).setDraggedFlag(false);
+            this.multipleSelectedNodes.remove(node);
+        }
+    }
+
+    private void setSelectedInputPort(Port port) {
+        this.selectedInputPort = port;
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.INPUT_PORT_SELECTED, this,
+                this.workflow));
+    }
+
+    private void selectInputPort(Port port) {
+        deselectInputPort();
+        NodeController.getGUI(port).setSelectedFlag(true);
+        setSelectedInputPort(port);
+    }
+
+    private void deselectInputPort() {
+        if (this.selectedInputPort != null) {
+        	NodeController.getGUI(this.selectedInputPort).setSelectedFlag(false);
+            setSelectedInputPort(null);
+        }
+    }
+
+    private void setSelectedOutputPort(Port port) {
+        this.selectedOutputPort = port;
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.OUTPUT_PORT_SELECTED, this,
+                this.workflow));
+    }
+
+    private void selectOutputPort(Port port) {
+        deselectOutputPort();
+        NodeController.getGUI(port).setSelectedFlag(true);
+        setSelectedOutputPort(port);
+    }
+
+    private void deselectOutputPort() {
+        if (this.selectedOutputPort != null) {
+        	NodeController.getGUI(this.selectedOutputPort).setSelectedFlag(false);
+            setSelectedOutputPort(null);
+        }
+    }
+
+    private void selectEdge(Edge edge) {
+        if (edge != null) {
+            deselectEdge();
+            NodeController.getGUI(edge).setSelectedFlag(true);
+            this.selectedEdge = edge;
+
+            // When an edge is selected, ports on both sides will be selected
+            // too.
+            selectOutputPort(edge.getFromPort());
+            selectInputPort(edge.getToPort());
+        }
+    }
+
+    private void deselectEdge() {
+        if (this.selectedEdge != null) {
+        	NodeController.getGUI(this.selectedEdge).setSelectedFlag(false);
+            this.selectedEdge = null;
+        }
+    }
+
+    private void reset() {
+        setSelectedNode(null);
+        this.draggedNode = null;
+        setSelectedInputPort(null);
+        setSelectedOutputPort(null);
+        this.selectedEdge = null;
+        this.multipleSelectedNodes = null;
+    }
+
+    private void notifyListeners(GraphCanvasEvent event) {
+        for (GraphCanvasListener listener : this.listeners) {
+            listener.graphCanvasChanged(event);
+        }
+    }
+
+    /**
+     * Initializes the GUI.
+     */
+    private void initGUI() {
+        this.panel = new JPanel() {
+            @Override
+            protected void paintComponent(Graphics g) {
+                super.paintComponent(g);
+                GraphCanvas.this.paintComponent((Graphics2D) g);
+            }
+        };
+
+        this.panel.setLayout(null);
+        this.panel.setOpaque(true); // To make the background color visible.
+        this.panel.setBackground(new Color(255, 255, 255));
+        this.panel.setDoubleBuffered(true);
+
+        this.panel.addMouseListener(new MouseAdapter() {
+
+            @Override
+            public void mouseClicked(MouseEvent event) {
+                GraphCanvas.this.mouseClicked(event);
+            }
+
+            @Override
+            public void mousePressed(MouseEvent event) {
+                GraphCanvas.this.mousePressed(event);
+            }
+
+            @Override
+            public void mouseReleased(MouseEvent event) {
+                GraphCanvas.this.mouseReleased(event);
+                notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.WORKFLOW_CHANGED, GraphCanvas.this, GraphCanvas.this.workflow));
+            }
+        });
+
+        this.panel.addMouseMotionListener(new MouseMotionListener() {
+
+            public void mouseDragged(MouseEvent event) {
+                GraphCanvas.this.mouseDragged(event);
+            }
+
+            public void mouseMoved(MouseEvent event) {
+                GraphCanvas.this.mouseMoved(event);
+            }
+        });
+
+        this.panel.addKeyListener(new KeyAdapter() {
+            @Override
+            public void keyPressed(KeyEvent event) {
+                GraphCanvas.this.keyPressed(event);
+            }
+
+            @Override
+            public void keyReleased(KeyEvent event) {
+                GraphCanvas.this.keyReleased(event);
+            }
+
+        });
+
+        this.scrollPane = new JScrollPane(this.panel);
+
+        // Set up drag and drop
+        DropTargetListener dropTargetListener = new DropTargetAdapter() {
+            public void drop(DropTargetDropEvent event) {
+                GraphCanvas.this.drop(event);
+            }
+        };
+        new DropTarget(this.panel, DnDConstants.ACTION_COPY_OR_MOVE, dropTargetListener);
+
+        createPopupMenu();
+    }
+
+    private void createPopupMenu() {
+        createEdgePopupMenu();
+        createNodePopupMenu();
+    }
+
+    private void createNodePopupMenu() {
+        this.nodePopup = new JPopupMenu();
+        if (editable) {
+			JMenuItem deleteItem = new JMenuItem("Delete");
+			deleteItem.addActionListener(new AbstractAction() {
+				public void actionPerformed(ActionEvent event) {
+					try {
+						removeSelectedNode();
+					} catch (GraphException e) {
+						// Should not happen
+						logger.error(e.getMessage(), e);
+						GraphCanvas.this.engine.getGUI().getErrorWindow()
+								.error(ErrorMessages.UNEXPECTED_ERROR, e);
+					} catch (RuntimeException e) {
+						logger.error(e.getMessage(), e);
+						GraphCanvas.this.engine.getGUI().getErrorWindow()
+								.error(ErrorMessages.UNEXPECTED_ERROR, e);
+					} catch (Error e) {
+						logger.error(e.getMessage(), e);
+						GraphCanvas.this.engine.getGUI().getErrorWindow()
+								.error(ErrorMessages.UNEXPECTED_ERROR, e);
+					}
+
+				}
+			});
+			this.nodePopup.add(deleteItem);
+		}
+		rerunItem = new JMenuItem("ReRun");
+        rerunItem.addActionListener(new AbstractAction() {
+            public void actionPerformed(ActionEvent event) {
+                try {
+                    rerunSelectedNode();
+                } catch (RuntimeException e) {
+                    logger.error(e.getMessage(), e);
+                    GraphCanvas.this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+                } catch (Error e) {
+                    logger.error(e.getMessage(), e);
+                    GraphCanvas.this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+                }
+
+            }
+        });
+
+        breakPointItem = new JMenuItem("Add break Point");
+        breakPointItem.addActionListener(new AbstractAction() {
+            public void actionPerformed(ActionEvent event) {
+                try {
+                    toggleBreakPointToNode();
+                } catch (RuntimeException e) {
+                    logger.error(e.getMessage(), e);
+                    GraphCanvas.this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+                } catch (Error e) {
+                    logger.error(e.getMessage(), e);
+                    GraphCanvas.this.engine.getGUI().getErrorWindow().error(ErrorMessages.UNEXPECTED_ERROR, e);
+                }
+
+            }
+        });
+  
+
+    }
+
+    private synchronized void toggleBreakPointToNode() {
+        if (this.selectedNode != null) {
+            this.selectedNode.setBreak(!this.selectedNode.isBreak());
+            this.repaint();
+        }
+    }
+
+    private void rerunSelectedNode() {
+        if (this.selectedNode != null) {
+
+            ArrayList<Node> exploreNodes = new ArrayList<Node>();
+            exploreNodes.add(this.selectedNode);
+            while (exploreNodes.size() != 0) {
+                Node node = exploreNodes.get(0);
+                List<DataPort> outputPorts = node.getOutputPorts();
+                for (DataPort dataPort : outputPorts) {
+                    exploreNodes.addAll(dataPort.getToNodes());
+                }
+                node.setState(NodeExecutionState.WAITING);
+
+                exploreNodes.remove(0);
+            }
+            this.repaint();
+        }
+    }
+
+    private void prepareNodePopupMenu(Node node) {
+        this.nodePopup.remove(rerunItem);
+        this.nodePopup.remove(breakPointItem);
+
+        if (this.engine.getGUI().getWorkflow().getExecutionState() == WorkflowExecutionState.PAUSED && !(node instanceof InputNode)) {
+            this.nodePopup.add(rerunItem);
+
+        }
+        if (this.engine.getGUI().getWorkflow().getExecutionState() != WorkflowExecutionState.NONE) {
+            if (node.isBreak()) {
+                breakPointItem.setText("Remove break Point");
+            } else {
+                breakPointItem.setText("Add break Point");
+            }
+            this.nodePopup.add(breakPointItem);
+        }
+       
+    }
+
+    private void createEdgePopupMenu() {
+        this.edgePopup = new JPopupMenu();
+        if (editable) {
+			JMenuItem deleteItem = new JMenuItem("Delete");
+			deleteItem.addActionListener(new AbstractAction() {
+				private static final long serialVersionUID = 1L;
+
+				public void actionPerformed(ActionEvent e) {
+					removeSelectedEdge();
+				}
+			});
+			this.edgePopup.add(deleteItem);
+		}
+    }
+
+    private void maybeShowPopup(MouseEvent event) {
+        if (event.isPopupTrigger()) {
+            GraphPiece piece = NodeController.getGUI(this.graph).getGraphPieceAt(event.getPoint());
+            if (piece instanceof Node) {
+                prepareNodePopupMenu((Node) piece);
+                this.nodePopup.show(event.getComponent(), event.getX(), event.getY());
+            } else if (piece instanceof Edge) {
+                this.edgePopup.show(event.getComponent(), event.getX(), event.getY());
+            }
+        }
+    }
+
+
+	public File getWorkflowFile() {
+		return workflowFile;
+	}
+
+	public void setWorkflowFile(File workflowFile) {
+		this.workflowFile = workflowFile;
+	}
+	
+	public boolean isWorkflowChanged(){
+		try {
+			if (originalWorkflowElement==null){
+				updateOriginalWorkflowElement();
+			}
+			return !XMLUtil.isEqual(originalWorkflowElement, getWorkflow().toXML());
+		} catch (Exception e) {
+			e.printStackTrace();
+			return true;
+		}
+	}
+	
+	public void workflowSaved(){
+		updateOriginalWorkflowElement();
+        notifyListeners(new GraphCanvasEvent(GraphCanvasEvent.GraphCanvasEventType.WORKFLOW_CHANGED, this, this.workflow));
+	}
+
+	private void updateOriginalWorkflowElement() {
+		originalWorkflowElement = getWorkflow().toXML();
+	}
+
+	@Override
+	public void executionModeChanged(XBayaConfiguration config) {
+		editable=config.getXbayaExecutionMode()==XBayaExecutionMode.IDE;
+		getGraph().setEditable(editable);
+		this.workflow.setEditable(config.getXbayaExecutionMode()==XBayaExecutionMode.IDE);
+	}
+}
\ 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/GraphCanvasEvent.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvasEvent.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvasEvent.java
new file mode 100644
index 0000000..1d96da3
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvasEvent.java
@@ -0,0 +1,99 @@
+/*
+ *
+ * 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 org.apache.airavata.workflow.model.wf.Workflow;
+
+public class GraphCanvasEvent {
+
+    /**
+     * The type of an event.
+     */
+    public enum GraphCanvasEventType {
+        /**
+         * A graph was loaded.
+         */
+        GRAPH_LOADED,
+        /**
+         * The name or the description of the workflow has changed.
+         */
+        NAME_CHANGED,
+        /**
+         * A node is selected.
+         */
+        NODE_SELECTED,
+        /**
+         * An input port is selected.
+         */
+        INPUT_PORT_SELECTED,
+        /**
+         * An output port is selected.
+         */
+        OUTPUT_PORT_SELECTED,
+        
+        /**
+         * Event when the workflow was changed
+         */
+        WORKFLOW_CHANGED
+    }
+
+    private GraphCanvasEventType type;
+
+    private GraphCanvas graphCanvas;
+
+    private Workflow workflow;
+
+    /**
+     * Constructs a GraphPanelEvent.
+     * 
+     * @param type
+     * @param canvas
+     * @param workflow
+     */
+    public GraphCanvasEvent(GraphCanvasEventType type, GraphCanvas canvas, Workflow workflow) {
+        this.type = type;
+        this.graphCanvas = canvas;
+        this.workflow = workflow;
+    }
+
+    /**
+     * @return The type of the event
+     */
+    public GraphCanvasEventType getType() {
+        return this.type;
+    }
+
+    /**
+     * @return The graph panel
+     */
+    public GraphCanvas getGraphCanvas() {
+        return this.graphCanvas;
+    }
+
+    /**
+     * @return The graph
+     */
+    public Workflow getWorkflow() {
+        return this.workflow;
+    }
+
+}
\ 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/GraphCanvasListener.java
----------------------------------------------------------------------
diff --git a/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvasListener.java b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvasListener.java
new file mode 100644
index 0000000..b9168fb
--- /dev/null
+++ b/modules/xbaya-gui/src/main/java/org/apache/airavata/xbaya/ui/graph/GraphCanvasListener.java
@@ -0,0 +1,32 @@
+/*
+ *
+ * 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;
+
+public interface GraphCanvasListener {
+
+    /**
+     * Called when a graph changes
+     * 
+     * @param event
+     */
+    public void graphCanvasChanged(GraphCanvasEvent event);
+}
\ No newline at end of file