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 [5/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/graph/amazon/InstanceNode.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/InstanceNode.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/InstanceNode.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/InstanceNode.java Thu May 17 17:12:15 2012
@@ -0,0 +1,300 @@
+/*
+ *
+ * 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.graph.amazon;
+
+import org.apache.airavata.workflow.model.component.Component;
+import org.apache.airavata.workflow.model.component.amazon.InstanceComponent;
+import org.apache.airavata.workflow.model.graph.ControlEdge;
+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.GraphSchema;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.xmlpull.infoset.XmlElement;
+
+public class InstanceNode extends ResourceNode {
+
+    /*
+     * XML configuration
+     */
+    private static final String NEW_TAG_NAME = "newInstance";
+    private static final String AMI_ID_TAG_NAME = "ami";
+    private static final String INSTANCE_ID_TAG_NAME = "instance";
+    private static final String INSTANCE_TYPE_TAG_NAME = "type";
+    private static final String USERNAME_TAG_NAME = "username";
+
+    private boolean startNewInstance;
+
+    private String instanceId;
+
+    private String amiId;
+
+    private String username;
+
+    private String instanceType;
+
+    private String outputInstanceId;
+
+    /**
+     * 
+     * Constructs a InstanceNode.
+     * 
+     * @param graph
+     */
+    public InstanceNode(Graph graph) {
+        super(graph);
+        this.startNewInstance = true;
+    }
+
+    /**
+     * Constructs an InstanceNode.
+     * 
+     * @param nodeElement
+     * @throws GraphException
+     */
+    public InstanceNode(XmlElement nodeElement) throws GraphException {
+        super(nodeElement);
+    }
+
+    public boolean isStartNewInstance() {
+        return this.startNewInstance;
+    }
+
+    public void setStartNewInstance(boolean startNewInstance) {
+        this.startNewInstance = startNewInstance;
+    }
+
+    public String getUsername() {
+        return this.username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public String getInstanceType() {
+        return this.instanceType;
+    }
+
+    public void setInstanceType(String instanceType) {
+        this.instanceType = instanceType;
+    }
+
+    /**
+     * Returns the instanceId.
+     * 
+     * @return The instanceId
+     */
+    public String getInstanceId() {
+        return this.instanceId;
+    }
+
+    /**
+     * Sets instanceId.
+     * 
+     * @param instanceId
+     *            The instanceId to set.
+     */
+    public void setInstanceId(String instanceId) {
+        this.instanceId = instanceId;
+    }
+
+    /**
+     * Sets amiId.
+     * 
+     * @param amiId
+     *            The amiId to set.
+     */
+    public void setAmiId(String amiId) {
+        this.amiId = amiId;
+    }
+
+    /**
+     * 
+     * @return AMI_ID or Instance ID depend on user's choice
+     */
+    public String getIdAsValue() {
+        if (this.startNewInstance)
+            return this.amiId;
+        else
+            return this.instanceId;
+    }
+
+    /**
+     * 
+     * @return
+     */
+    public String getOutputInstanceId() {
+        return this.outputInstanceId;
+    }
+
+    /**
+     * 
+     * @param outputInstanceId
+     */
+    public void setOutputInstanceId(String outputInstanceId) {
+        this.outputInstanceId = outputInstanceId;
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#getComponent()
+     */
+    @Override
+    public Component getComponent() {
+        Component component = super.getComponent();
+        if (component == null) {
+            // The component is null when read from the graph XML.
+            component = new InstanceComponent();
+            setComponent(component);
+        }
+        return component;
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#parseConfiguration(org.xmlpull.infoset.XmlElement)
+     */
+    @Override
+    protected void parseConfiguration(XmlElement configElement) {
+        super.parseConfiguration(configElement);
+
+        // new instance
+        XmlElement element = configElement.element(null, NEW_TAG_NAME);
+        if (element != null) {
+            for (Object child : element.children()) {
+                this.startNewInstance = Boolean.valueOf((String) child).booleanValue();
+            }
+        }
+
+        if (this.startNewInstance) {
+            // ami id
+            XmlElement element2 = configElement.element(null, AMI_ID_TAG_NAME);
+            if (element != null) {
+                for (Object child : element2.children()) {
+                    this.amiId = (String) child;
+                }
+            }
+
+            // instance type
+            XmlElement element3 = configElement.element(null, INSTANCE_TYPE_TAG_NAME);
+            if (element != null) {
+                for (Object child : element3.children()) {
+                    this.instanceType = (String) child;
+                }
+            }
+
+        } else {
+            // instance id
+            XmlElement element2 = configElement.element(null, INSTANCE_ID_TAG_NAME);
+            if (element != null) {
+                for (Object child : element2.children()) {
+                    this.instanceId = (String) child;
+                }
+            }
+        }
+
+        // username
+        XmlElement element2 = configElement.element(null, USERNAME_TAG_NAME);
+        if (element != null) {
+            for (Object child : element2.children()) {
+                this.username = (String) child;
+            }
+        }
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#toXML()
+     */
+    @Override
+    protected XmlElement toXML() {
+        XmlElement nodeElement = super.toXML();
+        nodeElement.setAttributeValue(GraphSchema.NS, GraphSchema.NODE_TYPE_ATTRIBUTE, GraphSchema.NODE_TYPE_INSTANCE);
+        return nodeElement;
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#addConfigurationElement(org.xmlpull.infoset.XmlElement)
+     */
+    @Override
+    protected XmlElement addConfigurationElement(XmlElement nodeElement) {
+        XmlElement configElement = super.addConfigurationElement(nodeElement);
+
+        // save start new instance
+        XmlElement element = configElement.addElement(GraphSchema.NS, NEW_TAG_NAME);
+        element.addChild(String.valueOf(this.startNewInstance));
+
+        if (this.startNewInstance) {
+            // save ami id
+            if (this.amiId != null) {
+                XmlElement element2 = configElement.addElement(GraphSchema.NS, AMI_ID_TAG_NAME);
+                element2.addChild(this.amiId);
+            }
+
+            // save instance type
+            if (this.instanceType != null) {
+                XmlElement element3 = configElement.addElement(GraphSchema.NS, INSTANCE_TYPE_TAG_NAME);
+                element3.addChild(this.instanceType);
+            }
+        } else {
+            // save instance id
+            if (this.instanceId != null) {
+                XmlElement element2 = configElement.addElement(GraphSchema.NS, INSTANCE_ID_TAG_NAME);
+                element2.addChild(this.instanceId);
+            }
+        }
+
+        // save username
+        if (this.username != null) {
+            XmlElement element2 = configElement.addElement(GraphSchema.NS, USERNAME_TAG_NAME);
+            element2.addChild(this.username);
+        }
+
+        return configElement;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#edgeWasAdded(org.apache.airavata.workflow.model.graph.Edge)
+     */
+    @Override
+    protected void edgeWasAdded(Edge edge) throws GraphException {
+        super.edgeWasAdded(edge);
+
+        if (edge instanceof ControlEdge) {
+            Port toPort = edge.getToPort();
+            Node toNode = toPort.getNode();
+            /*
+             * check if there is already more than instance node connecting to destination node
+             */
+            if (!(toNode instanceof InstanceNode)) {
+                for (Node node : toNode.getControlInPort().getFromNodes()) {
+                    if ((node instanceof InstanceNode) && this != node) {
+                        throw new GraphException("Cannot connect more than one instance node to another node.");
+                    }
+                }
+            }
+        }
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/ResourceNode.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/ResourceNode.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/ResourceNode.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/ResourceNode.java Thu May 17 17:12:15 2012
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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.graph.amazon;
+
+import org.apache.airavata.workflow.model.graph.DataEdge;
+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.GraphSchema;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.xmlpull.infoset.XmlElement;
+
+/**
+ * The placeholder for Instance Nodes type. Using for easy checking
+ * 
+ */
+public abstract class ResourceNode extends NodeImpl {
+
+    /**
+     * 
+     * Constructs a ResourceNode.
+     * 
+     * @param graph
+     */
+    public ResourceNode(Graph graph) {
+        super(graph);
+    }
+
+    /**
+     * Constructs an InstanceNode.
+     * 
+     * @param nodeElement
+     * @throws GraphException
+     */
+    public ResourceNode(XmlElement nodeElement) throws GraphException {
+        super(nodeElement);
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#addConfigurationElement(org.xmlpull.infoset.XmlElement)
+     */
+    @Override
+    protected XmlElement addConfigurationElement(XmlElement nodeElement) {
+        XmlElement configElement = nodeElement.addElement(GraphSchema.NS, GraphSchema.NODE_CONFIG_TAG);
+        return configElement;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#edgeWasAdded(org.apache.airavata.workflow.model.graph.Edge)
+     */
+    @Override
+    protected void edgeWasAdded(Edge edge) throws GraphException {
+        super.edgeWasAdded(edge);
+
+        if (edge instanceof DataEdge) {
+            Port toPort = edge.getToPort();
+            Node toNode = toPort.getNode();
+            Port fromPort = edge.getFromPort();
+            Node fromNode = fromPort.getNode();
+
+            if (!(toNode instanceof ResourceNode && fromNode instanceof ResourceNode)) {
+                throw new GraphException("Cannot connect Resource Node to other type of nodes");
+            }
+        }
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/TerminateInstanceNode.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/TerminateInstanceNode.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/TerminateInstanceNode.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/amazon/TerminateInstanceNode.java Thu May 17 17:12:15 2012
@@ -0,0 +1,89 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+
+package org.apache.airavata.workflow.model.graph.amazon;
+
+import org.apache.airavata.workflow.model.component.Component;
+import org.apache.airavata.workflow.model.component.amazon.TerminateInstanceComponent;
+import org.apache.airavata.workflow.model.graph.Graph;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.GraphSchema;
+import org.xmlpull.infoset.XmlElement;
+
+public class TerminateInstanceNode extends ResourceNode {
+
+    private boolean startNewInstance;
+
+    /**
+     * 
+     * Constructs a InstanceNode.
+     * 
+     * @param graph
+     */
+    public TerminateInstanceNode(Graph graph) {
+        super(graph);
+        this.startNewInstance = true;
+    }
+
+    /**
+     * Constructs an InstanceNode.
+     * 
+     * @param nodeElement
+     * @throws GraphException
+     */
+    public TerminateInstanceNode(XmlElement nodeElement) throws GraphException {
+        super(nodeElement);
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#getComponent()
+     */
+    @Override
+    public Component getComponent() {
+        Component component = super.getComponent();
+        if (component == null) {
+            // The component is null when read from the graph XML.
+            component = new TerminateInstanceComponent();
+            setComponent(component);
+        }
+        return component;
+    }
+
+    /**
+     * 
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#toXML()
+     */
+    @Override
+    protected XmlElement toXML() {
+        XmlElement nodeElement = super.toXML();
+        nodeElement.setAttributeValue(GraphSchema.NS, GraphSchema.NODE_TYPE_ATTRIBUTE, GraphSchema.NODE_TYPE_TERMINATE);
+        return nodeElement;
+    }
+
+    public boolean isStartNewInstance() {
+        return this.startNewInstance;
+    }
+
+    public void setStartNewInstance(boolean startNewInstance) {
+        this.startNewInstance = startNewInstance;
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/BasicTypeMapping.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/BasicTypeMapping.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/BasicTypeMapping.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/BasicTypeMapping.java Thu May 17 17:12:15 2012
@@ -0,0 +1,252 @@
+/*
+ *
+ * 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.graph.dynamic;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.exceptions.WorkflowException;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.xmlpull.infoset.XmlAttribute;
+import org.xmlpull.infoset.XmlElement;
+import org.xmlpull.infoset.XmlNamespace;
+
+public class BasicTypeMapping {
+
+    /**
+     * STR_UNBOUNDED
+     */
+    private static final String STR_UNBOUNDED = "unbounded";
+
+    /**
+     * STR_MAX_OCCURS
+     */
+    private static final String STR_MAX_OCCURS = "maxOccurs";
+
+    /**
+     * STR_TYPE
+     */
+    private static final String STR_TYPE = "type";
+
+    /**
+     * NUM
+     */
+    private static final int NUM = 2;
+
+    private static QName[] TYPES = new QName[NUM];
+
+    private static String[] NAMES = new String[NUM * 2];
+
+    private static String[] DEFAULTS = new String[NUM * 2];
+
+    private static String[] VAR_NAMES = new String[NUM * 2];
+
+    public static final QName STRING_QNAME = new QName("http://www.w3.org/2001/XMLSchema", "string");
+    public static QName INT_QNAME = new QName("http://www.w3.org/2001/XMLSchema", "int");
+
+    /**
+     * Used to generate string1, string2, string3 ...
+     */
+    public static int uniqueVarappend = 0;
+
+    static {
+
+        TYPES[0] = INT_QNAME;
+
+        TYPES[1] = STRING_QNAME;
+
+        NAMES[0] = "int";
+        NAMES[1] = "String";
+        NAMES[0 + NUM] = "int[]";
+        NAMES[1 + NUM] = "String[]";
+
+        DEFAULTS[0] = "0";
+        DEFAULTS[1] = "null";
+        DEFAULTS[0 + NUM] = "null";
+        DEFAULTS[1 + NUM] = "null";
+
+        VAR_NAMES[0] = "intVal";
+        VAR_NAMES[1] = "string";
+        VAR_NAMES[0 + NUM] = "intArray";
+        VAR_NAMES[1 + NUM] = "stringArray";
+
+    }
+
+    /**
+     * REturns the index of the simple type which can be used to get the Java typename, etc. rerurns -1 if not a simple
+     * type.
+     * 
+     * @param qname
+     * @return
+     */
+    public static int getSimpleTypeIndex(QName qname) {
+        for (int i = 0; i < TYPES.length; ++i) {
+            if (TYPES[i].equals(qname)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    public static String getTypeName(int index) {
+        if (index >= 2 * NUM || index < 0) {
+            throw new IllegalStateException("Invalid Index");
+        }
+        return NAMES[index];
+    }
+
+    public static String getTypeName(QName qName) {
+        return getTypeName(getSimpleTypeIndex(qName));
+    }
+
+    public static String getTypeDefault(int index) {
+        if (index >= 2 * NUM || index < 0) {
+            throw new IllegalStateException("Invalid Index");
+        }
+        return DEFAULTS[index];
+    }
+
+    public static String getTypeDefault(QName qName) {
+        return getTypeDefault(getSimpleTypeIndex(qName));
+    }
+
+    public static String getTypeVariableName(int index) {
+        if (index >= 2 * NUM || index < 0) {
+            throw new IllegalStateException("Invalid Index");
+        }
+        return VAR_NAMES[index] + getUniqueVarAppender();
+    }
+
+    public static String getTypeVariableName(QName qName) {
+        return getTypeVariableName(getSimpleTypeIndex(qName));
+    }
+
+    private synchronized static int getUniqueVarAppender() {
+        return uniqueVarappend++;
+    }
+
+    public static void reset() {
+        uniqueVarappend = 0;
+    }
+
+    public static Object getObjectOfType(int index, Object obj) {
+        switch (index) {
+        case 0:
+            return new Integer((String) obj);
+        case 1:
+            return obj;
+        }
+        throw new WorkflowRuntimeException("type Not Supported yet!!");
+    }
+
+    public static Object getObjectOfType(QName qName, Object obj) {
+        return getObjectOfType(getSimpleTypeIndex(qName), obj);
+    }
+
+    public static int getSimpleTypeIndex(XmlElement element) {
+
+        XmlAttribute type = element.attribute(STR_TYPE);
+        if (null == type) {
+            return -1;
+        }
+        String typeQNameString = type.getValue();
+        String typeName = XMLUtil.getLocalPartOfQName(typeQNameString);
+        String prefix = XMLUtil.getPrefixOfQName(typeQNameString);
+        XmlNamespace namespace = element.lookupNamespaceByPrefix(prefix);
+        if (namespace == null) {
+            return -1;
+        }
+        QName typeQname = new QName(namespace.getName(), typeName, prefix);
+        int simpleTypeIndex = getSimpleTypeIndex(typeQname);
+        if (-1 == simpleTypeIndex) {
+            return -1;
+        }
+
+        XmlAttribute maxOccurs = element.attribute(STR_MAX_OCCURS);
+        if (maxOccurs != null && STR_UNBOUNDED.equals(maxOccurs.getValue())) {
+            // this is the comvention the arraytype index is simplextye index + NUM
+            return NUM + simpleTypeIndex;
+        } else {
+            return simpleTypeIndex;
+        }
+    }
+
+    public static boolean isArrayType(XmlElement element) {
+        int index = getSimpleTypeIndex(element);
+        if (index >= NUM) {
+            return true;
+        }
+        return false;
+    }
+
+    public static Object getOutputArray(XmlElement element, String name, int simpleIndex) throws WorkflowException {
+        try {
+            // This code doesn't work when the output is a complex type.
+            // Object output = this.outputMessage.getObjectPart(name);
+            // return output;
+
+            XmlElement outputElement = (XmlElement) element;
+            Iterator valueElementItr = outputElement.elements(null, name).iterator();
+            LinkedList<String> ret = new LinkedList<String>();
+            while (valueElementItr.hasNext()) {
+                XmlElement valueElement = (XmlElement) valueElementItr.next();
+                Iterator childIt = valueElement.children().iterator();
+                int numberOfChildren = 0;
+                while (childIt.hasNext()) {
+                    childIt.next();
+                    numberOfChildren++;
+                }
+                if (numberOfChildren == 1) {
+                    Object child = valueElement.children().iterator().next();
+                    if (child instanceof String) {
+                        // Value is a simple type. Return the string.
+                        String value = (String) child;
+                        ret.add(value);
+                    }
+                }
+            }
+            switch (simpleIndex) {
+            case 0:
+                Integer[] intRet = new Integer[ret.size()];
+                for (int i = 0; i < ret.size(); i++) {
+                    intRet[i] = Integer.parseInt(ret.get(i));
+                }
+                return intRet;
+            case 1:
+                String[] strRet = new String[ret.size()];
+                for (int i = 0; i < ret.size(); i++) {
+                    strRet[i] = ret.get(i);
+                }
+                return strRet;
+            }
+            throw new WorkflowException("Unknown type");
+
+        } catch (RuntimeException e) {
+            String message = "Error in getting output. name: " + name;
+            throw new WorkflowException(message, e);
+        }
+    }
+
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicNode.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicNode.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicNode.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicNode.java Thu May 17 17:12:15 2012
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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.graph.dynamic;
+
+import java.net.URL;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.airavata.workflow.model.component.dynamic.DynamicComponent;
+import org.apache.airavata.workflow.model.component.dynamic.DynamicComponentPort;
+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.Port;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+import org.apache.airavata.workflow.model.graph.impl.PortImpl;
+import org.apache.airavata.workflow.model.graph.util.GraphUtil;
+
+public class DynamicNode extends NodeImpl implements PortAddable {
+
+    /**
+     * Constructs a WSNode.
+     * 
+     * @param graph
+     */
+    public DynamicNode(Graph graph) {
+        super(graph);
+        Collection<PortImpl> allPorts = this.getAllPorts();
+        for (Port port : allPorts) {
+            ((DynamicPort) port).setNode(this);
+        }
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Node#getComponent()
+     */
+    @Override
+    public DynamicComponent getComponent() {
+        return (DynamicComponent) super.getComponent();
+    }
+
+    /**
+     * @throws GraphException
+     * @see org.apache.airavata.workflow.model.graph.impl.NodeImpl#edgeWasAdded(org.apache.airavata.workflow.model.graph.Edge)
+     */
+    @Override
+    protected void edgeWasAdded(Edge edge) throws GraphException {
+        GraphUtil.validateConnection(edge);
+    }
+
+    public DataPort getFreeInPort() {
+        List<DataPort> inputPorts = this.getInputPorts();
+        for (DataPort dataPort : inputPorts) {
+            if (null == dataPort.getFromNode()) {
+                return dataPort;
+            }
+        }
+        // none found, so make a new one.
+        DynamicComponentPort comPort = new DynamicComponentPort(getComponent());
+        getComponent().addInputPort(comPort);
+        DataPort port = comPort.createPort();
+        ((DynamicPort) port).setNode(this);
+        this.addInputPort(port);
+
+        return port;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.dynamic.PortAddable#removeLastDynamicallyAddedInPort()
+     */
+    @Override
+    public void removeLastDynamicallyAddedInPort() throws GraphException {
+
+        List<DataPort> inputPorts = this.getInputPorts();
+        if (inputPorts.size() == 1) {
+            // This is the initial port, so leave it alone
+            return;
+        }
+        DataPort portToBeRemoved = null;
+        for (DataPort dataPort : inputPorts) {
+            if (null == dataPort.getFromNode()) {
+                getComponent().removeInputPort((DynamicComponentPort) dataPort.getComponentPort());
+                portToBeRemoved = dataPort;
+                break;
+            }
+        }
+        if (null != portToBeRemoved) {
+            this.removeInputPort(portToBeRemoved);
+        }
+    }
+
+    /**
+     * @param url
+     */
+    public void setImplURL(URL url) {
+        this.getComponent().setImplJarLocation(url);
+    }
+
+    /**
+     * @param operationName
+     */
+    public void setOperationName(String operationName) {
+        this.getComponent().setOperationName(operationName);
+    }
+
+    /**
+     * @param className
+     */
+    public void setClassName(String className) {
+        this.getComponent().setClassName(className);
+    }
+
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicPort.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicPort.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicPort.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/DynamicPort.java Thu May 17 17:12:15 2012
@@ -0,0 +1,88 @@
+/*
+ *
+ * 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.graph.dynamic;
+
+import javax.xml.namespace.QName;
+
+import org.apache.airavata.workflow.model.component.ComponentPort;
+import org.apache.airavata.workflow.model.component.dynamic.DynamicComponentPort;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.impl.NodeImpl;
+
+public class DynamicPort extends DataPort {
+
+    private DynamicComponentPort componentPort;
+
+    /**
+     * Constructs a DynamicPort.
+     * 
+     */
+    public DynamicPort() {
+        super();
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.DataPort#copyType(org.apache.airavata.workflow.model.graph.DataPort)
+     */
+    @Override
+    public void copyType(DataPort port) throws GraphException {
+
+    }
+
+    /**
+     * Returns the typeQName.
+     * 
+     * @return The typeQName
+     */
+    @Override
+    public QName getType() {
+        return getComponentPort().getType();
+    }
+
+    public void setComponentPort(ComponentPort componentPort) {
+        super.setComponentPort(componentPort);
+        this.componentPort = (DynamicComponentPort) componentPort;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.impl.PortImpl#getComponentPort()
+     */
+    @Override
+    public DynamicComponentPort getComponentPort() {
+        if (this.componentPort == null) {
+            ComponentPort port = super.getComponentPort();
+            if (port instanceof DynamicComponentPort) {
+                this.componentPort = (DynamicComponentPort) port;
+            } else {
+                throw new WorkflowRuntimeException("UNEXPECTED ERROR: Unable to resolve Port");
+            }
+
+        }
+        return this.componentPort;
+    }
+
+    public void setNode(NodeImpl node) {
+        super.setNode(node);
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/PortAddable.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/PortAddable.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/PortAddable.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/PortAddable.java Thu May 17 17:12:15 2012
@@ -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.workflow.model.graph.dynamic;
+
+import org.apache.airavata.workflow.model.graph.DataPort;
+import org.apache.airavata.workflow.model.graph.GraphException;
+
+public interface PortAddable {
+
+    public abstract void removeLastDynamicallyAddedInPort() throws GraphException;
+
+    public abstract DataPort getFreeInPort();
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/SchemaCompilerUtil.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/SchemaCompilerUtil.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/SchemaCompilerUtil.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/dynamic/SchemaCompilerUtil.java Thu May 17 17:12:15 2012
@@ -0,0 +1,224 @@
+/*
+ *
+ * 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.graph.dynamic;
+
+import java.io.File;
+import java.net.URI;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.apache.xmlbeans.SchemaCodePrinter;
+import org.apache.xmlbeans.impl.common.IOUtil;
+import org.apache.xmlbeans.impl.common.XmlErrorPrinter;
+import org.apache.xmlbeans.impl.tool.CodeGenUtil;
+import org.apache.xmlbeans.impl.tool.CommandLine;
+import org.apache.xmlbeans.impl.tool.SchemaCompiler;
+import org.apache.xmlbeans.impl.values.XmlListImpl;
+
+public class SchemaCompilerUtil extends SchemaCompiler {
+
+    public static void compile(String[] args) {
+        if (args.length == 0) {
+            return;
+        }
+
+        Set flags = new HashSet();
+        flags.add("h");
+        flags.add("help");
+        flags.add("usage");
+        flags.add("license");
+        flags.add("quiet");
+        flags.add("verbose");
+        flags.add("version");
+        flags.add("dl");
+        flags.add("noupa");
+        flags.add("nopvr");
+        flags.add("noann");
+        flags.add("novdoc");
+        flags.add("noext");
+        flags.add("srconly");
+        flags.add("debug");
+
+        Set opts = new HashSet();
+        opts.add("out");
+        opts.add("name");
+        opts.add("src");
+        opts.add("d");
+        opts.add("cp");
+        opts.add("compiler");
+        opts.add("javasource");
+        opts.add("jar"); // deprecated
+        opts.add("ms");
+        opts.add("mx");
+        opts.add("repackage");
+        opts.add("schemaCodePrinter");
+        opts.add("extension");
+        opts.add("extensionParms");
+        opts.add("allowmdef");
+        opts.add("catalog");
+        CommandLine cl = new CommandLine(args, flags, opts);
+
+        String[] badopts = cl.getBadOpts();
+        if (badopts.length > 0) {
+            for (int i = 0; i < badopts.length; i++)
+                System.out.println("Unrecognized option: " + badopts[i]);
+            return;
+        }
+
+        boolean verbose = (cl.getOpt("verbose") != null);
+        boolean quiet = (cl.getOpt("quiet") != null);
+        if (verbose)
+            quiet = false;
+
+        String outputfilename = cl.getOpt("out");
+
+        String repackage = cl.getOpt("repackage");
+
+        cl.getOpt("schemaCodePrinter");
+        SchemaCodePrinter codePrinter = null;
+        String name = cl.getOpt("name");
+
+        boolean download = (cl.getOpt("dl") != null);
+        boolean noUpa = (cl.getOpt("noupa") != null);
+        boolean noPvr = (cl.getOpt("nopvr") != null);
+        boolean noAnn = (cl.getOpt("noann") != null);
+        boolean noVDoc = (cl.getOpt("novdoc") != null);
+        boolean noExt = (cl.getOpt("noext") != null);
+        boolean nojavac = (cl.getOpt("srconly") != null);
+        boolean debug = (cl.getOpt("debug") != null);
+
+        String allowmdef = cl.getOpt("allowmdef");
+        Set mdefNamespaces = (allowmdef == null ? Collections.EMPTY_SET : new HashSet(Arrays.asList(XmlListImpl
+                .split_list(allowmdef))));
+
+        List extensions = new ArrayList();
+
+        String classesdir = cl.getOpt("d");
+        File classes = null;
+        if (classesdir != null)
+            classes = new File(classesdir);
+
+        String srcdir = cl.getOpt("src");
+        File src = null;
+        if (srcdir != null)
+            src = new File(srcdir);
+        if (nojavac && srcdir == null && classes != null)
+            src = classes;
+
+        // create temp directory
+        File tempdir = null;
+        if (src == null || classes == null) {
+            throw new WorkflowRuntimeException("Code gen src directory or classes directory is null");
+        }
+
+        File jarfile = null;
+        if (outputfilename == null && classes == null && !nojavac)
+            outputfilename = "xmltypes.jar";
+        if (outputfilename != null)
+            jarfile = new File(outputfilename);
+
+        if (src == null)
+            src = IOUtil.createDir(tempdir, "src");
+        if (classes == null)
+            classes = IOUtil.createDir(tempdir, "classes");
+
+        File[] classpath = null;
+        String cpString = cl.getOpt("cp");
+        if (cpString != null) {
+            String[] cpparts = cpString.split(File.pathSeparator);
+            List cpList = new ArrayList();
+            for (int i = 0; i < cpparts.length; i++)
+                cpList.add(new File(cpparts[i]));
+            classpath = (File[]) cpList.toArray(new File[cpList.size()]);
+        } else {
+            classpath = CodeGenUtil.systemClasspath();
+        }
+
+        String javasource = cl.getOpt("javasource");
+        String compiler = cl.getOpt("compiler");
+        String jar = cl.getOpt("jar");
+        if (verbose && jar != null)
+            System.out.println("The 'jar' option is no longer supported.");
+
+        String memoryInitialSize = cl.getOpt("ms");
+        String memoryMaximumSize = cl.getOpt("mx");
+
+        File[] xsdFiles = cl.filesEndingWith(".xsd");
+        File[] wsdlFiles = cl.filesEndingWith(".wsdl");
+        File[] javaFiles = cl.filesEndingWith(".java");
+        File[] configFiles = cl.filesEndingWith(".xsdconfig");
+        URL[] urlFiles = cl.getURLs();
+
+        if (xsdFiles.length + wsdlFiles.length + urlFiles.length == 0) {
+            System.out.println("Could not find any xsd or wsdl files to process.");
+            return;
+        }
+        File baseDir = cl.getBaseDir();
+        URI baseURI = baseDir == null ? null : baseDir.toURI();
+
+        XmlErrorPrinter err = new XmlErrorPrinter(verbose, baseURI);
+
+        String catString = cl.getOpt("catalog");
+
+        Parameters params = new Parameters();
+        params.setBaseDir(baseDir);
+        params.setXsdFiles(xsdFiles);
+        params.setWsdlFiles(wsdlFiles);
+        params.setJavaFiles(javaFiles);
+        params.setConfigFiles(configFiles);
+        params.setUrlFiles(urlFiles);
+        params.setClasspath(classpath);
+        params.setOutputJar(jarfile);
+        params.setName(name);
+        params.setSrcDir(src);
+        params.setClassesDir(classes);
+        params.setCompiler(compiler);
+        params.setJavaSource(javasource);
+        params.setMemoryInitialSize(memoryInitialSize);
+        params.setMemoryMaximumSize(memoryMaximumSize);
+        params.setNojavac(nojavac);
+        params.setQuiet(quiet);
+        params.setVerbose(verbose);
+        params.setDownload(download);
+        params.setNoUpa(noUpa);
+        params.setNoPvr(noPvr);
+        params.setNoAnn(noAnn);
+        params.setNoVDoc(noVDoc);
+        params.setNoExt(noExt);
+        params.setDebug(debug);
+        params.setErrorListener(err);
+        params.setRepackage(repackage);
+        params.setExtensions(extensions);
+        params.setMdefNamespaces(mdefNamespaces);
+        params.setCatalogFile(catString);
+        params.setSchemaCodePrinter(codePrinter);
+
+        compile(params);
+
+    }
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/EdgeImpl.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/EdgeImpl.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/EdgeImpl.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/EdgeImpl.java Thu May 17 17:12:15 2012
@@ -0,0 +1,164 @@
+/*
+ *
+ * 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.graph.impl;
+
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.graph.Edge;
+import org.apache.airavata.workflow.model.graph.GraphException;
+import org.apache.airavata.workflow.model.graph.GraphSchema;
+import org.xmlpull.infoset.XmlElement;
+
+/**
+ * The Edge represents an edge that connects a uses port to a provide port.
+ * 
+ */
+public abstract class EdgeImpl implements Edge {
+
+    private GraphImpl graph;
+
+    private PortImpl fromPort;
+
+    private PortImpl toPort;
+    // The followings are used only during parsing the XML.
+
+    private String fromPortID;
+
+    private String toPortID;
+
+    private String label;
+
+    /**
+     * Creates an Edge.
+     */
+    public EdgeImpl() {
+        // Do nothing
+    }
+
+    /**
+     * Constructs a EdgeImpl.
+     * 
+     * @param edgeXml
+     */
+    public EdgeImpl(XmlElement edgeXml) {
+        parse(edgeXml);
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Edge#getFromPort()
+     */
+    public PortImpl getFromPort() {
+        return this.fromPort;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Edge#getToPort()
+     */
+    public PortImpl getToPort() {
+        return this.toPort;
+    }
+
+    /**
+     * Sets a graph this edge belogs to.
+     * 
+     * @param graph
+     *            The graph
+     */
+    protected void setGraph(GraphImpl graph) {
+        this.graph = graph;
+    }
+
+    /**
+     * @param fromPort
+     */
+    protected void setFromPort(PortImpl fromPort) {
+        this.fromPort = fromPort;
+    }
+
+    /**
+     * @param toPort
+     */
+    protected void setToPort(PortImpl toPort) {
+        this.toPort = toPort;
+    }
+
+    protected void indexToPointer() throws GraphException {
+        this.fromPort = this.graph.getPort(this.fromPortID);
+        if (this.fromPort == null) {
+            throw new GraphException("Cannot find a port with the ID, " + this.fromPortID + ".");
+        }
+        this.toPort = this.graph.getPort(this.toPortID);
+        if (this.toPort == null) {
+            throw new GraphException("Cannot find a port with the ID, " + this.toPortID + ".");
+        }
+
+        // Has to do the above first because they are used in the edgeWasAdded
+        // method.
+        this.fromPort.addEdge(this);
+        this.toPort.addEdge(this);
+    }
+
+    /**
+     * @param edgeElement
+     */
+    protected void parse(XmlElement edgeElement) {
+        XmlElement fromPortElement = edgeElement.element(GraphSchema.EDGE_FROM_PORT_TAG);
+        this.fromPortID = fromPortElement.requiredText();
+
+        XmlElement toPortElement = edgeElement.element(GraphSchema.EDGE_TO_PORT_TAG);
+        this.toPortID = toPortElement.requiredText();
+    }
+
+    /**
+     * @return the XmlElement
+     */
+    protected XmlElement toXML() {
+        XmlElement edgeXml = XMLUtil.BUILDER.newFragment(GraphSchema.NS, GraphSchema.EDGE_TAG);
+
+        XmlElement fromEle = edgeXml.addElement(GraphSchema.NS, GraphSchema.EDGE_FROM_PORT_TAG);
+        fromEle.addChild(this.fromPort.getID());
+
+        XmlElement toEle = edgeXml.addElement(GraphSchema.NS, GraphSchema.EDGE_TO_PORT_TAG);
+        toEle.addChild(this.toPort.getID());
+
+        return edgeXml;
+    }
+
+    /**
+     * Returns the label.
+     * 
+     * @return The label
+     */
+    public String getLabel() {
+        return this.label;
+    }
+
+    /**
+     * Sets label.
+     * 
+     * @param label
+     *            The label to set.
+     */
+    public void setLabel(String label) {
+        this.label = label;
+    }
+
+}
\ No newline at end of file

Added: incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/GraphImpl.java
URL: http://svn.apache.org/viewvc/incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/GraphImpl.java?rev=1339718&view=auto
==============================================================================
--- incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/GraphImpl.java (added)
+++ incubator/airavata/trunk/modules/workflow-model/src/main/java/org/apache/airavata/workflow/model/graph/impl/GraphImpl.java Thu May 17 17:12:15 2012
@@ -0,0 +1,656 @@
+/*
+ *
+ * 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.graph.impl;
+
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.airavata.common.utils.XMLUtil;
+import org.apache.airavata.workflow.model.exceptions.WorkflowRuntimeException;
+import org.apache.airavata.workflow.model.graph.ControlPort;
+import org.apache.airavata.workflow.model.graph.DataEdge;
+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.GraphFactory;
+import org.apache.airavata.workflow.model.graph.GraphSchema;
+import org.apache.airavata.workflow.model.graph.Node;
+import org.apache.airavata.workflow.model.graph.Port;
+import org.apache.airavata.workflow.model.graph.Port.Kind;
+import org.apache.airavata.workflow.model.graph.system.InputNode;
+import org.apache.airavata.workflow.model.graph.system.OutputNode;
+import org.apache.airavata.workflow.model.graph.system.StreamSourceNode;
+import org.apache.airavata.workflow.model.graph.system.SystemDataPort;
+import org.apache.airavata.workflow.model.graph.util.GraphUtil;
+import org.apache.airavata.workflow.model.graph.ws.WSPort;
+import org.apache.airavata.workflow.model.utils.ApplicationVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xmlpull.infoset.XmlElement;
+
+public abstract class GraphImpl implements Graph {
+
+    private static final Logger logger = LoggerFactory.getLogger(GraphImpl.class);
+
+    /**
+     * Unique ID of this workflow
+     */
+    private String id;
+
+    /**
+     * Name of the workflow. It has to have one.
+     */
+    private String name = "Workflow";
+
+    /**
+     * Default to empty string to avoid null check.
+     */
+    private String description = "";
+
+    private List<NodeImpl> nodes = new LinkedList<NodeImpl>();
+
+    private List<PortImpl> ports = new LinkedList<PortImpl>();
+
+    private List<EdgeImpl> edges = new LinkedList<EdgeImpl>();
+
+    private GraphFactory factory;
+
+    /**
+     * @param factory
+     */
+    public GraphImpl(GraphFactory factory) {
+        this.factory = factory;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getID()
+    */
+        public String getID() {
+             if (this.id == null) {
+                 this.id = this.name;
+                 // If its still null
+                 if (null == this.id) {
+                    throw new WorkflowRuntimeException("The workflow ID is null");
+                 }
+             }
+            return this.id;
+        }
+
+
+    /**
+     * This will only be done for the ODE
+     * 
+     * @param id
+     */
+    public void setID(String id) {
+        this.id = id;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#setName(java.lang.String)
+     */
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getName()
+     */
+    public String getName() {
+        return this.name;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getDescription()
+     */
+    public String getDescription() {
+        return this.description;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#setDescription(java.lang.String)
+     */
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getNodes()
+     */
+    public List<NodeImpl> getNodes() {
+        return this.nodes;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getPorts()
+     */
+    public List<PortImpl> getPorts() {
+        return this.ports;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getEdges()
+     */
+    public List<EdgeImpl> getEdges() {
+        return this.edges;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#removeNode(org.apache.airavata.workflow.model.graph.Node)
+     */
+    public void removeNode(Node node) throws GraphException {
+        if (node == null) {
+            throw new IllegalArgumentException("null");
+        }
+        if (!this.nodes.contains(node)) {
+            throw new GraphException("The graph doesn't contain the node that is being removed.");
+        }
+
+        NodeImpl nodeImpl = (NodeImpl) node;
+
+        // Have to be very careful to remove the node.
+        // The extended for loop cannot be used to remove the elements.
+
+        // Remove edges connected to input ports.
+        for (Iterator<DataPort> portItr = nodeImpl.getInputPorts().iterator(); portItr.hasNext();) {
+            DataPort port = portItr.next();
+            for (Iterator<DataEdge> edgeItr = port.getEdges().iterator(); edgeItr.hasNext();) {
+                DataEdge edge = edgeItr.next();
+                // Remove the edge from from-port.
+                DataPort fromPort = edge.getFromPort();
+                fromPort.removeEdge(edge);
+                // remove the edge from this port. This is necessary so that
+                // type update works properly.
+                edgeItr.remove();
+
+                // Remove the edge from the graph.
+                this.edges.remove(edge);
+                fromPort.getNode().edgeWasRemoved(edge);
+            }
+            // Remove the port from the node.
+            portItr.remove();
+            // Remove the port from the graph.
+            this.ports.remove(port);
+        }
+
+        // Remove edges connected to output ports.
+        for (Iterator<DataPort> portItr = nodeImpl.getOutputPorts().iterator(); portItr.hasNext();) {
+            DataPort port = portItr.next();
+            for (Iterator<DataEdge> edgeItr = port.getEdges().iterator(); edgeItr.hasNext();) {
+                DataEdge edge = edgeItr.next();
+                DataPort toPort = edge.getToPort();
+                toPort.removeEdge(edge);
+                edgeItr.remove();
+                this.edges.remove(edge);
+                toPort.getNode().edgeWasRemoved(edge);
+            }
+            portItr.remove();
+            this.ports.remove(port);
+        }
+
+        for (Iterator<ControlPort> portItr = nodeImpl.getControlOutPorts().iterator(); portItr.hasNext();) {
+            PortImpl port = portItr.next();
+            for (Iterator<? extends EdgeImpl> edgeItr = port.getEdges().iterator(); edgeItr.hasNext();) {
+                EdgeImpl edge = edgeItr.next();
+                PortImpl toPort = edge.getToPort();
+                toPort.removeEdge(edge);
+                edgeItr.remove();
+                this.edges.remove(edge);
+                toPort.getNode().edgeWasRemoved(edge);
+            }
+            portItr.remove();
+            this.ports.remove(port);
+        }
+
+        PortImpl controlInPort = nodeImpl.getControlInPort();
+        if (controlInPort != null) {
+            for (Iterator<? extends EdgeImpl> edgeItr = controlInPort.getEdges().iterator(); edgeItr.hasNext();) {
+                EdgeImpl edge = edgeItr.next();
+                PortImpl fromPort = edge.getFromPort();
+                fromPort.removeEdge(edge);
+                edgeItr.remove();
+                this.edges.remove(edge);
+                fromPort.getNode().edgeWasRemoved(edge);
+            }
+            this.ports.remove(controlInPort);
+        }
+
+        PortImpl eprPort = nodeImpl.getEPRPort();
+        if (eprPort != null) {
+            for (Iterator<? extends EdgeImpl> edgeItr = eprPort.getEdges().iterator(); edgeItr.hasNext();) {
+                EdgeImpl edge = edgeItr.next();
+                PortImpl toPort = edge.getToPort();
+                toPort.removeEdge(edge);
+                edgeItr.remove();
+                this.edges.remove(edge);
+                toPort.getNode().edgeWasRemoved(edge);
+            }
+            this.ports.remove(eprPort);
+        }
+
+        this.nodes.remove(node);
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getNode(java.lang.String)
+     */
+    public NodeImpl getNode(String nodeID) {
+        for (NodeImpl node : this.nodes) {
+            if (nodeID.equals(node.getID())) {
+                return node;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param port
+     * @throws GraphException
+     */
+    public void removePort(Port port) throws GraphException {
+        if (port == null) {
+            throw new IllegalArgumentException("null");
+        }
+        if (!this.ports.contains(port)) {
+            throw new GraphException("The graph doesn't contain the port that is being removed.");
+        }
+
+        // copy it so that we can remove edge without worrying about the
+        // iteration issue.
+        ArrayList<Edge> edgesToBeRemoved = new ArrayList<Edge>(port.getEdges());
+        for (Edge edge : edgesToBeRemoved) {
+            removeEdge(edge);
+        }
+
+        this.ports.remove(port);
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#getPort(java.lang.String)
+     */
+    public PortImpl getPort(String portID) {
+        for (PortImpl port : this.ports) {
+            if (portID.equals(port.getID())) {
+                return port;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#addEdge(org.apache.airavata.workflow.model.graph.Port,
+     *      org.apache.airavata.workflow.model.graph.Port)
+     */
+    public Edge addEdge(Port fromPort, Port toPort) throws GraphException {
+        if (containsEdge(fromPort, toPort)) {
+            // The edge already exists. Doesn't create a new one.
+            return null;
+        }
+
+        if (!this.ports.contains(fromPort) || !this.ports.contains(toPort)) {
+            // The specified port doesn't belong to the graph.
+            throw new GraphException("The graph doesn't contain the specified port.");
+        }
+
+        PortImpl fromPortImpl = (PortImpl) fromPort;
+        PortImpl toPortImpl = (PortImpl) toPort;
+        NodeImpl fromNode = fromPortImpl.getNode();
+        NodeImpl toNode = toPortImpl.getNode();
+
+        EdgeImpl edge = this.factory.createEdge(fromPort, toPort);
+
+        edge.setFromPort(fromPortImpl);
+        edge.setToPort(toPortImpl);
+        fromPortImpl.addEdge(edge);
+        toPortImpl.addEdge(edge);
+        addEdge(edge);
+
+        try {
+            fromNode.edgeWasAdded(edge);
+            toNode.edgeWasAdded(edge);
+            return edge;
+        } catch (GraphException e) {
+            removeEdge(edge);
+            throw e;
+        }
+
+    }
+
+    /**
+     * @throws GraphException
+     * @see org.apache.airavata.workflow.model.graph.Graph#removeEdge(org.apache.airavata.workflow.model.graph.Edge)
+     */
+    public void removeEdge(Edge edge) throws GraphException {
+        if (!this.edges.contains(edge)) {
+            throw new GraphException("The graph doesn't contain the specified edge.");
+        }
+        EdgeImpl edgeImpl = (EdgeImpl) edge;
+
+        PortImpl fromPort = edgeImpl.getFromPort();
+        PortImpl toPort = edgeImpl.getToPort();
+
+        NodeImpl fromNode = fromPort.getNode();
+        NodeImpl toNode = toPort.getNode();
+
+        fromPort.removeEdge(edgeImpl);
+        toPort.removeEdge(edgeImpl);
+
+        this.edges.remove(edgeImpl);
+
+        // This has to be after removing edges.
+        fromNode.edgeWasRemoved(edge);
+        toNode.edgeWasRemoved(edge);
+    }
+
+    /**
+     * @throws GraphException
+     * @see org.apache.airavata.workflow.model.graph.Graph#removeEdge(org.apache.airavata.workflow.model.graph.Port,
+     *      org.apache.airavata.workflow.model.graph.Port)
+     */
+    public void removeEdge(Port fromPort, Port toPort) throws GraphException {
+        Collection<? extends Edge> fromEdges = fromPort.getEdges();
+        for (Edge fromEdge : fromEdges) {
+            if (fromEdge.getToPort() == toPort) {
+                // It's OK to remove this way because it will exit the loop
+                // right away.
+                removeEdge(fromEdge);
+                return;
+            }
+        }
+        throw new WorkflowRuntimeException("No edge exist between two ports.");
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#containsEdge(org.apache.airavata.workflow.model.graph.Port,
+     *      org.apache.airavata.workflow.model.graph.Port)
+     */
+    public boolean containsEdge(Port fromPort, Port toPort) {
+        for (Edge fromEdge : fromPort.getEdges()) {
+            Collection<? extends Edge> toEdges = toPort.getEdges();
+            if (toEdges.contains(fromEdge)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @throws GraphException
+     * @see org.apache.airavata.workflow.model.graph.Graph#importGraph(org.apache.airavata.workflow.model.graph.Graph)
+     */
+    public void importGraph(Graph graph) throws GraphException {
+
+        // Does not support other implementations.
+        if (!(graph instanceof GraphImpl)) {
+            throw new GraphException("Cannot import this graph implementation");
+        }
+
+        GraphImpl graphImpl = (GraphImpl) graph;
+
+        for (NodeImpl node : graphImpl.getNodes()) {
+            addNode(node);
+            // Recreates the ID so that it doesn't conflict with the existing
+            // one.
+            node.createID();
+            // Changes the position.
+            Point position = node.getPosition();
+            node.setPosition(new Point(position.x + 5, position.y + 5));
+        }
+
+        for (PortImpl port : graphImpl.getPorts()) {
+            addPort(port);
+        }
+
+        for (EdgeImpl edge : graphImpl.getEdges()) {
+            addEdge(edge);
+        }
+    }
+
+    /**
+     * @see org.apache.airavata.workflow.model.graph.Graph#toXML()
+     */
+    public XmlElement toXML() {
+
+        XmlElement graphElement = XMLUtil.BUILDER.newFragment(GraphSchema.NS, GraphSchema.GRAPH_TAG);
+
+        graphElement.setAttributeValue(GraphSchema.NS, GraphSchema.XBAYA_VERSION_ATTRIBUTE, ApplicationVersion.VERSION);
+
+        XmlElement idElement = graphElement.addElement(GraphSchema.NS, GraphSchema.GRAPH_ID_TAG);
+        idElement.addChild(getID());
+
+        if (this.name != null) {
+            XmlElement nameElement = graphElement.addElement(GraphSchema.NS, GraphSchema.GRAPH_NAME_TAG);
+            nameElement.addChild(getName());
+        }
+
+        if (this.description != null) {
+            XmlElement descriptionElement = graphElement.addElement(GraphSchema.NS, GraphSchema.GRAPH_DESCRIPTION_TAG);
+            descriptionElement.addChild(getDescription());
+        }
+
+        toXML(graphElement);
+
+        for (NodeImpl node : this.nodes) {
+            XmlElement nodeElement = node.toXML();
+            graphElement.addChild(nodeElement);
+        }
+
+        for (PortImpl port : this.ports) {
+            XmlElement portElement = port.toXML();
+            graphElement.addChild(portElement);
+        }
+
+        for (EdgeImpl edge : this.edges) {
+            XmlElement edgeElement = edge.toXML();
+            graphElement.addChild(edgeElement);
+        }
+
+        return graphElement;
+    }
+
+    /**
+     * @param graphElement
+     */
+    protected void toXML(@SuppressWarnings("unused") XmlElement graphElement) {
+        // For subclass to overwrite.
+    }
+
+    /**
+     * @param graphElement
+     * @throws GraphException
+     */
+    protected void parse(XmlElement graphElement) throws GraphException {
+        String version = graphElement.attributeValue(GraphSchema.NS, GraphSchema.XBAYA_VERSION_ATTRIBUTE);
+        logger.info("parsing a workflow created by version " + version);
+
+        XmlElement idElement = graphElement.element(GraphSchema.GRAPH_ID_TAG);
+        if (idElement != null) {
+            this.id = idElement.requiredText();
+        }
+
+        XmlElement nameElement = graphElement.element(GraphSchema.GRAPH_NAME_TAG);
+        if (nameElement != null) {
+            this.name = nameElement.requiredText();
+        }
+
+        XmlElement descriptionElement = graphElement.element(GraphSchema.GRAPH_DESCRIPTION_TAG);
+        if (descriptionElement != null) {
+            this.description = descriptionElement.requiredText();
+        }
+
+        for (XmlElement nodeElement : graphElement.elements(null, GraphSchema.NODE_TAG)) {
+            NodeImpl nodeImpl = this.factory.createNode(nodeElement);
+            // need to call this to set this graph to the node.
+            addNode(nodeImpl);
+        }
+
+        for (XmlElement portElement : graphElement.elements(null, GraphSchema.PORT_TAG)) {
+            PortImpl port = this.factory.createPort(portElement);
+            // need to call this to set this graph to the port.
+            this.addPort(port);
+        }
+
+        for (XmlElement edgeElement : graphElement.elements(null, GraphSchema.EDGE_TAG)) {
+            EdgeImpl edge = this.factory.createEdge(edgeElement);
+            // need to call this to set this graph to the edge.
+            this.addEdge(edge);
+        }
+
+        indexToPointer();
+    }
+
+    /**
+     * Adds a node.
+     * 
+     * @param node
+     *            the node to add
+     */
+    protected void addNode(NodeImpl node) {
+        node.setGraph(this);
+        // if this is a Stream now put it at the begining
+        if (node instanceof StreamSourceNode) {
+            this.nodes.add(0, node);
+        } else {
+            this.nodes.add(node);
+        }
+    }
+
+    /**
+     * @param port
+     */
+    protected void addPort(PortImpl port) {
+        port.setGraph(this);
+        this.ports.add(port);
+    }
+
+    /**
+     * Converts indexes to references. This method is called after reading the graph from an XML file.
+     * 
+     * @throws GraphException
+     */
+    protected void indexToPointer() throws GraphException {
+        for (NodeImpl node : this.nodes) {
+            node.indexToPointer();
+        }
+        for (PortImpl port : this.ports) {
+            port.indexToPointer();
+        }
+        for (EdgeImpl edge : this.edges) {
+            edge.indexToPointer();
+        }
+    }
+
+    /**
+     * @param edge
+     */
+    private void addEdge(EdgeImpl edge) {
+        edge.setGraph(this);
+        this.edges.add(edge);
+    }
+
+    // private void createID() {
+    // Date date = new Date();
+    // SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd_HHmmss_S");
+    // String time = format.format(date);
+    //
+    // this.id = StringUtil.convertToJavaIdentifier(this.name) + "_" + time;
+    // }
+
+    /**
+     * @throws GraphException
+     */
+    public void fixParameterNodes() {
+        // XXX fix the ports of parameter nodes for 2.6.3 or before.
+        for (InputNode node : GraphUtil.getNodes(this, InputNode.class)) {
+            DataPort oldPort = node.getOutputPort(0);
+            if (oldPort instanceof WSPort) {
+                node.getOutputPorts().remove(oldPort);
+                this.ports.remove(oldPort);
+                SystemDataPort newPort = new SystemDataPort();
+                this.ports.add(newPort);
+                newPort.setKind(Kind.DATA_OUT);
+                newPort.setName(oldPort.getName());
+                newPort.setGraph(this);
+                newPort.setNode(node);
+                newPort.createID();
+                node.getOutputPorts().add(newPort);
+                for (DataEdge edge : oldPort.getEdges()) {
+                    edge.setFromPort(newPort);
+                    newPort.getEdges().add(edge);
+                }
+            }
+        }
+        for (OutputNode node : GraphUtil.getNodes(this, OutputNode.class)) {
+            DataPort oldPort = node.getInputPort(0);
+            if (oldPort instanceof WSPort) {
+                node.getInputPorts().remove(oldPort);
+                this.ports.remove(oldPort);
+                SystemDataPort newPort = new SystemDataPort();
+                this.ports.add(newPort);
+                newPort.setKind(Kind.DATA_IN);
+                newPort.setName(oldPort.getName());
+                newPort.setGraph(this);
+                newPort.setNode(node);
+                newPort.createID();
+                node.getInputPorts().add(newPort);
+                for (DataEdge edge : oldPort.getEdges()) {
+                    edge.setToPort(newPort);
+                    newPort.getEdges().add(edge);
+                }
+            }
+        }
+    }
+
+    /**
+     * This returns the number of input Nodes, this will be useful when adding unique Id for nodes
+     * @return
+     */
+    public int getCurrentInputNodeCount(){
+        int index=0;
+        for(Node node:nodes){
+            if(node instanceof InputNode){
+                index++;
+            }
+        }
+        return index;
+    }
+    /**
+    * This returns the number of input Nodes, this will be useful when adding unique Id for nodes
+      * @return
+      */
+     public int getCurrentOutputNodeCount(){
+         int index=0;
+         for(Node node:nodes){
+             if(node instanceof OutputNode){
+                 index++;
+             }
+         }
+         return index;
+     }
+
+
+}
\ No newline at end of file