/* ******************************************************************************
* Copyright (c) 2006-2016 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
/**
*
*/
package org.xmind.core.util;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
import java.util.Stack;
import org.xmind.core.ITopic;
/**
* @author Frank Shaka
* @since 3.6.50
*/
public class TopicIterator implements Iterator<ITopic> {
private static class TopicWrapper {
public final ITopic topic;
/**
*
*/
public TopicWrapper(ITopic topic) {
this.topic = topic;
}
}
public static final int NONE = 0;
public static final int REVERSED = 1 << 0;
private int options;
private ITopic next;
private Stack<Object> stack;
public TopicIterator(ITopic root) {
this(root, NONE);
}
/**
*
*/
public TopicIterator(ITopic root, int options) {
this.options = options;
this.stack = new Stack<Object>();
this.stack.push(root);
this.next = findNext();
}
private static void pushFIFO(Stack<Object> stack, List<ITopic> topics) {
ListIterator<ITopic> it = topics.listIterator(topics.size());
while (it.hasPrevious()) {
stack.push(it.previous());
}
}
private static void pushLIFOStack(Stack<Object> stack,
List<ITopic> topics) {
for (ITopic topic : topics) {
stack.push(topic);
}
}
private ITopic findNext() {
if (stack.isEmpty())
return null;
Object o = stack.pop();
if (hasOption(REVERSED)) {
if (o instanceof TopicWrapper)
return ((TopicWrapper) o).topic;
ITopic t = (ITopic) o;
stack.push(new TopicWrapper(t));
pushLIFOStack(stack, t.getAllChildren());
return findNext();
} else {
ITopic t = (ITopic) o;
pushFIFO(stack, t.getAllChildren());
return t;
}
}
private boolean hasOption(int option) {
return (options & option) != 0;
}
/*
* (non-Javadoc)
*
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return next != null;
}
/*
* (non-Javadoc)
*
* @see java.util.Iterator#next()
*/
public ITopic next() {
ITopic t = next;
if (t == null)
throw new NoSuchElementException();
next = findNext();
return t;
}
/*
* (non-Javadoc)
*
* @see java.util.Iterator#remove()
*/
public void remove() {
/// ignore remove operations
}
}