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