/*
* Copyright 2007, Plutext Pty Ltd.
*
* This file is part of Docx4all.
Docx4all is free software: you can redistribute it and/or modify
it under the terms of version 3 of the GNU General Public License
as published by the Free Software Foundation.
Docx4all is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Docx4all. If not, see <http://www.gnu.org/licenses/>.
*/
package org.docx4all.xml;
import java.util.Stack;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author Jojada Tirtowidjojo - 30/11/2007
*/
public class ElementMLIterator {
private static Logger log = LoggerFactory.getLogger(ElementMLIterator.class);
private final ElementML root;
private Stack<StackEntry> stack;
public ElementMLIterator(ElementML root) throws IllegalArgumentException {
if (root == null) {
throw new IllegalArgumentException("Root is NULL");
}
this.root = root;
}
public boolean hasNext() {
boolean hasNext = false;
if (stack == null) {
hasNext = true;
} else if (stack.isEmpty()) {
;//false
} else {
for (int i=stack.size()-1; 0 <= i && !hasNext; i--) {
StackEntry se = stack.elementAt(i);
hasNext = se.hasNext();
}
}
return hasNext;
}
public ElementML next() {
if (stack == null) {
stack = new Stack<StackEntry>();
stack.push(new StackEntry(root));
return root;
}
if (stack.isEmpty()) {
return null;
}
ElementML theElem = null;
StackEntry se = stack.peek();
if (se.hasNext()) {
theElem = se.next();
stack.push(new StackEntry(theElem));
} else {
stack.pop();
theElem = next();
}
return theElem;
}
public void cruise(Callback callback) {
if (stack == null) {
stack = new Stack<StackEntry>();
stack.push(new StackEntry(root));
callback.handleStartElement(root);
cruise(callback);
} else if (!stack.isEmpty()) {
StackEntry se = stack.peek();
if (se.hasNext()) {
ElementML elem = se.next();
stack.push(new StackEntry(elem));
callback.handleStartElement(elem);
} else {
stack.pop();
callback.handleEndElement(se.elem);
}
cruise(callback);
}
}
public static class Callback {
public void handleStartElement(ElementML elem) {
;//method template
}
public void handleEndElement(ElementML elem) {
;//method template
}
}// Callback inner class
private final class StackEntry {
private ElementML elem;
private int childIdx;
private StackEntry(ElementML elem) {
this.elem = elem;
this.childIdx = -1;
}
private boolean hasNext() {
return (childIdx + 1) < elem.getChildrenCount();
}
private ElementML next() {
return elem.getChild(++childIdx);
}
}// StackEntry inner class
}// ElementMLIterator class