Package org.apache.airavata.xbaya.datadriven

Source Code of org.apache.airavata.xbaya.datadriven.WorkflowHarvester

/*
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/

package org.apache.airavata.xbaya.datadriven;

import java.awt.Point;
import java.util.LinkedList;
import java.util.List;

import javax.xml.namespace.QName;

import org.apache.airavata.common.utils.Pair;
import org.apache.airavata.xbaya.XBayaRuntimeException;
import org.apache.airavata.xbaya.component.system.InputComponent;
import org.apache.airavata.xbaya.graph.DataPort;
import org.apache.airavata.xbaya.graph.GraphException;
import org.apache.airavata.xbaya.graph.Node;
import org.apache.airavata.xbaya.graph.Port;
import org.apache.airavata.xbaya.graph.impl.NodeImpl;
import org.apache.airavata.xbaya.graph.system.InputNode;
import org.apache.airavata.xbaya.graph.ws.WSNode;
import org.apache.airavata.xbaya.wf.Workflow;

public class WorkflowHarvester {

    public WorkflowHarvester() {

    }

    public Workflow[] harvest(Workflow workflow, QName dataType) {
        LinkedList<Workflow> harvest = new LinkedList<Workflow>();
        LinkedList<Pair<String, String>> candidates = getCandidates(workflow, dataType);
        for (Pair<String, String> pair : candidates) {
            Workflow clone = workflow.clone();

            NodeImpl node = clone.getGraph().getNode(pair.getLeft());
            if (null == node) {
                throw new XBayaRuntimeException("Specified node not found:" + pair.getLeft());
            }
            Port candidatePort = null;
            List<DataPort> inPorts = node.getInputPorts();
            for (DataPort dataPort : inPorts) {
                if (pair.getRight().equals(dataPort.getID())) {
                    candidatePort = dataPort;
                    break;
                }
            }
            if (null == candidatePort) {
                throw new XBayaRuntimeException("Specifies Port was not found:" + pair.getRight());
            }
            if (!(candidatePort.getFromNode() instanceof InputNode)) {
                removeUnnecessaryNodes(node, candidatePort, clone);
                Node input = clone.addNode(new InputComponent());
                input.setPosition(new Point(Math.max(0, node.getPosition().x - 150), node.getPosition().y));

                // the returned workflows size should be less than that of the
                // original
                if (clone.getGraph().getNodes().size() < workflow.getGraph().getNodes().size()
                // if the sizes the different its a candidate, but need
                // to make sure
                // its not the same as one already harvested
                        && !isWorkflowAlreadyHarvested(harvest, clone)) {
                    try {
                        clone.getGraph().addEdge(input.getOutputPort(0), candidatePort);
                        cleanLeftOverInputNodes(clone);
                    } catch (GraphException e) {
                        throw new RuntimeException(e);
                    }

                    harvest.add(clone);
                }

            }
        }
        return harvest.toArray(new Workflow[0]);
    }

    /**
     * @param clone
     */
    private void cleanLeftOverInputNodes(Workflow clone) {

        List<NodeImpl> nodes = clone.getGraph().getNodes();
        LinkedList<Node> removeList = new LinkedList<Node>();
        for (Node nodeImpl : nodes) {
            if (nodeImpl instanceof InputNode) {
                if (nodeImpl.getOutputPort(0).getToNodes().size() == 0) {
                    removeList.add(nodeImpl);
                }
            }
        }
        for (Node node : removeList) {
            try {
                clone.removeNode(node);
            } catch (GraphException e) {
                throw new XBayaRuntimeException(e);
            }
        }
    }

    /**
     * @param harvest
     * @param clone
     * @return
     */
    private boolean isWorkflowAlreadyHarvested(LinkedList<Workflow> harvest, Workflow clone) {
        for (Workflow workflow : harvest) {
            if (workflow.equals(clone)) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param pair
     * @param clone
     */
    private void removeUnnecessaryNodes(Node node, Port candidatePort, Workflow workflow) {
        if (candidatePort.getFromPort().getEdges().size() == 1) {
            Node fromNode = candidatePort.getFromNode();
            try {
                List<DataPort> inputPorts = fromNode.getInputPorts();
                for (DataPort dataPort : inputPorts) {
                    removeUnnecessaryNodes(fromNode, dataPort, workflow);
                }
                workflow.removeNode(fromNode);
            } catch (GraphException e) {
                throw new XBayaRuntimeException(e);
            }
        }
    }

    /**
     * @param pair
     * @return
     */
    private List<DataPort> getRemainderPorts(Pair<WSNode, DataPort> pair) {
        LinkedList<DataPort> ret = new LinkedList<DataPort>();
        List<DataPort> inputPorts = pair.getLeft().getInputPorts();
        for (DataPort dataPort : inputPorts) {
            if (pair.getRight() != dataPort) {
                ret.add(dataPort);
            }
        }
        return ret;
    }

    /**
     * @param workflow
     * @param dataType
     * @return pair of nodeid and portid
     */
    private LinkedList<Pair<String, String>> getCandidates(Workflow workflow, QName dataType) {
        LinkedList<Pair<String, String>> candidates = new LinkedList<Pair<String, String>>();
        List<NodeImpl> nodes = workflow.getGraph().getNodes();
        for (NodeImpl node : nodes) {
            if (node instanceof WSNode) {
                List<DataPort> inputPorts = ((WSNode) node).getInputPorts();
                for (DataPort dataPort : inputPorts) {

                    if (dataType.equals(dataPort.getType())) {
                        candidates.add(new Pair<String, String>(node.getID(), dataPort.getID()));
                    }

                }
            }
        }

        return candidates;
    }

}
TOP

Related Classes of org.apache.airavata.xbaya.datadriven.WorkflowHarvester

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.