/* * Copyright 2004 The Apache Software Foundation. * * 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.apache.myfaces.util; import javax.faces.component.UIComponent; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Stack; /** * Iterates over a view structure, i.e. a component tree, in a * depth first manner. * * @author Manfred Geiler (latest modification by $Author$) * @version $Revision$ $Date$ */ public class ViewIterator implements Iterator { //private static final Log log = LogFactory.getLog(ViewIterator.class); private UIComponent _next = null; private boolean _mayHaveNext = true; private UIComponent _current = null; private Stack _stack = new Stack(); /** * @param root the root of the view structure to iterate over */ public ViewIterator(UIComponent root) { _next = root; _current = null; } public boolean hasNext() { return getNext() != null; } /** * @return the next component in the view. The first element is always the given root * component. */ public Object next() { if (!hasNext()) { throw new NoSuchElementException(); } _current = _next; _next = null; return _current; } private UIComponent getNext() { if (_next == null && _mayHaveNext) { //has child? Iterator children = _current.getFacetsAndChildren(); if (children.hasNext()) { _next = (UIComponent)children.next(); //push siblings _stack.push(children); } else { //has next sibling? for (;;) { if (_stack.empty()) { _next = null; _mayHaveNext = false; break; } Iterator currentSiblings = (Iterator)_stack.peek(); if (currentSiblings.hasNext()) { _next = (UIComponent)currentSiblings.next(); break; } else { _stack.pop(); } } } } return _next; } public void remove() { throw new UnsupportedOperationException(this.getClass().getName() + " UnsupportedOperationException"); } }