org.openflamingo.engine.dag.TSWorkflowExecutionPlanner.java Source code

Java tutorial

Introduction

Here is the source code for org.openflamingo.engine.dag.TSWorkflowExecutionPlanner.java

Source

/**
 * 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.openflamingo.engine.dag;

import org.apache.commons.lang.StringUtils;
import org.jgrapht.graph.DefaultEdge;
import org.jgrapht.graph.DirectedMultigraph;
import org.jgrapht.traverse.TopologicalOrderIterator;
import org.openflamingo.engine.util.WorkflowUtils;
import org.openflamingo.model.workflow.ActionType;
import org.openflamingo.model.workflow.BaseType;
import org.openflamingo.model.workflow.NodeType;
import org.openflamingo.model.workflow.Workflow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * Topological Sort Graph Algorithm  Workflow Execution Planner.
 *
 * @author Byoung Gon, Kim
 * @since 0.2
 */
public class TSWorkflowExecutionPlanner implements WorkflowExecutionPlanner {

    /**
     * SLF4J Logging
     */
    private Logger logger = LoggerFactory.getLogger(TSWorkflowExecutionPlanner.class);

    /**
     * Workflow Action?  ?  JAXB Object
     */
    private List<BaseType> orderedActions;

    /**
     * Workflow Action?  ?  Name
     */
    private List<String> namesOfActions;

    /**
     * Workflow Action?  JAXB Object 
     */
    private Map<String, String> nextOfAction;

    /**
     *  ? ?     Workflow Action 
     */
    private Map<String, String> reversedActions;

    /**
     * Workflow Action?  JAXB Object 
     */
    private Map<String, Object> actionMap;

    /**
     * Workflow XML JAXB Object
     */
    private Workflow workflow;

    /**
     * Topological Sort Iterator. ? Iterator? 
     *  Workflow XML? ??   ? from to?   .
     */
    private TopologicalOrderIterator iterator;

    /**
     *  ??. ?  ??    ?
     *  ?   ?   ?  ?.
     *
     * @param workflow Workflow XML JAXB Object
     * @throws Exception    
     */
    public TSWorkflowExecutionPlanner(Workflow workflow) throws Exception {
        this.workflow = workflow;
        this.namesOfActions = new LinkedList<String>();
        this.orderedActions = new LinkedList<BaseType>();
        this.actionMap = new HashMap<String, Object>();
        this.reversedActions = new HashMap<String, String>();
        this.nextOfAction = new HashMap<String, String>();
        this.iterator = new TopologicalOrderIterator(createGraph());

        // ? ? Action Name? ?.   ? ? ?.
        while (iterator.hasNext()) {
            namesOfActions.add((String) iterator.next());
        }

        // ? ?   ?   .
        for (String currentAction : namesOfActions) {
            if (actionMap.get(currentAction) instanceof NodeType) {
                //     ?? ?   .
                NodeType node = (NodeType) actionMap.get(currentAction);
                String[] tos = StringUtils.splitPreserveAllTokens(node.getTo(), ',');

                // ?? ? ?  ?   ? ?   .
                for (String to : tos) {
                    String reversedActions = buildReversedActions(this.reversedActions.get(to), currentAction);
                    this.reversedActions.put(to, reversedActions);
                }

                // ?  for        ?  ?.
                orderedActions.add((BaseType) actionMap.get(currentAction));
            } else { // BaseType ?  ?  End  ? .
                // ?  for        ?  ?.
                orderedActions.add((BaseType) actionMap.get(currentAction));
            }
        }
    }

    /**
     *    ? ?  ?  ?  ?? .
     *    (node1) ?? ?  node2? node2  ?   .
     * ?  ? node2? ?  node1    ?  ??  ?.
     * Hadoop  Workflow? ? ?    ?     ? .
     *
     * @param predecessor  ? ? 
     * @param current      
     * @return    ? ?  ?  ?  ?
     */
    private String buildReversedActions(String predecessor, String current) {
        List<String> nodes = new ArrayList<String>();
        if (predecessor != null) {
            String[] strings = StringUtils.splitPreserveAllTokens(predecessor, ',');
            Collections.addAll(nodes, strings);
        }
        nodes.add(current);
        return org.springframework.util.StringUtils.collectionToCommaDelimitedString(nodes);
    }

    /**
     * Topological Sort Graph Algorithm?   ?.
     *
     * @return Topological Sort Graph
     */
    private DirectedMultigraph<String, DefaultEdge> createGraph() {
        DirectedMultigraph<String, DefaultEdge> graph = new DirectedMultigraph<String, DefaultEdge>(
                DefaultEdge.class);

        // Add Action's Vertex
        List<ActionType> actions = workflow.getAction();
        for (ActionType actionType : actions) {
            graph.addVertex(actionType.getName());
            actionMap.put(actionType.getName(), actionType);
        }

        // Add Start's Vertex
        if (workflow.getStart() != null) {
            graph.addVertex(workflow.getStart().getName());
            actionMap.put(workflow.getStart().getName(), workflow.getStart());
        }

        // Add End's Vertex
        if (workflow.getEnd() != null) {
            graph.addVertex(workflow.getEnd().getName());
            actionMap.put(workflow.getEnd().getName(), workflow.getEnd());
        }

        // Add Action's Edge
        for (ActionType actionType : actions) {
            if (!StringUtils.isEmpty(actionType.getTo())) {
                nextOfAction.put(actionType.getName(), actionType.getTo());
                String[] targets = StringUtils.splitPreserveAllTokens(actionType.getTo(), ",");
                for (String target : targets) {
                    logger.trace("[Graph] {} => {}", actionType.getName(), target);
                    graph.addEdge(actionType.getName(), target);
                }
            }
        }

        // Add Start's Edge
        if (workflow.getStart() != null) {
            if (!StringUtils.isEmpty(workflow.getStart().getTo())) {
                nextOfAction.put(workflow.getStart().getName(), workflow.getStart().getTo());
                String[] targets = StringUtils.splitPreserveAllTokens(workflow.getStart().getTo(), ",");
                for (String target : targets) {
                    logger.trace("[Graph] {} => {}", workflow.getStart().getName(), target);
                    graph.addEdge(workflow.getStart().getName(), target);
                }
            }
        }

        return graph;
    }

    @Override
    public List<String> getNamesOfActions() {
        return namesOfActions;
    }

    @Override
    public Map<String, Object> getActionMap() {
        return actionMap;
    }

    @Override
    public Map<String, String> getGlobalVariables() {
        return WorkflowUtils.getGlobalVariables(workflow);
    }

    @Override
    public List<BaseType> getOrderedActions() {
        return orderedActions;
    }

    @Override
    public Map<String, String> getNextOfAction() {
        return nextOfAction;
    }

    @Override
    public Map<String, String> getReversedActions() {
        return reversedActions;
    }
}