org.eclipse.elk.tree.intermediate.NeighborsProcessor.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.elk.tree.intermediate.NeighborsProcessor.java

Source

/*******************************************************************************
 * Copyright (c) 2013, 2015 Kiel University and others.
 * 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:
 *     Kiel University - initial API and implementation
 *******************************************************************************/
package org.eclipse.elk.tree.intermediate;

import java.util.Iterator;

import org.eclipse.elk.core.util.IElkProgressMonitor;
import org.eclipse.elk.tree.ILayoutProcessor;
import org.eclipse.elk.tree.graph.TGraph;
import org.eclipse.elk.tree.graph.TNode;
import org.eclipse.elk.tree.properties.Properties;

import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;

/**
 * A processor which determine the neighbors and siblings for all nodes in the graph. A neighbor is
 * the current node's nearest node, at the same level. A siblings is a neighbor with the same
 * parent.
 * 
 * @author sor
 * @author sgu
 */
public class NeighborsProcessor implements ILayoutProcessor {

    /** the number of nodes in the given graph. */
    private int numberOfNodes;

    /**
     * {@inheritDoc}
     */
    public void process(final TGraph tGraph, final IElkProgressMonitor progressMonitor) {
        progressMonitor.begin("Processor set neighbors", 1f);

        /** save number of nodes for progress computation */
        numberOfNodes = tGraph.getNodes().isEmpty() ? 1 : tGraph.getNodes().size();

        /** find the root of the component */
        TNode root = null;
        Iterator<TNode> it = tGraph.getNodes().iterator();
        while (root == null && it.hasNext()) {
            TNode tNode = it.next();
            if (tNode.getProperty(Properties.ROOT)) {
                root = tNode;
            }
        }

        /** start with the root and level down by dsf */
        if (root != null) {
            setNeighbors(root.getChildren(), progressMonitor);
        }

        progressMonitor.done();

    }

    /**
     * Set the neighbors of each node in the current level and for their children. A neighbor is the
     * current node's nearest node, at the same level. A siblings is a neighbor with the same
     * parent.
     * 
     * @param currentLevel
     *            the list of TNode at the same level, for which the neighbors and siblings should
     *            be determined
     * @param progressMonitor
     *            the current progress monitor
     */
    private void setNeighbors(final Iterable<TNode> currentLevel, final IElkProgressMonitor progressMonitor) {
        /** only do something in filled levels */
        if (!Iterables.isEmpty(currentLevel)) {
            /** create subtask for recursive descent */
            IElkProgressMonitor sT = progressMonitor.subTask(Iterables.size(currentLevel) / numberOfNodes);

            sT.begin("Set neighbors in level", 1f);

            /** build empty iterator */
            Iterable<TNode> nextLevel = new Iterable<TNode>() {

                public Iterator<TNode> iterator() {
                    return Iterators.emptyIterator();
                }
            };

            TNode lN = null;

            /**
             * the left neighbor is the previous processed node the right neighbor of the left
             * neighbor is the current node
             */
            for (TNode cN : currentLevel) {
                /** append the children of the current node to the next level */
                nextLevel = Iterables.concat(nextLevel, cN.getChildren());
                if (lN != null) {
                    lN.setProperty(Properties.RIGHTNEIGHBOR, cN);
                    cN.setProperty(Properties.LEFTNEIGHBOR, lN);
                    if (cN.getParent() == lN.getParent()) {
                        lN.setProperty(Properties.RIGHTSIBLING, cN);
                        cN.setProperty(Properties.LEFTSIBLING, lN);
                    }
                }

                lN = cN;
            }

            /** add amount of work units to the whole task */
            sT.done();

            /** determine neighbors by bfs and for the whole graph */
            setNeighbors(nextLevel, progressMonitor);
        }

    }
}