com.synflow.models.graph.visit.ReversePostOrder.java Source code

Java tutorial

Introduction

Here is the source code for com.synflow.models.graph.visit.ReversePostOrder.java

Source

/*******************************************************************************
 * Copyright (c) 2012-2014 Synflow SAS.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Matthieu Wipliez - initial API and implementation and/or initial documentation
 *******************************************************************************/
package com.synflow.models.graph.visit;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

import org.eclipse.emf.ecore.EReference;

import com.google.common.collect.Lists;
import com.synflow.models.graph.Edge;
import com.synflow.models.graph.Graph;
import com.synflow.models.graph.GraphPackage;
import com.synflow.models.graph.Vertex;

/**
 * This class defines a reverse post order based on a post-order DFS.
 * 
 * @author Matthieu Wipliez
 * 
 */
public class ReversePostOrder extends DFS {

    /**
     * Creates the reverse post-ordering of the given graph, starting from the given roots. If
     * <code>roots</code> is <code>null</code> or empty, this method visits the graph to find roots.
     * If no entry vertex is found, the first vertex of the graph is used.
     * 
     * @param graph
     *            a graph
     * @param refEdges
     *            the EReference that returns either the incoming or outgoing edges of a vertex
     * @param refVertex
     *            the EReference that returns either the source or target of an edge
     * @param roots
     *            a list of vertex
     */
    @SuppressWarnings("unchecked")
    public ReversePostOrder(Graph graph, EReference refEdges, EReference refVertex, List<? extends Vertex> roots) {
        super(refEdges, refVertex, graph.getVertices().size());

        if (roots == null || roots.isEmpty()) {
            roots = new ArrayList<Vertex>();
            EReference opposite = refVertex.getEOpposite();
            for (Vertex vertex : graph.getVertices()) {
                List<Edge> edges = (List<Edge>) vertex.eGet(opposite);
                if (edges.isEmpty()) {
                    ((List<Vertex>) roots).add(vertex);
                }
            }
        }

        if (roots.isEmpty()) {
            // no entry point in the graph, take the first vertex
            if (!graph.getVertices().isEmpty()) {
                visitPost(graph.getVertices().get(0));
            }
        } else {
            ListIterator<? extends Vertex> it = roots.listIterator(roots.size());
            while (it.hasPrevious()) {
                visitPost(it.previous());
            }
        }
    }

    /**
     * Creates the reverse post-ordering of the given graph, starting from the given roots. If
     * <code>roots</code> is <code>null</code> or empty, this method visits the graph to find roots.
     * If no entry vertex is found, the first vertex of the graph is used.
     * 
     * @param graph
     *            a graph
     * @param refEdges
     *            the EReference that returns either the incoming or outgoing edges of a vertex
     * @param refVertex
     *            the EReference that returns either the source or target of an edge
     * @param entries
     *            entry vertices given individually
     */
    public ReversePostOrder(Graph graph, EReference refEdges, EReference refVertex, Vertex... entries) {
        this(graph, refEdges, refVertex, Arrays.asList(entries));
    }

    /**
     * Creates the reverse post-ordering of the given graph, starting from the given entries. If
     * <code>entries</code> is <code>null</code> or empty, this method visits the graph to find
     * roots. If no entry vertex is found, the first vertex of the graph is used.
     * 
     * @param graph
     *            a graph
     * @param entries
     *            a list of vertex
     */
    public ReversePostOrder(Graph graph, List<? extends Vertex> entries) {
        this(graph, GraphPackage.Literals.VERTEX__OUTGOING, GraphPackage.Literals.EDGE__TARGET, entries);
    }

    /**
     * Creates the reverse post-ordering of the given graph, starting from the given entries. This
     * is a convenience constructor equivalent to <code>this(graph, Arrays.asList(entries));</code>.
     * 
     * @param graph
     *            a graph
     * @param entries
     *            entry vertices given individually
     */
    public ReversePostOrder(Graph graph, Vertex... entries) {
        this(graph, Arrays.asList(entries));
    }

    @Override
    public Iterator<Vertex> iterator() {
        return Lists.reverse(vertices).iterator();
    }

}