001 /*
002 * This file is part of the Echo Point Project. This project is a
003 * collection of Components that have extended the Echo Web Application
004 * Framework Version 3.
005 *
006 * Version: MPL 1.1
007 *
008 * The contents of this file are subject to the Mozilla Public License Version
009 * 1.1 (the "License"); you may not use this file except in compliance with
010 * the License. You may obtain a copy of the License at
011 * http://www.mozilla.org/MPL/
012 *
013 * Software distributed under the License is distributed on an "AS IS" basis,
014 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
015 * for the specific language governing rights and limitations under the
016 * License.
017 */
018
019 package echopoint.tree;
020
021 import java.util.Enumeration;
022 import java.util.Stack;
023 import java.util.EmptyStackException;
024 import java.util.NoSuchElementException;
025 import java.io.Serializable;
026
027 /**
028 * An enumeration that follows the path from {@code ancestor} to the node.
029 * The enumeration's {@code nextElement()} method first returns
030 * {@code ancestor}, then the child of {@code ancestor} that is an ancestor
031 * of the node, and so on, and finally returns this node. Creation of the
032 * enumeration is O(m) where m is the number of nodes between this node and
033 * {@code ancestor}, inclusive. Each {@code nextElement()} message is O(1).
034 *
035 * @author Brad Baker, Rakesh Vidyadharan 2009-05-29
036 * @version $Id: PathBetweenNodesEnumeration.java 213 2009-06-03 16:34:13Z sptrakesh $
037 * @since 3.0.0b3
038 */
039 public final class PathBetweenNodesEnumeration
040 implements Enumeration<TreeNode>, Serializable
041 {
042 private static final long serialVersionUID = 1l;
043
044 protected Stack<TreeNode> stack = new Stack<TreeNode>();
045
046 /**
047 * Create a new enumeration from the specified ancestor the destination.
048 *
049 * @param ancestor The start of the enumeration.
050 * @param descendant The destination of the enumeration.
051 */
052 public PathBetweenNodesEnumeration( final TreeNode ancestor,
053 final TreeNode descendant )
054 {
055 if ( ancestor == null || descendant == null )
056 {
057 throw new IllegalArgumentException( "argument is null" );
058 }
059
060 stack.push( descendant );
061 TreeNode current = descendant;
062
063 while ( current != ancestor )
064 {
065 current = current.getParent();
066
067 if ( current == null && ( descendant != ancestor ) )
068 {
069 throw new IllegalArgumentException( "node " + ancestor
070 + " is not an ancestor of " + descendant );
071 }
072
073 stack.push( current );
074 }
075 }
076
077 /** {@inheritDoc} */
078 public boolean hasMoreElements()
079 {
080 return stack.size() > 0;
081 }
082
083 /** {@inheritDoc} */
084 public TreeNode nextElement()
085 {
086 try
087 {
088 return stack.pop();
089 }
090 catch ( final EmptyStackException e )
091 {
092 throw new NoSuchElementException( "No more elements" );
093 }
094 }
095 }