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 2012/05/17 19:12:21 UTC

svn commit: r1339718 [3/10] - in /incubator/airavata/trunk: ./ modules/airavata-client/ modules/distribution/ modules/distribution/src/main/assembly/ modules/workflow-model/ modules/workflow-model/src/ modules/workflow-model/src/main/ modules/workflow-...

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentKey.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentKey.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentKey.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentKey.java Thu May 17 17:12:15 2012
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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.workflow.model.component.ws;
+
+import javax.xml.namespace.QName;
+
+public class WSComponentKey {
+
+    private final String id;
+
+    private final QName portType;
+
+    private final String operation;
+
+    /**
+     * Constructs a WSComponentKey.
+     * 
+     * @param id
+     * @param portType
+     * @param operation
+     */
+    public WSComponentKey(String id, QName portType, String operation) {
+        this.id = id;
+        this.portType = portType;
+        this.operation = operation;
+    }
+
+    /**
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    @Override
+    public boolean equals(Object object) {
+        if (object == null || !(object instanceof WSComponentKey)) {
+            return false;
+        }
+        WSComponentKey key = (WSComponentKey) object;
+        return this.id.equals(key.id) && this.portType.equals(key.portType) && this.operation.equals(key.operation);
+    }
+
+    /**
+     * @see java.lang.Object#hashCode()
+     */
+    @Override
+    public final int hashCode() {
+        return this.id.hashCode() ^ this.portType.hashCode() ^ this.operation.hashCode();
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentPort.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentPort.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentPort.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WSComponentPort.java Thu May 17 17:12:15 2012
@@ -0,0 +1,240 @@
+/*
+ *
+ * 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.workflow.model.component.ws;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.common.utils.WSConstants;
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.component.ComponentDataPort;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.graph.ws.WSPort;
+import org.xmlpull.infoset.XmlElement;
+import org.xmlpull.infoset.XmlNamespace;
+
+import xsul5.XmlConstants;
+
+public class WSComponentPort extends ComponentDataPort {
+
+    /**
+     * default
+     */
+    public static final String DEFAULT = "default";
+
+    private WSComponent component;
+
+    private XmlElement elementElement;
+
+    private Object value;
+
+    private String defaultValue;
+
+    private String targetNamespace;
+
+    private boolean schemaUsed;
+
+    private XmlElement annotation;
+
+    private XmlElement appinfo;
+
+    private boolean optional;
+
+    /**
+     * Creates WSComponentPort
+     * 
+     * @param name
+     *            The name
+     * @param type
+     *            The type
+     * @param component
+     */
+    public WSComponentPort(String name, QName type, WSComponent component) {
+        super(name);
+        this.component = component;
+        this.type = type;
+        this.schemaUsed = false;
+    }
+
+    protected WSComponentPort(XmlElement element, String targetNamespace, WSComponent component)
+            throws ComponentException {
+        this.component = component;
+        this.elementElement = element;
+        this.targetNamespace = targetNamespace;
+        this.schemaUsed = true;
+        parse(element);
+    }
+
+    /**
+     * @return The component
+     */
+    public WSComponent getComponent() {
+        return this.component;
+    }
+
+    /**
+     * @return The port created.
+     */
+    @Override
+    public WSPort createPort() {
+        WSPort port = new WSPort();
+        port.setName(this.name);
+        // port.setTypeQName(this.type);
+        port.setComponentPort(this);
+        return port;
+    }
+
+    /**
+     * @return true if schema is used; false otherwise.
+     */
+    public boolean isSchemaUsed() {
+        return this.schemaUsed;
+    }
+
+    /**
+     * @return The targetNamespace
+     */
+    public String getTargetNamespace() {
+        return this.targetNamespace;
+    }
+
+    /**
+     * @return The element.
+     */
+    public XmlElement getElement() {
+        return this.elementElement;
+    }
+
+    /**
+     * Returns the defaultValue.
+     * 
+     * @return The defaultValue
+     */
+    public String getDefaultValue() {
+        return this.defaultValue;
+    }
+
+    /**
+     * Sets defaultValue.
+     * 
+     * @param defaultValue
+     *            The defaultValue to set.
+     */
+    public void setDefaultValue(String defaultValue) {
+        this.defaultValue = defaultValue;
+    }
+
+    /**
+     * Returns the value.
+     * 
+     * @return The value. The value is either String (or any other object possibly) or XmlElement.
+     */
+    public Object getValue() {
+        return this.value;
+    }
+
+    /**
+     * Sets value.
+     * 
+     * @param value
+     *            The value to set. The value is either String (or any other object possibly) or XmlElement.
+     */
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    /**
+     * @return The appinfo element.
+     */
+    public XmlElement getAppinfo() {
+        return this.appinfo;
+    }
+
+    /**
+     * @return true if it's optional; false otherwise.
+     */
+    public boolean isOptional() {
+        return this.optional;
+    }
+
+    /**
+     * @param element
+     * @throws ComponentException
+     */
+    private void parse(XmlElement element) throws ComponentException {
+        this.name = element.attributeValue(WSConstants.NAME_ATTRIBUTE);
+
+        // type
+        String typeQNameString = element.attributeValue(WSConstants.TYPE_ATTRIBUTE);
+        if (typeQNameString == null) {
+            // Type might be defined inline.
+            // TODO fix this.
+            this.type = WSConstants.XSD_ANY_TYPE;
+        } else {
+            String typeName = XMLUtil.getLocalPartOfQName(typeQNameString);
+            String prefix = XMLUtil.getPrefixOfQName(typeQNameString);
+            XmlNamespace namespace = null;
+            if (prefix == null) {
+                if ("string".equals(typeName) || "int".equals(typeName)) {
+                    namespace = XmlConstants.BUILDER.newNamespace("xsd", WSConstants.XSD_NS_URI);
+                    prefix = "xsd";
+                } else {
+                    throw new ComponentException("Namespace prefix, " + prefix + ", is not defined");
+                }
+            } else {
+                namespace = element.lookupNamespaceByPrefix(prefix);
+            }
+            this.type = new QName(namespace.getName(), typeName, prefix);
+        }
+
+        // annotation
+        this.annotation = element.element(null, WSConstants.ANNOTATION_TAG);
+        if (this.annotation != null) {
+            XmlElement documentationElement = this.annotation.element(null, WSConstants.DOCUMENTATION_TAG);
+            if (documentationElement != null) {
+                // Sets the documentation.
+                this.description = documentationElement.requiredText();
+            }
+            this.appinfo = this.annotation.element(null, WSConstants.APPINFO_TAG);
+        }
+
+        // defaut value
+        this.defaultValue = element.attributeValue(WSConstants.DEFAULT_ATTRIBUTE);
+        if (this.defaultValue == null && this.annotation != null) {
+            XmlElement defaultElement = this.annotation.element(null, DEFAULT);
+            if (defaultElement != null) {
+                for (Object child : defaultElement.children()) {
+                    if (child instanceof XmlElement) {
+                        this.defaultValue = XMLUtil.xmlElementToString((XmlElement) child);
+                    }
+                }
+            }
+        }
+
+        // minOccurs
+        String minOccurs = element.attributeValue(WSConstants.MIN_OCCURS_ATTRIBUTE);
+        if ("0".equals(minOccurs)) {
+            this.optional = true;
+        } else {
+            this.optional = false;
+        }
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WorkflowComponent.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WorkflowComponent.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WorkflowComponent.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/component/ws/WorkflowComponent.java Thu May 17 17:12:15 2012
@@ -0,0 +1,168 @@
+/*
+ *
+ * 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.workflow.model.component.ws;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.common.exception.UtilsException;
+import org.apache.airavata.common.utils.WSDLUtil;
+import org.apache.airavata.workflow.model.component.ComponentException;
+import org.apache.airavata.workflow.model.graph.Graph;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.ws.WorkflowNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.gpel.GpelConstants;
+import org.xmlpull.infoset.XmlElement;
+import org.xmlpull.infoset.XmlNamespace;
+
+import xsul5.wsdl.WsdlDefinitions;
+import xsul5.wsdl.WsdlPortType;
+
+public class WorkflowComponent extends WSComponent {
+
+    /**
+     * GPEL_NAMESPACE
+     */
+    public static final XmlNamespace GPEL_NAMESPACE = GpelConstants.GPEL_NS;
+
+    /**
+     * workflowTemplateID
+     */
+    public static final String WORKFLOW_TEMPLATE_ID_TAG = "workflowTemplateID";
+
+    protected Workflow workflow;
+
+    private URI templateID;
+
+    /**
+     * Constructs a WorkflowComponent.
+     * 
+     * This method is used when loading a workflow component from GPEL.
+     * 
+     * @param workflow
+     * @throws ComponentException
+     */
+    public WorkflowComponent(Workflow workflow) throws ComponentException {
+        super(workflow.getWorkflowWSDL());
+        this.workflow = workflow;
+        this.templateID = this.workflow.getGPELTemplateID();
+
+        // Add template ID to WSDL
+        for (WsdlPortType portType : this.wsdl.portTypes()) {
+            XmlElement templateIDElement = portType.xml().addElement(GPEL_NAMESPACE, WORKFLOW_TEMPLATE_ID_TAG);
+            templateIDElement.setText(this.templateID.toString());
+        }
+    }
+
+    /**
+     * Returns the templateID.
+     * 
+     * @return The templateID
+     */
+    public URI getTemplateID() {
+        return this.templateID;
+    }
+
+    /**
+     * Constructs a WorkflowComponent.
+     * 
+     * This method is used when loading a workflow component from an xwf file.
+     * 
+     * @param wsdl
+     * @param portTypeQName
+     * @param operationName
+     * @throws ComponentException
+     */
+    public WorkflowComponent(WsdlDefinitions wsdl, QName portTypeQName, String operationName) throws ComponentException {
+        super(wsdl, portTypeQName, operationName);
+        try {
+            // Get template ID from WSDL
+            WsdlPortType portType = this.wsdl.getPortType(portTypeQName.getLocalPart());
+            XmlElement templateIDElement = portType.xml().element(GPEL_NAMESPACE, WORKFLOW_TEMPLATE_ID_TAG);
+            String templateIDString = templateIDElement.requiredText();
+            this.templateID = new URI(templateIDString);
+        } catch (URISyntaxException e) {
+            throw new ComponentException(e);
+        }
+    }
+
+    /**
+     * @param workflowClient
+     * @return The workflow
+     * @throws ComponentException
+     * @throws WorkflowEngineException
+     * @throws GraphException
+     */
+    public Workflow getWorkflow() throws GraphException, ComponentException {
+        return this.workflow;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.component.ws.WSComponent#createNode(org.apache.airavata.workflow.model.graph.Graph)
+     */
+    @Override
+    public WorkflowNode createNode(Graph graph) {
+        WorkflowNode node = new WorkflowNode(graph);
+
+        // Copy some infomation from the component
+
+        node.setName(getName());
+        node.setComponent(this);
+        // node.setWSDLQName(this.wsdlQName);
+
+        // Creates a unique ID for the node. This has to be after setName().
+        node.createID();
+
+        // Creat ports
+        createPorts(node);
+
+        return node;
+    }
+
+    /**
+     * @param definitions
+     * @return workflow template ID if the specified WSDL definition is for a workflow; null otherwise.
+     * @throws ComponentException
+     */
+    public static URI getWorkflowTemplateID(WsdlDefinitions definitions) throws ComponentException {
+        try {
+            // Get template ID from WSDL
+            WsdlPortType portType = WSDLUtil.getFirstPortType(definitions);
+            XmlElement templateIDElement = portType.xml().element(GPEL_NAMESPACE, WORKFLOW_TEMPLATE_ID_TAG);
+            if (templateIDElement == null) {
+                // Not a workflow
+                return null;
+            } else {
+                String templateIDString = templateIDElement.requiredText();
+                URI templateID = new URI(templateIDString);
+                return templateID;
+            }
+        } catch (URISyntaxException e) {
+            throw new ComponentException(e);
+        } catch (UtilsException e) {
+            throw new ComponentException(e);
+        }
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowException.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowException.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowException.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowException.java Thu May 17 17:12:15 2012
@@ -0,0 +1,62 @@
+/*
+ *
+ * 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.workflow.model.exceptions;
+
+public class WorkflowException extends Exception {
+
+    /**
+     * Constructs a XBayaException.
+     * 
+     */
+    public WorkflowException() {
+        super();
+    }
+
+    /**
+     * Constructs a XBayaException.
+     * 
+     * @param message
+     */
+    public WorkflowException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a XBayaException.
+     * 
+     * @param cause
+     */
+    public WorkflowException(Throwable cause) {
+        super(cause);
+    }
+
+    /**
+     * Constructs a XBayaException.
+     * 
+     * @param message
+     * @param cause
+     */
+    public WorkflowException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowRuntimeException.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowRuntimeException.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowRuntimeException.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/exceptions/WorkflowRuntimeException.java Thu May 17 17:12:15 2012
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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.workflow.model.exceptions;
+
+public class WorkflowRuntimeException extends RuntimeException {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *  
+     */
+    public WorkflowRuntimeException() {
+        super();
+    }
+
+    /**
+     * @param arg0
+     */
+    public WorkflowRuntimeException(String arg0) {
+        super(arg0);
+    }
+
+    /**
+     * @param arg0
+     */
+    public WorkflowRuntimeException(Throwable arg0) {
+        super(arg0);
+    }
+
+    /**
+     * @param arg0
+     * @param arg1
+     */
+    public WorkflowRuntimeException(String arg0, Throwable arg1) {
+        super(arg0, arg1);
+    }
+
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/DSCUtil.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/DSCUtil.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/DSCUtil.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/DSCUtil.java Thu May 17 17:12:15 2012
@@ -0,0 +1,130 @@
+/*
+ *
+ * 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.workflow.model.gpel;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.common.exception.UtilsException;
+import org.apache.airavata.common.utils.WSDLUtil;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.apache.airavata.workflow.model.gpel.script.BPELScript;
+import org.apache.airavata.workflow.model.graph.Graph;
+import org.apache.airavata.workflow.model.graph.util.GraphUtil;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.wf.Workflow;
+
+import xsul5.wsdl.WsdlDefinitions;
+import xsul5.wsdl.WsdlPortType;
+import xsul5.wsdl.WsdlResolver;
+import xsul5.wsdl.WsdlUtil;
+
+public class DSCUtil {
+
+    /**
+     * For debugging
+     * 
+     * @param args
+     */
+    public static void main(String[] args) {
+        WsdlDefinitions awsdl = WsdlResolver.getInstance().loadWsdl(DSCUtil.class, "wsdls/math/adder-awsdl.xml");
+        WsdlDefinitions cwsdl = convertToCWSDL(awsdl, URI.create("http://localhost"));
+        System.out.println(cwsdl.xmlStringPretty());
+    }
+
+    /**
+     * Creates CWSDLs for all WSDLs in a workflow.
+     * 
+     * @param workflow
+     * @param dscURL
+     * @return The Map<partnerLinkName, CWSDL>.
+     * @throws URISyntaxException
+     */
+    public static Map<String, WsdlDefinitions> createCWSDLs(Workflow workflow, String dscURL) throws URISyntaxException {
+        return createCWSDLs(workflow, new URI(dscURL));
+    }
+
+    /**
+     * @param workflow
+     * @param dscURL
+     * @return The Map<partnerLinkName, CWSDL>.
+     */
+    public static Map<String, WsdlDefinitions> createCWSDLs(Workflow workflow, URI dscURL) {
+        Map<String, WsdlDefinitions> WSDLMap = new HashMap<String, WsdlDefinitions>();
+        Graph graph = workflow.getGraph();
+        for (WSNode node : GraphUtil.getWSNodes(graph)) {
+            String partnerLinkName = BPELScript.createPartnerLinkName(node.getID());
+            WsdlDefinitions wsdl = node.getComponent().getWSDL();
+            if (WSDLUtil.isAWSDL(wsdl)) {
+                try {
+                    wsdl = convertToCWSDL(WSDLUtil.deepClone(wsdl), dscURL);
+                } catch (UtilsException e) {
+                    e.printStackTrace();
+                }
+            }
+            WSDLMap.put(partnerLinkName, wsdl);
+        }
+        return WSDLMap;
+    }
+
+    /**
+     * Converts a specified AWSDL to CWSDL using DSC URI.
+     * 
+     * @param definitions
+     *            The specified AWSDL. This will be modified.
+     * @param dscURI
+     * @return The CWSDL converted.
+     */
+    public static WsdlDefinitions convertToCWSDL(WsdlDefinitions definitions, URI dscURI) {
+        // Create a new List to avoid ConcurrentModificationException.
+        List<WsdlPortType> portTypes = new ArrayList<WsdlPortType>();
+        for (WsdlPortType portType : definitions.portTypes()) {
+            portTypes.add(portType);
+        }
+
+        for (WsdlPortType portType : portTypes) {
+            URI uri = creatEPR(dscURI, portType.getQName());
+            WsdlUtil.createCWSDL(definitions, portType, uri);
+        }
+        return definitions;
+    }
+
+    private static URI creatEPR(URI dscURI, QName portTypeQName) {
+        String encodedPortType;
+        try {
+            encodedPortType = URLEncoder.encode(portTypeQName.toString(), "UTF-8");
+            URI epr = dscURI.resolve("/" + encodedPortType);
+            return epr;
+        } catch (UnsupportedEncodingException e) {
+            // Should not happen
+            throw new WorkflowRuntimeException(e);
+        }
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScript.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScript.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScript.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScript.java Thu May 17 17:12:15 2012
@@ -0,0 +1,1139 @@
+/*
+ *
+ * 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.workflow.model.gpel.script;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.common.utils.StringUtil;
+import org.apache.airavata.common.utils.WSConstants;
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.component.ComponentPort;
+import org.apache.airavata.workflow.model.component.ws.WSComponent;
+import org.apache.airavata.workflow.model.component.ws.WSComponentPort;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.EPRPort;
+import org.apache.airavata.workflow.model.graph.Graph;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.amazon.InstanceNode;
+import org.apache.airavata.workflow.model.graph.amazon.ResourceNode;
+import org.apache.airavata.workflow.model.graph.system.BlockNode;
+import org.apache.airavata.workflow.model.graph.system.ConstantNode;
+import org.apache.airavata.workflow.model.graph.system.EndBlockNode;
+import org.apache.airavata.workflow.model.graph.system.EndForEachNode;
+import org.apache.airavata.workflow.model.graph.system.EndifNode;
+import org.apache.airavata.workflow.model.graph.system.ExitNode;
+import org.apache.airavata.workflow.model.graph.system.ForEachNode;
+import org.apache.airavata.workflow.model.graph.system.IfNode;
+import org.apache.airavata.workflow.model.graph.system.InputNode;
+import org.apache.airavata.workflow.model.graph.system.MemoNode;
+import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.system.ReceiveNode;
+import org.apache.airavata.workflow.model.graph.system.StreamSourceNode;
+import org.apache.airavata.workflow.model.graph.util.GraphUtil;
+import org.apache.airavata.workflow.model.graph.ws.WSNode;
+import org.apache.airavata.workflow.model.utils.WorkflowConstants;
+import org.apache.airavata.workflow.model.utils.ApplicationVersion;
+import org.apache.airavata.workflow.model.wf.Workflow;
+import org.gpel.GpelConstants;
+import org.gpel.model.GpelAssign;
+import org.gpel.model.GpelAssignCopy;
+import org.gpel.model.GpelAssignCopyFrom;
+import org.gpel.model.GpelAssignCopyTo;
+import org.gpel.model.GpelCondition;
+import org.gpel.model.GpelElse;
+import org.gpel.model.GpelFlow;
+import org.gpel.model.GpelForEach;
+import org.gpel.model.GpelIf;
+import org.gpel.model.GpelInvoke;
+import org.gpel.model.GpelProcess;
+import org.gpel.model.GpelReceive;
+import org.gpel.model.GpelReply;
+import org.gpel.model.GpelScope;
+import org.gpel.model.GpelSequence;
+import org.gpel.model.GpelVariable;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlComment;
+import org.xmlpull.infoset.XmlElement;
+import org.xmlpull.infoset.XmlInfosetBuilder;
+import org.xmlpull.infoset.XmlNamespace;
+
+import xsul5.wsdl.WsdlPortType;
+import xsul5.wsdl.plnk.PartnerLinkRole;
+import xsul5.wsdl.plnk.PartnerLinkType;
+
+public class BPELScript {
+
+    /**
+     * GPELNS
+     */
+    public static final String GPELNS = "http://schemas.gpel.org/2005/grid-process/";
+
+    /**
+     * GPEL
+     */
+    public static final String GPEL = "gpel";
+
+    /**
+     * BPEL
+     */
+    public static final String BPEL = "bpel";
+
+    /**
+     * BPEL2_NS
+     */
+    public static final String BPEL2_NS = "http://docs.oasis-open.org/wsbpel/2.0/process/executable";
+
+    /**
+     * Name of workflow partner link
+     */
+    public static final String WORKFLOW_PARTNER_LINK = "workflowUserPartner";
+
+    private static final String TARGET_NS_NAME = "http://www.extreme.indiana.edu/xwf/bpel/";
+
+    private static final String WORKFLOW_INPUT_NAME = "WorkflowInput";
+
+    private static final String WORKFLOW_OUTPUT_NAME = "WorkflowOutput";
+
+    private static final String PARTNER_LINK_NAME_SUFFIX = "Partner";
+
+    private static final String PARTNER_LINK_TYPE_SUFFIX = "LT";
+
+    private static final String MY_ROLE_SUFFIX = "Provider";
+
+    private static final String PARTNER_ROLE_SUFFIX = "Service";
+
+    private static final String INPUT_SUFFIX = "Input";
+
+    private static final String OUTPUT_SUFFIX = "Output";
+
+    // It's empty to match with node ID.
+    private static final String INVOKE_NAME_PREFIX = "";
+
+    private static final String TYPENS_SUFFIX = "typens";
+
+    private static final String ARRAY_SUFIX = "Array";
+
+    private static final String FOREACH_VALUE_SUFFIX = "Value";
+
+    private static final Logger logger = LoggerFactory.getLogger(BPELScript.class);
+
+    private Workflow workflow;
+
+    private Graph graph;
+
+    private WorkflowWSDL workflowWSDL;
+
+    /**
+     * List of nodes that are not processed yet
+     */
+    private List<Node> remainNodes;
+
+    private GpelProcess process;
+
+    private XmlNamespace targetNamespace;
+
+    private XmlNamespace typesNamespace;
+
+    private String workflowPrefix;
+
+    private XmlNamespace bpelNS;
+
+    /**
+     * 
+     * Constructs a BPELScript.
+     * 
+     * @param workflow
+     */
+    public BPELScript(Workflow workflow) {
+        this(workflow, "Run");
+    }
+
+    /**
+     * Constructs a BPELScript.
+     * 
+     * @param workflow
+     */
+    public BPELScript(Workflow workflow, String operationName) {
+        this.workflow = workflow;
+        this.graph = workflow.getGraph();
+        this.workflowWSDL = new WorkflowWSDL(this.workflow, operationName);
+    }
+
+    /**
+     * Returns the GPEL Process.
+     * 
+     * @return The GPEL Process
+     */
+    public GpelProcess getGpelProcess() {
+        return this.process;
+    }
+
+    /**
+     * @return the WSDL of the workflow
+     */
+    public WorkflowWSDL getWorkflowWSDL() {
+        return this.workflowWSDL;
+    }
+
+    /**
+     * Returns the WSDLs of components in the workflow.
+     * 
+     * @return The WSDLs of components.
+     */
+    public Collection<XmlElement> getWSDLs() {
+        Collection<XmlElement> wsdls = new ArrayList<XmlElement>();
+        for (Node node : this.graph.getNodes()) {
+            if (node instanceof WSNode) {
+                WSNode wsNode = (WSNode) node;
+                WSComponent component = wsNode.getComponent();
+                wsdls.add(component.toXML());
+            }
+        }
+        return wsdls;
+    }
+
+    /**
+     * @param warnings
+     *            returns the warning messages.
+     * @return true if the workflow is valid; false otherwise.
+     */
+    public boolean validate(List<String> warnings) {
+        // Empty
+        if (this.graph.getNodes().size() == 0) {
+            String message = "The workflow is empty.";
+            warnings.add(message);
+        }
+
+        // Input ports need to be connected.
+        Collection<Port> inputPorts = GraphUtil.getPorts(this.graph, Port.Kind.DATA_IN);
+        for (Port inputPort : inputPorts) {
+            ComponentPort componentPort = inputPort.getComponentPort();
+            if (componentPort instanceof WSComponentPort) {
+                WSComponentPort wsComponentPort = (WSComponentPort) componentPort;
+                if (wsComponentPort.isOptional()) {
+                    // optional input.
+                    continue;
+                }
+            }
+            Collection<Port> fromPorts = inputPort.getFromPorts();
+            if (fromPorts.size() == 0) {
+                Node node = inputPort.getNode();
+                String message = node.getID() + " has an unconnected input " + inputPort.getName();
+                warnings.add(message);
+            }
+        }
+
+        // Input nodes need to be connected.
+        List<InputNode> inputNodes = GraphUtil.getNodes(this.graph, InputNode.class);
+        for (InputNode inputNode : inputNodes) {
+            if (inputNode.getPort().getToPorts().size() == 0) {
+                String message = inputNode.getID() + " is not connected to any service.";
+                warnings.add(message);
+            }
+        }
+
+        // Cycle
+        if (GraphUtil.containsCycle(this.graph)) {
+            String message = "There is a cycle in the workflow.";
+            warnings.add(message);
+        }
+
+        // XXX bypass some checks for debugging.
+        String debug = System.getProperty("xbaya.debug");
+        if (!"true".equalsIgnoreCase(debug)) {
+
+            // split/merge are not supported.
+            List<ForEachNode> splitNodes = GraphUtil.getNodes(this.graph, ForEachNode.class);
+            List<EndForEachNode> mergeNodes = GraphUtil.getNodes(this.graph, EndForEachNode.class);
+            if (splitNodes.size() > 0 || mergeNodes.size() > 0) {
+                String message = "Split/merge are not supported yet.";
+                warnings.add(message);
+            }
+
+            // block are not supported.
+            List<BlockNode> blockNodes = GraphUtil.getNodes(this.graph, BlockNode.class);
+            List<EndBlockNode> endBlockNodes = GraphUtil.getNodes(this.graph, EndBlockNode.class);
+            if (blockNodes.size() > 0 || endBlockNodes.size() > 0) {
+                String message = "Blocks/EndBlocks are not supported yet.";
+                warnings.add(message);
+            }
+
+            // // receive is not supported.
+            // List<ReceiveNode> receiveNodes = GraphUtil.getNodes(this.graph,
+            // ReceiveNode.class);
+            // if (receiveNodes.size() > 0) {
+            // String message = "Receive is not supported yet.";
+            // warnings.add(message);
+            // }
+        }
+
+        if (warnings.size() > 0) {
+            return false;
+        } else {
+            // No error.
+            return true;
+        }
+    }
+
+    /**
+     * @throws GraphException
+     */
+    public void create(BPELScriptType type) throws GraphException {
+        try {
+            // Create WSDL for the workflow.
+            // This has to be done before generating the BPEL document.
+            this.workflowWSDL.create();
+
+            this.remainNodes = new LinkedList<Node>(this.graph.getNodes());
+
+            String bpelTargetNamespace = TARGET_NS_NAME + this.graph.getID() + "/";
+
+            this.workflowPrefix = StringUtil.convertToJavaIdentifier(this.graph.getName());
+
+            if (BPELScriptType.BPEL2 == type) {
+                GpelConstants.GPEL_NS = XmlInfosetBuilder.newInstance().newNamespace(BPEL, BPEL2_NS);
+                this.bpelNS = XmlInfosetBuilder.newInstance().newNamespace(BPEL, BPEL2_NS);
+                this.process = new GpelProcess(bpelNS, bpelTargetNamespace);
+            } else if (BPELScriptType.GPEL == type) {
+                GpelConstants.GPEL_NS = XmlInfosetBuilder.newInstance().newNamespace(GPEL, GPELNS);
+                this.bpelNS = XmlInfosetBuilder.newInstance().newNamespace(GPEL, GPELNS);
+                this.process = new GpelProcess(bpelNS, bpelTargetNamespace);
+            } else {
+                throw new GraphException("Unknown BPEL type " + type);
+            }
+
+            // Target namespace of the workflow WSDL
+            this.targetNamespace = this.process.xml().declareNamespace(this.workflowWSDL.getTargetNamespace());
+
+            // Types namespace of the workflow WSDL
+            this.typesNamespace = this.process.xml().declareNamespace(this.workflowWSDL.getTypesNamespace());
+
+            // xsd
+            XMLUtil.declareNamespaceIfNecessary(WSConstants.XSD_NS.getPrefix(), WSConstants.XSD_NS.getName(), false,
+                    this.process.xml());
+
+            this.process.setActivity(createMainSequence());
+
+            // comment
+            addComment();
+
+            // Validate
+            this.process.xmlValidate();
+
+            logger.info(this.process.xmlStringPretty());
+        } catch (RuntimeException e) {
+            throw new GraphException(e);
+        }
+    }
+
+    /**
+     * @param nodeID
+     * @return The partner link name.
+     */
+    public static String createPartnerLinkName(String nodeID) {
+        return nodeID + PARTNER_LINK_NAME_SUFFIX;
+    }
+
+    private void addComment() {
+        XmlComment comment = this.process.xml().newComment(
+                "\nThis document is automatically generated by " + WorkflowConstants.APPLICATION_NAME + " "
+                        + ApplicationVersion.VERSION + ".\n");
+        this.process.xml().insertChild(0, "\n");
+        this.process.xml().insertChild(0, comment);
+        this.process.xml().insertChild(0, "\n");
+    }
+
+    private GpelSequence createMainSequence() throws GraphException {
+        GpelSequence sequence = new GpelSequence(this.bpelNS);
+
+        // Remove InputNodes and MemoNodes.
+        removeUnnecessaryNodes(this.remainNodes);
+
+        addInitialReceive(sequence);
+
+        addBlock(this.remainNodes, sequence);
+
+        addFinalReply(sequence);
+
+        if (this.remainNodes.size() > 0) {
+            throw new GraphException("Some node(s) are not connected.");
+        }
+
+        return sequence;
+    }
+
+    private void addInitialReceive(GpelSequence sequence) {
+        // Create a partner link
+        String partnerLinkName = WORKFLOW_PARTNER_LINK;
+        XmlNamespace partnerLinkTypeNS = this.workflowWSDL.getTargetNamespace();
+        String partnerLinkTypeName = this.workflowPrefix + PARTNER_LINK_TYPE_SUFFIX;
+        String myRollName = this.workflowPrefix + MY_ROLE_SUFFIX;
+
+        this.process.addPartnerLink(partnerLinkName, partnerLinkTypeNS, partnerLinkTypeName, myRollName, null);
+        this.workflowWSDL.addPartnerLinkTypeAndRoll(partnerLinkTypeName, myRollName,
+                this.workflowWSDL.getPortTypeQName());
+
+        // Create a variable
+        this.process.addMessageVariable(WORKFLOW_INPUT_NAME, this.targetNamespace,
+                this.workflowWSDL.getWorkflowInputMessageName());
+
+        GpelReceive receive = new GpelReceive(this.bpelNS, WORKFLOW_PARTNER_LINK, this.workflowWSDL.getPortTypeQName(),
+                this.workflowWSDL.getWorkflowOperationName());
+        receive.setGpelVariableName(WORKFLOW_INPUT_NAME);
+        sequence.addActivity(receive);
+    }
+
+    private void addFinalReply(GpelSequence sequence) throws GraphException {
+        // Create a variable
+        this.process.addMessageVariable(WORKFLOW_OUTPUT_NAME, this.targetNamespace,
+                this.workflowWSDL.getWorkflowOutputMessageName());
+
+        List<GpelAssignCopy> copies = new ArrayList<GpelAssignCopy>();
+        List<OutputNode> outputNodes = GraphUtil.getNodes(this.graph, OutputNode.class);
+        this.remainNodes.removeAll(outputNodes);
+        for (OutputNode outputNode : outputNodes) {
+            Port port = outputNode.getPort();
+            GpelAssignCopyFrom from = createAssignCopyFrom(port);
+            GpelAssignCopyTo to = createAssignCopyTo(port, false);
+
+            copies.add(new GpelAssignCopy(this.bpelNS, from, to));
+        }
+
+        if (copies.size() != 0) {
+            // When there is no outputs, we don't create assign.
+            GpelAssign assign = new GpelAssign(this.bpelNS, copies);
+            sequence.addActivity(assign);
+        }
+
+        GpelReply reply = new GpelReply(this.bpelNS, WORKFLOW_PARTNER_LINK, this.workflowWSDL.getPortTypeQName(),
+                this.workflowWSDL.getWorkflowOperationName());
+        reply.setVariableName(WORKFLOW_OUTPUT_NAME);
+        sequence.addActivity(reply);
+    }
+
+    /**
+     * @param block
+     * @param sequence
+     * @throws GraphException
+     */
+    private void addBlock(Collection<Node> block, GpelSequence sequence) throws GraphException {
+        List<Node> nextNodes = getNextExecutableNodes(block);
+        while (nextNodes.size() > 0) {
+            block.removeAll(nextNodes);
+            removeUnnecessaryNodes(nextNodes);
+            if (nextNodes.size() == 0) {
+                // Everything was uncessary nodes (constants, etc.). Move on.
+            } else if (nextNodes.size() == 1) {
+                addSingle(nextNodes.get(0), block, sequence);
+            } else if (nextNodes.size() > 1) {
+                // XXX The algorithm used here is not efficient. It introduces
+                // unnessary barriers.
+                addFlow(nextNodes, block, sequence);
+            } else {
+                // Should not happen.
+                throw new WorkflowRuntimeException("nextNodes.size(): " + nextNodes.size());
+            }
+            nextNodes = getNextExecutableNodes(block);
+        }
+    }
+
+    private void addFlow(List<Node> nextNodes, Collection<Node> block, GpelSequence sequence) throws GraphException {
+        GpelFlow flow = new GpelFlow(this.bpelNS);
+        for (Node node : nextNodes) {
+            GpelSequence childSequence = new GpelSequence(this.bpelNS);
+            flow.addActivity(childSequence);
+            addSingle(node, block, childSequence);
+        }
+        sequence.addActivity(flow);
+    }
+
+    // TODO: Add xml to BPEL
+    private void addSingle(Node node, Collection<Node> block, GpelSequence sequence) throws GraphException {
+        logger.info("Processing + " + node.getID());
+        if (node instanceof WSNode) {
+            addInvoke((WSNode) node, sequence);
+        } else if (node instanceof ConstantNode) {
+            // nothing
+        } else if (node instanceof ForEachNode) {
+            addForEach((ForEachNode) node, block, sequence);
+        } else if (node instanceof EndForEachNode) {
+            // nothing.
+        } else if (node instanceof IfNode) {
+            addIf((IfNode) node, block, sequence);
+        } else if (node instanceof EndifNode) {
+            // nothing
+        } else if (node instanceof ReceiveNode) {
+            addReceive((ReceiveNode) node, sequence);
+        } else if (node instanceof BlockNode) {
+            addBlock((BlockNode) node, block, sequence);
+        } else if (node instanceof EndBlockNode) {
+            // nothing
+        } else if (node instanceof StreamSourceNode) {
+            addStreamSource((StreamSourceNode) node, sequence);
+        } else if (node instanceof ExitNode) {
+            addExit((ExitNode) node, sequence);
+        } else if (node instanceof ResourceNode) {
+            // nothing
+        } else {
+
+            throw new GraphException(node.getClass().getName() + " is not supported.");
+        }
+    }
+
+    /**
+     * @param node
+     * @param sequence
+     */
+    private void addStreamSource(StreamSourceNode node, GpelSequence sequence) {
+        GpelFlow flow = new GpelFlow(this.bpelNS);
+        new GpelSequence(this.bpelNS);
+        sequence.addActivity(flow);
+
+    }
+
+    /**
+     * @param node
+     * @param sequence
+     */
+    private void addExit(ExitNode node, GpelSequence sequence) {
+        sequence.xml().addElement(this.bpelNS, "exit");
+    }
+
+    private void addInvoke(WSNode node, GpelSequence sequence) throws GraphException {
+        String id = node.getID();
+
+        WSComponent wsdlComponent = node.getComponent();
+        String operation = wsdlComponent.getOperationName();
+
+        QName portTypeQName = wsdlComponent.getPortTypeQName();
+        XmlNamespace namespace = XMLUtil.declareNamespaceIfNecessary(id.toLowerCase(), portTypeQName.getNamespaceURI(),
+                false, this.process.xml());
+
+        // Variable
+        String inputVariableName = id + INPUT_SUFFIX;
+        this.process.addMessageVariable(inputVariableName, namespace, portTypeQName.getLocalPart());
+        String outputVariableName = id + OUTPUT_SUFFIX;
+        this.process.addMessageVariable(outputVariableName, namespace, portTypeQName.getLocalPart());
+
+        // Assign
+        List<GpelAssignCopy> copies = new ArrayList<GpelAssignCopy>();
+        for (Port port : node.getInputPorts()) {
+            Port fromPort = port.getFromPort();
+            if (fromPort == null) {
+                // optional input
+                continue;
+            }
+            GpelAssignCopyFrom from = createAssignCopyFrom(port);
+            GpelAssignCopyTo to = createAssignCopyTo(port, true);
+
+            GpelAssignCopy copy = new GpelAssignCopy(this.bpelNS, from, to);
+            copies.add(copy);
+        }
+
+        GpelAssign assign = new GpelAssign(this.bpelNS, copies);
+        sequence.addActivity(assign);
+
+        PartnerLinkRole partnerRoll = this.workflowWSDL.getPartnerRoll(portTypeQName);
+        if (partnerRoll == null) {
+            String partnerLinkTypeName = id + PARTNER_LINK_TYPE_SUFFIX;
+            String partnerRollName = id + PARTNER_ROLE_SUFFIX;
+            partnerRoll = this.workflowWSDL.addPartnerLinkTypeAndRoll(partnerLinkTypeName, partnerRollName,
+                    portTypeQName);
+        }
+        PartnerLinkType partnerLinkType = partnerRoll.getPartnerLinkType();
+
+        // partnerLink
+        String partnerLinkName = createPartnerLinkName(id);
+        XmlNamespace partnerLinkTypeNS = this.targetNamespace;
+        this.process.addPartnerLink(partnerLinkName, partnerLinkTypeNS, partnerLinkType.getName(), null,
+                partnerRoll.getName());
+
+        // Invoke
+        GpelInvoke invoke = new GpelInvoke(this.bpelNS, partnerLinkName, namespace, portTypeQName.getLocalPart(),
+                operation);
+        invoke.setName(INVOKE_NAME_PREFIX + id);
+        invoke.setInputVariableName(inputVariableName);
+        invoke.setOutputVariableName(outputVariableName);
+
+        sequence.addActivity(invoke);
+    }
+
+    /**
+     * Creates BpelAssignCopyFrom for a specified port.
+     * 
+     * @param port
+     * @return The BpelAssignCopyFrom created
+     * @throws GraphException
+     */
+    private GpelAssignCopyFrom createAssignCopyFrom(Port port) throws GraphException {
+        GpelAssignCopyFrom from = new GpelAssignCopyFrom(this.bpelNS);
+
+        Port fromPort = port.getFromPort();
+        Node fromNode = fromPort.getNode();
+        if (fromNode instanceof InputNode) {
+            from.setVariable(WORKFLOW_INPUT_NAME);
+            from.setPart(WorkflowWSDL.INPUT_PART_NAME);
+            from.setQuery("/" + this.typesNamespace.getPrefix() + ":"
+                    + this.workflowWSDL.getWorkflowInputMessageElelmentName() + "/" + fromNode.getID());
+        } else if (fromNode instanceof ConstantNode) {
+            ConstantNode constNode = (ConstantNode) fromNode;
+            Object value = constNode.getValue();
+            // The namaspace and name of the literal element will be set
+            // correctly in from.setLiteral().
+            XmlElement literalElement = XMLUtil.BUILDER.newFragment(GpelAssignCopyFrom.LITERAL_EL);
+            literalElement.addChild(value);
+            from.setLiteral(literalElement);
+        } else if (fromNode instanceof WSNode) {
+            String fromID = fromNode.getID();
+            WSComponent fromWsdlComponent = (WSComponent) fromNode.getComponent();
+
+            WSComponentPort fromWsdlPort = (WSComponentPort) fromPort.getComponentPort();
+
+            from.setVariable(fromID + OUTPUT_SUFFIX);
+            from.setPart(fromWsdlComponent.getOutputPartName());
+
+            if (fromWsdlPort.isSchemaUsed()) {
+                String typesTargetNamespace = fromWsdlPort.getTargetNamespace();
+                XmlNamespace namespace = XMLUtil.declareNamespaceIfNecessary(fromID.toLowerCase() + TYPENS_SUFFIX,
+                        typesTargetNamespace, false, this.process.xml());
+
+                from.setQuery("/" + namespace.getPrefix() + ":" + fromWsdlComponent.getOutputTypeName() + "/"
+                        + fromWsdlPort.getName());
+            } else {
+                // No query needed?
+            }
+        } else if (fromNode instanceof ForEachNode) {
+            from.setVariable(fromNode.getID() + FOREACH_VALUE_SUFFIX);
+        } else if (fromNode instanceof EndForEachNode) {
+            from.setVariable(fromNode.getID() + ARRAY_SUFIX);
+        } else if (fromNode instanceof EndifNode) {
+            // endif has multiple outputs, so we use port ID here.
+            from.setVariable(fromPort.getID() + OUTPUT_SUFFIX);
+        } else if (fromNode instanceof ReceiveNode) {
+            if (fromPort instanceof EPRPort) {
+                from.setPartnerLink(fromNode.getID() + PARTNER_LINK_NAME_SUFFIX);
+                from.setEndpointReference("myRole");
+            } else {
+                from.setVariable(fromNode.getID() + INPUT_SUFFIX);
+            }
+        } else if (fromNode instanceof InstanceNode) {
+            // no op
+        } else {
+            throw new GraphException("Unexpected node," + fromNode.getClass().getName() + " is connected");
+        }
+        return from;
+    }
+
+    /**
+     * Creates BpelAssignCopyFrom for a specified port.
+     * 
+     * @param toPort
+     * @param input
+     * @return The GpelAssignCopyTo created
+     */
+    private GpelAssignCopyTo createAssignCopyTo(Port toPort, boolean input) {
+        GpelAssignCopyTo to = new GpelAssignCopyTo(this.bpelNS);
+
+        Node toNode = toPort.getNode();
+        if (toNode instanceof OutputNode) {
+            to.setVariable(WORKFLOW_OUTPUT_NAME);
+            to.setPart(WorkflowWSDL.OUTPUT_PART_NAME);
+            to.setQuery("/" + this.typesNamespace.getPrefix() + ":"
+                    + this.workflowWSDL.getWorkflowOutputMessageElementName() + "/" + toNode.getID());
+        } else {
+            WSComponentPort toComponentPort = (WSComponentPort) toPort.getComponentPort();
+
+            String toID = toNode.getID();
+            WSComponent toWSComponent = (WSComponent) toNode.getComponent();
+            to.setVariable(toID + INPUT_SUFFIX);
+            to.setPart(toWSComponent.getInputPartName());
+
+            if (toComponentPort.isSchemaUsed()) {
+                // Normal case.
+                // e.g. <part name="name" type="typens:fooType">
+                String typesTargetNamespace = toComponentPort.getTargetNamespace();
+                XmlNamespace namespace = XMLUtil.declareNamespaceIfNecessary(toID.toLowerCase() + TYPENS_SUFFIX,
+                        typesTargetNamespace, false, this.process.xml());
+
+                String typeName = input ? toWSComponent.getInputTypeName() : toWSComponent.getOutputTypeName();
+                to.setQuery("/" + namespace.getPrefix() + ":" + typeName + "/" + toComponentPort.getName());
+            } else {
+                // e.g. <part name="name" type="xsd:string">
+                // No query is needed?
+            }
+        }
+        return to;
+    }
+
+    private void removeUnnecessaryNodes(List<Node> block) {
+        List<Node> unnecessaryNodes = new ArrayList<Node>();
+        for (Node node : block) {
+            if (node instanceof InputNode || node instanceof MemoNode || node instanceof ConstantNode) {
+                unnecessaryNodes.add(node);
+            }
+        }
+        block.removeAll(unnecessaryNodes);
+    }
+
+    private List<Node> getNextExecutableNodes(Collection<Node> nodes) throws GraphException {
+        List<Node> nextNodes = new ArrayList<Node>();
+        for (Node node : nodes) {
+            if (isExecutable(node, nodes)) {
+                nextNodes.add(node);
+            }
+        }
+        return nextNodes;
+    }
+
+    /**
+     * Checks is a specified node can be executed next. A node can be executed if all the previous node are done or
+     * there is no input ports.
+     * 
+     * @param node
+     *            the specified node
+     * @param nodes
+     *            List of nodes remained.
+     * @return true if the specified node can be executed next; false otherwise
+     * @throws GraphException
+     */
+    private boolean isExecutable(Node node, Collection<Node> nodes) throws GraphException {
+        if (node instanceof OutputNode) {
+            return false;
+        }
+
+        // Check data dependency.
+        for (Port port : node.getInputPorts()) {
+            Collection<Port> fromPorts = port.getFromPorts();
+            for (Port fromPort : fromPorts) {
+                if (fromPort instanceof EPRPort) {
+                    continue;
+                }
+                Node fromNode = fromPort.getNode();
+                if (nodes.contains(fromNode)) {
+                    // There is a node that should be executed before this
+                    // node.
+                    return false;
+                }
+            }
+        }
+
+        // Check control dependency.
+        Port port = node.getControlInPort();
+        if (port != null) {
+            Collection<Node> fromNodes = port.getFromNodes();
+            for (Node fromNode : fromNodes) {
+                if (nodes.contains(fromNode)) {
+                    return false;
+                }
+            }
+        }
+
+        // special handling
+        // This has to be at the end.
+        if (node instanceof ForEachNode) {
+            return isExecutable((ForEachNode) node, nodes, ForEachNode.class, EndForEachNode.class);
+        } else if (node instanceof IfNode) {
+            return isExecutable((IfNode) node, nodes, IfNode.class, EndifNode.class);
+        }
+
+        return true;
+    }
+
+    private <S extends Node, E extends Node> boolean isExecutable(S node, Collection<Node> nodes, Class<S> startClass,
+            Class<E> endClass) throws GraphException {
+        // copy remainNodes so that it doesn't break the original one.
+        LinkedList<Node> copiedRemainNodes = new LinkedList<Node>(nodes);
+        Set<Node> block = new HashSet<Node>();
+        getSpecialBlock(node, 0, block, startClass, endClass);
+
+        copiedRemainNodes.remove(node);
+        while (block.size() > 0) {
+            List<Node> doneNodeInBlock = new LinkedList<Node>();
+            for (Node nodeInBlock : block) {
+                if (isExecutable(nodeInBlock, copiedRemainNodes)) {
+                    copiedRemainNodes.remove(nodeInBlock);
+                    doneNodeInBlock.add(nodeInBlock);
+                }
+            }
+            if (doneNodeInBlock.size() == 0) {
+                // Cannot proceed anymore. This means that some nodes are depend
+                // on outer nodes that haven't finished.
+                return false;
+            }
+            block.removeAll(doneNodeInBlock);
+        }
+        return true;
+    }
+
+    /**
+     * @param node
+     * @param depth
+     * @param block
+     *            It's a set so that duplicated nodes won't be added.
+     * @param startClass
+     * @param endClass
+     * @throws GraphException
+     */
+    private void getSpecialBlock(Node node, int depth, Set<Node> block, Class startClass, Class endClass)
+            throws GraphException {
+        List<Node> nextNodes = GraphUtil.getNextNodes(node);
+        for (Node nextNode : nextNodes) {
+            if (nextNode instanceof OutputNode) {
+                throw new GraphException("Nodes after " + startClass.getName()
+                        + " cannot be connected to the output without going through " + endClass.getName() + ".");
+            } else if (endClass.isInstance(nextNode)) {
+                block.add(nextNode);
+                if (depth == 0) {
+                    // Stop the recursion here.
+                } else {
+                    getSpecialBlock(nextNode, depth - 1, block, startClass, endClass);
+                }
+            } else if (startClass.isInstance(nextNode)) {
+                // handle embedded forEach
+                block.add(nextNode);
+                getSpecialBlock(nextNode, depth + 1, block, startClass, endClass);
+            } else {
+                block.add(nextNode);
+                getSpecialBlock(nextNode, depth, block, startClass, endClass);
+            }
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private <S extends Node, E extends Node> E findEndNode(Node node, int depth, Class<S> startClass, Class<E> endClass)
+            throws GraphException {
+        List<Node> nextNodes = GraphUtil.getNextNodes(node);
+        for (Node nextNode : nextNodes) {
+            if (nextNode instanceof OutputNode) {
+                throw new GraphException("Nodes after " + startClass.getName()
+                        + " cannot be connected to the output without going through " + endClass.getName() + ".");
+            } else if (endClass.isInstance(nextNode)) {
+                if (depth == 0) {
+                    // Stop the recursion here.
+                    return (E) nextNode; // This cast is OK.
+                } else {
+                    return findEndNode(nextNode, depth - 1, startClass, endClass);
+                }
+            } else if (startClass.isInstance(nextNode)) {
+                // handle embedded forEach
+                return findEndNode(nextNode, depth + 1, startClass, endClass);
+            } else {
+                return findEndNode(nextNode, depth, startClass, endClass);
+            }
+        }
+        throw new GraphException("Cannot find matching  " + endClass.getName() + " for " + startClass.getName() + ".");
+    }
+
+    private void addForEach(ForEachNode splitNode, Collection<Node> parentBlock, GpelSequence sequence)
+            throws GraphException {
+        Set<Node> forEachBlock = getForEachBlock(splitNode);
+        parentBlock.removeAll(forEachBlock);
+
+        GpelSequence subSequence = new GpelSequence(this.bpelNS);
+        GpelScope scope = new GpelScope(this.bpelNS, subSequence);
+
+        String arrayName = splitNode.getID() + ARRAY_SUFIX;
+        // TODO This should be type instead of messageType
+        this.process.addMessageVariable(arrayName, WSConstants.XSD_NS, WSConstants.XSD_ANY_TYPE.getLocalPart());
+
+        // Extract array from the previous node.
+        GpelAssignCopyFrom arrayFrom = createAssignCopyFrom(splitNode.getInputPort(0));
+        GpelAssignCopyTo arrayTo = new GpelAssignCopyTo(this.bpelNS);
+        arrayTo.setVariable(arrayName);
+        GpelAssignCopy arrayCopy = new GpelAssignCopy(this.bpelNS, arrayFrom, arrayTo);
+        GpelAssign arrayAssign = new GpelAssign(this.bpelNS, arrayCopy);
+        sequence.addActivity(arrayAssign);
+
+        // Extract a item from array
+        String valueName = splitNode.getID() + FOREACH_VALUE_SUFFIX;
+        // TODO set local variable in scope instead of process
+        // TODO This should be type instead of messageType
+        this.process.addMessageVariable(valueName, WSConstants.XSD_NS, WSConstants.XSD_ANY_TYPE.getLocalPart());
+        GpelAssignCopyFrom valueFrom = new GpelAssignCopyFrom(this.bpelNS);
+        valueFrom.setVariable(arrayName);
+        valueFrom.setQuery("$" + arrayName + "/*[$i]");
+        GpelAssignCopyTo valueTo = new GpelAssignCopyTo(this.bpelNS);
+        valueTo.setVariable(valueName);
+        GpelAssignCopy valueCopy = new GpelAssignCopy(this.bpelNS, valueFrom, valueTo);
+        GpelAssign valueAssign = new GpelAssign(this.bpelNS, valueCopy);
+
+        subSequence.addActivity(valueAssign);
+
+        addBlock(forEachBlock, subSequence);
+
+        Node mergeNode = getMergeNode(splitNode);
+        String outputName = mergeNode.getID() + ARRAY_SUFIX;
+        // TODO This should be type instead of messageType
+        this.process.addMessageVariable(outputName, WSConstants.XSD_NS, WSConstants.XSD_ANY_TYPE.getLocalPart());
+        GpelAssignCopyFrom outputFrom = createAssignCopyFrom(mergeNode.getInputPort(0).getFromPort());
+        GpelAssignCopyTo outputTo = new GpelAssignCopyTo(this.bpelNS);
+        outputTo.setVariable(outputName);
+        outputTo.setQuery("/value[$i]");
+        GpelAssignCopy outputCopy = new GpelAssignCopy(this.bpelNS, outputFrom, outputTo);
+        GpelAssign outputAssign = new GpelAssign(this.bpelNS, outputCopy);
+        subSequence.addActivity(outputAssign);
+
+        GpelForEach forEach = new GpelForEach(this.bpelNS, "i", "1", "count($" + arrayName + "/*)",
+                true /* parallel */, scope);
+
+        sequence.addActivity(forEach);
+    }
+
+    private Set<Node> getForEachBlock(ForEachNode node) throws GraphException {
+        Set<Node> forEachBlock = new HashSet<Node>();
+        getSpecialBlock(node, 0, forEachBlock, ForEachNode.class, EndForEachNode.class);
+        return forEachBlock;
+    }
+
+    private EndForEachNode getMergeNode(ForEachNode node) throws GraphException {
+        return findEndNode(node, 0, ForEachNode.class, EndForEachNode.class);
+    }
+
+    private void addIf(IfNode ifNode, Collection<Node> parentBlock, GpelSequence sequence) throws GraphException {
+        //
+        // Condition
+        //
+        String booleanExpression = ifNode.getXPath();
+        if (booleanExpression == null) {
+            throw new GraphException("XPath cannot be null");
+        }
+        // replace $1, $2,... with actual value.
+        List<? extends Port> inputPorts = ifNode.getInputPorts();
+        ArrayList<GpelAssignCopy> copies = new ArrayList<GpelAssignCopy>();
+        for (int i = 0; i < inputPorts.size(); i++) {
+            Port port = inputPorts.get(i);
+            Port fromPort = port.getFromPort();
+            if (fromPort != null) {
+                String variableName = port.getID() + INPUT_SUFFIX;
+
+                GpelVariable ifVar = new GpelVariable(this.process.xml().getNamespace(), variableName);
+                XmlNamespace xsdNS = process.xml().lookupNamespaceByName(WSConstants.XSD_NS_URI);
+                if (null != xsdNS && xsdNS.getPrefix() != null) {
+                    ifVar.xml().setAttributeValue("element",
+                            xsdNS.getPrefix() + ":" + WSConstants.XSD_ANY_TYPE.getLocalPart());
+                } else {
+                    this.process.xml().declareNamespace(WSConstants.XSD_NS);
+                    ifVar.xml().setAttributeValue("element",
+                            WSConstants.XSD_NS.getPrefix() + ":" + WSConstants.XSD_ANY_TYPE.getLocalPart());
+                }
+                this.process.getVariables().addVariable(ifVar);
+
+                GpelAssignCopyFrom from = createAssignCopyFrom(fromPort);
+                GpelAssignCopyTo to = new GpelAssignCopyTo(this.bpelNS);
+                to.setVariable(variableName);
+                GpelAssignCopy copy = new GpelAssignCopy(this.bpelNS, from, to);
+                copies.add(copy);
+
+                booleanExpression = booleanExpression.replaceAll("\\$" + i, "\\$" + variableName);
+            }
+        }
+        if (copies.size() > 0) {
+            GpelAssign assign = new GpelAssign(this.bpelNS, copies);
+            sequence.addActivity(assign);
+        }
+        GpelCondition condition = new GpelCondition(this.bpelNS, booleanExpression);
+
+        //
+        // If block
+        //
+        EndifNode endifNode = getEndifNode(ifNode);
+        GpelSequence ifSequence = createIfSequence(ifNode, endifNode, true, parentBlock);
+        GpelIf gpelIf = new GpelIf(this.bpelNS, condition, ifSequence);
+
+        //
+        // Else block
+        //
+        GpelSequence elseSequence = createIfSequence(ifNode, endifNode, false, parentBlock);
+        GpelElse gpelElse = new GpelElse(this.bpelNS, elseSequence);
+        gpelIf.setElse(gpelElse);
+
+        //
+        // Create global variables for endif.
+        //
+        for (Port outputPort : endifNode.getOutputPorts()) {
+            String variable = outputPort.getID() + OUTPUT_SUFFIX;
+            GpelVariable ifVar = new GpelVariable(this.process.xml().getNamespace(), variable);
+            XmlNamespace xsdNS = process.xml().lookupNamespaceByName(WSConstants.XSD_NS_URI);
+            if (null != xsdNS && xsdNS.getPrefix() != null) {
+                ifVar.xml().setAttributeValue("element",
+                        xsdNS.getPrefix() + ":" + WSConstants.XSD_ANY_TYPE.getLocalPart());
+            } else {
+                this.process.xml().declareNamespace(WSConstants.XSD_NS);
+                ifVar.xml().setAttributeValue("element",
+                        WSConstants.XSD_NS.getPrefix() + ":" + WSConstants.XSD_ANY_TYPE.getLocalPart());
+            }
+            this.process.getVariables().addVariable(ifVar);
+        }
+
+        sequence.addActivity(gpelIf);
+    }
+
+    private GpelSequence createIfSequence(IfNode ifNode, EndifNode endifNode, boolean ifBlock,
+            Collection<Node> parentBlock) throws GraphException {
+        Set<Node> block = getIfBlock(ifNode, ifBlock);
+        parentBlock.removeAll(block);
+        GpelSequence sequence = new GpelSequence(this.bpelNS);
+        addBlock(block, sequence);
+
+        // Create a copy to global variable.
+        List<DataPort> outputPorts = endifNode.getOutputPorts();
+        ArrayList<GpelAssignCopy> copies = new ArrayList<GpelAssignCopy>();
+        for (int i = 0; i < outputPorts.size(); i++) {
+            DataPort outputPort = outputPorts.get(i);
+            String variable = outputPort.getID() + OUTPUT_SUFFIX;
+            int index = ifBlock ? i : i + outputPorts.size();
+            DataPort inputPort = endifNode.getInputPort(index);
+            Port fromPort = inputPort.getFromPort();
+            GpelAssignCopyFrom from = createAssignCopyFrom(fromPort);
+            GpelAssignCopyTo to = new GpelAssignCopyTo(this.bpelNS);
+            to.setVariable(variable);
+            GpelAssignCopy copy = new GpelAssignCopy(this.bpelNS, from, to);
+            copies.add(copy);
+        }
+        GpelAssign assign = new GpelAssign(this.bpelNS, copies);
+        sequence.addActivity(assign);
+
+        return sequence;
+    }
+
+    private Set<Node> getIfBlock(Node node, boolean ifBlock) throws GraphException {
+        Set<Node> block = new HashSet<Node>();
+
+        int index = ifBlock ? 0 : 1;
+        Port controlOutPort = node.getControlOutPorts().get(index);
+        for (Node nextNode : controlOutPort.getToNodes()) {
+            block.add(nextNode);
+            getSpecialBlock(nextNode, 0, block, IfNode.class, EndifNode.class);
+        }
+        return block;
+    }
+
+    private EndifNode getEndifNode(IfNode node) throws GraphException {
+        return findEndNode(node, 0, IfNode.class, EndifNode.class);
+    }
+
+    /**
+     * @param node
+     * @param block
+     * @param sequence
+     */
+    private void addReceive(ReceiveNode node, GpelSequence sequence) {
+        String id = node.getID();
+        String operationName = id;
+
+        // Create this operation and type in WSDL.
+        WsdlPortType portType = this.workflowWSDL.addReceivePortType(operationName, node);
+        QName portTypeQName = portType.getQName();
+
+        // Partner link
+        String partnerLinkName = createPartnerLinkName(id);
+        XmlNamespace partnerLinkTypeNS = this.targetNamespace;
+        String partnerLinkTypeName = id + PARTNER_LINK_TYPE_SUFFIX;
+        String myRollName = id + MY_ROLE_SUFFIX;
+        this.process.addPartnerLink(partnerLinkName, partnerLinkTypeNS, partnerLinkTypeName, myRollName, null);
+        this.workflowWSDL.addPartnerLinkTypeAndRoll(partnerLinkTypeName, myRollName, portTypeQName);
+
+        GpelReceive receive = new GpelReceive(this.bpelNS, partnerLinkName, portTypeQName, operationName);
+        String variableName = id + INPUT_SUFFIX;
+        this.process.addMessageVariable(variableName, WSConstants.XSD_NS, variableName);
+        receive.setGpelVariableName(variableName);
+        sequence.addActivity(receive);
+    }
+
+    private void addBlock(BlockNode blockNode, Collection<Node> parentBlock, GpelSequence sequence)
+            throws GraphException {
+
+        //
+        // normal block
+        //
+        EndBlockNode endBlockNode = getEndBlockNode(blockNode);
+        GpelSequence normalSequence = createBlockSequence(blockNode, endBlockNode, true, parentBlock);
+        GpelScope scope = new GpelScope(this.bpelNS, normalSequence);
+
+        //
+        // exception block
+        //
+        // GpelSequence compensationSequence = createBlockSequence(blockNode,
+        // endBlockNode, false, parentBlock);
+        // TODO GpelExceptionHandler handler
+        // = new GpelExceptionHandler(compensationSequence);
+        // scope.add(handler);
+
+        sequence.addActivity(scope);
+    }
+
+    private GpelSequence createBlockSequence(BlockNode blockNode, EndBlockNode endBlockNode, boolean blockBlock,
+            Collection<Node> parentBlock) throws GraphException {
+        Set<Node> block = getBlockBlock(blockNode, blockBlock);
+        parentBlock.removeAll(block);
+        GpelSequence sequence = new GpelSequence(this.bpelNS);
+        addBlock(block, sequence);
+
+        // Create a copy to global variable.
+        List<DataPort> outputPorts = endBlockNode.getOutputPorts();
+        ArrayList<GpelAssignCopy> copies = new ArrayList<GpelAssignCopy>();
+        for (int i = 0; i < outputPorts.size(); i++) {
+            DataPort outputPort = outputPorts.get(i);
+            String variable = outputPort.getID() + OUTPUT_SUFFIX;
+            int index = blockBlock ? i : i + outputPorts.size();
+            DataPort inputPort = endBlockNode.getInputPort(index);
+            Port fromPort = inputPort.getFromPort();
+            GpelAssignCopyFrom from = createAssignCopyFrom(fromPort);
+            GpelAssignCopyTo to = new GpelAssignCopyTo(this.bpelNS);
+            to.setVariable(variable);
+            GpelAssignCopy copy = new GpelAssignCopy(this.bpelNS, from, to);
+            copies.add(copy);
+        }
+        GpelAssign assign = new GpelAssign(this.bpelNS, copies);
+        sequence.addActivity(assign);
+
+        return sequence;
+    }
+
+    private Set<Node> getBlockBlock(Node node, boolean blockBlock) throws GraphException {
+        Set<Node> block = new HashSet<Node>();
+
+        int index = blockBlock ? 0 : 1;
+        Port controlOutPort = node.getControlOutPorts().get(index);
+        for (Node nextNode : controlOutPort.getToNodes()) {
+            block.add(nextNode);
+            getSpecialBlock(nextNode, 0, block, BlockNode.class, EndBlockNode.class);
+        }
+        return block;
+    }
+
+    private EndBlockNode getEndBlockNode(BlockNode node) throws GraphException {
+        return findEndNode(node, 0, BlockNode.class, EndBlockNode.class);
+    }
+
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScriptType.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScriptType.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScriptType.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/gpel/script/BPELScriptType.java Thu May 17 17:12:15 2012
@@ -0,0 +1,27 @@
+/*
+ *
+ * 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.workflow.model.gpel.script;
+
+public enum BPELScriptType {
+
+    GPEL, BPEL2
+}
\ No newline at end of file