All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.conqat.lib.commons.visitor.VisitorUtils Maven / Gradle / Ivy

There is a newer version: 2024.7.2
Show newest version
/*
 * Copyright (c) CQSE GmbH
 *
 * Licensed 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.conqat.lib.commons.visitor;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.List;

import org.conqat.lib.commons.collections.CollectionUtils;
import org.conqat.lib.commons.collections.IdentityHashSet;
import org.conqat.lib.commons.error.NeverThrownRuntimeException;

/**
 * Utility class for working with visitors.
 */
public class VisitorUtils {

	/**
	 * Visits all nodes of a tree in pre-order, i.e. a node is visited directly before its children.
	 * 
	 * @param root
	 *            the root of the tree.
	 * @param walker
	 *            the walker user for traversing the tree.
	 * @param visitor
	 *            the visitor used for visiting the nodes.
	 */
	public static  void visitAllPreOrder(T root,
			ITreeWalker walker, IVisitor visitor) throws X1, X2 {
		visitor.visit(root);
		for (T child : walker.getChildren(root)) {
			visitAllPreOrder(child, walker, visitor);
		}
	}

	/**
	 * Visits all leaves of a tree, i.e. those nodes without children.
	 * 
	 * @param root
	 *            the root of the tree.
	 * @param walker
	 *            the walker user for traversing the tree.
	 * @param visitor
	 *            the visitor used for visiting the nodes.
	 */
	public static  void visitLeaves(T root, ITreeWalker walker,
			IVisitor visitor) throws X1, X2 {
		Collection children = walker.getChildren(root);
		if (children.isEmpty()) {
			visitor.visit(root);
		} else {
			for (T child : children) {
				visitLeaves(child, walker, visitor);
			}
		}
	}

	/**
	 * Visits all elements of a mesh in depth first order. It is made sure, that each reachable element
	 * is visited exactly once, where we use equality of references to determine elements that were seen
	 * before.
	 * 
	 * Does not use recursive function calls to enable listing large graphs.
	 * 
	 * @param start
	 *            the element to start the traversal from.
	 * @param walker
	 *            the walker user for traversing the mesh.
	 * @param visitor
	 *            the visitor used for visiting the elements.
	 */
	public static  void visitAllDepthFirst(T start,
			IMeshWalker walker, IVisitor visitor) throws X1, X2 {
		IdentityHashSet visitedNodes = new IdentityHashSet<>();
		Deque todoNodes = new ArrayDeque<>();
		todoNodes.addFirst(start);
		while (!todoNodes.isEmpty()) {
			T current = todoNodes.removeFirst();
			if (visitedNodes.contains(current)) {
				continue;
			}
			visitor.visit(current);
			visitedNodes.add(current);
			for (T succ : CollectionUtils.reverse(walker.getAdjacentElements(current))) {
				if (!visitedNodes.contains(succ)) {
					todoNodes.addFirst(succ);
				}
			}
		}
	}

	/**
	 * Lists all elements of a mesh in depth first order. It is made sure, that each reachable element
	 * is visited exactly once, where we use equality of references to determine elements that were seen
	 * before.
	 * 
	 * @param start
	 *            the element to start the traversal from.
	 * @param walker
	 *            the walker user for traversing the mesh.
	 */
	public static  List listAllDepthFirst(T start, IMeshWalker walker) throws X {
		final List list = new ArrayList<>();
		visitAllDepthFirst(start, walker, new IVisitor() {

			@Override
			public void visit(T element) throws NeverThrownRuntimeException {
				list.add(element);
			}
		});
		return list;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy