in mixins/core-mixins/src/main/java/org/apache/axiom/core/impl/TreeWalkerImpl.java [107:293]
public boolean proceed() throws StreamException {
if (incremental && !handler.drain()) {
return false;
}
try {
// Determine the next node (i.e. the node for which the next event is generated) and
// update the state
final CoreNode previousNode = node;
final CoreNode nextNode;
if (state == STATE_PASS_THROUGH || state == STATE_STREAMING) {
nextNode = previousNode;
} else if (previousNode == null) {
if (state == STATE_NONE && !(root instanceof CoreDocument)) {
nextNode = null;
state = STATE_START_FRAGMENT;
} else {
nextNode = root;
state = STATE_NOT_VISITED;
}
} else if (state == STATE_VISITED && previousNode == root) {
nextNode = null;
} else if (state == STATE_NOT_VISITED && previousNode instanceof CoreElement) {
final CoreElement element = (CoreElement) previousNode;
// TODO: handle case with preserve == false
CoreAttribute firstAttribute = element.coreGetFirstAttribute();
if (firstAttribute == null) {
nextNode = element;
state = STATE_ATTRIBUTES_VISITED;
} else {
nextNode = firstAttribute;
state = STATE_NOT_VISITED;
}
} else if (state == STATE_NOT_VISITED || state == STATE_ATTRIBUTES_VISITED) {
final CoreParentNode parent = (CoreParentNode) previousNode;
int nodeState = parent.getState();
if (nodeState == CoreParentNode.COMPACT) {
nextNode = previousNode;
state = STATE_CONTENT_VISITED;
} else if (preserve || nodeState == CoreParentNode.COMPLETE) {
CoreChildNode child = parent.coreGetFirstChild();
if (child == null) {
nextNode = parent;
state = STATE_VISITED;
} else {
nextNode = child;
state = STATE_NOT_VISITED;
}
} else {
CoreChildNode child = parent.coreGetFirstChildIfAvailable();
if (child == null) {
nextNode = parent;
if (nodeState == CoreParentNode.DISCARDING
|| nodeState == CoreParentNode.DISCARDED) {
throw new NodeConsumedException();
}
parent.coreGetInputContext().setPassThroughHandler(handler);
state = STATE_PASS_THROUGH;
} else {
nextNode = child;
state = STATE_NOT_VISITED;
}
}
} else if (state == STATE_CONTENT_VISITED) {
nextNode = previousNode;
state = STATE_VISITED;
} else if (previousNode instanceof CoreChildNode) {
final CoreChildNode previousChildNode = (CoreChildNode) previousNode;
if (preserve) {
CoreChildNode sibling = previousChildNode.coreGetNextSibling();
if (sibling == null) {
nextNode = previousChildNode.coreGetParent();
state = STATE_VISITED;
} else {
nextNode = sibling;
state = STATE_NOT_VISITED;
}
} else {
CoreChildNode sibling = previousChildNode.coreGetNextSiblingIfAvailable();
if (sibling == null) {
CoreParentNode parent = previousChildNode.coreGetParent();
nextNode = parent;
int nodeState = parent.getState();
// TODO: <hack>
if (nodeState == CoreParentNode.INCOMPLETE
&& parent.coreGetInputContext() == null) {
nodeState = CoreParentNode.COMPLETE;
}
// </hack>
if (nodeState == CoreParentNode.COMPLETE) {
state = STATE_VISITED;
} else if (nodeState == CoreParentNode.DISCARDING
|| nodeState == CoreParentNode.DISCARDED) {
throw new NodeConsumedException();
} else {
parent.coreGetInputContext().setPassThroughHandler(handler);
state = STATE_PASS_THROUGH;
}
} else {
nextNode = sibling;
state = STATE_NOT_VISITED;
}
}
} else {
final CoreAttribute attribute = (CoreAttribute) previousNode;
// TODO: handle case with preserve == false
CoreAttribute nextAttribute = attribute.coreGetNextAttribute();
if (nextAttribute == null) {
nextNode = attribute.coreGetOwnerElement();
state = STATE_ATTRIBUTES_VISITED;
} else {
nextNode = nextAttribute;
state = STATE_NOT_VISITED;
}
}
// More closely examine the case where we move to a node that has not
// been visited yet. It may be a sourced element or a leaf node
if (state == STATE_NOT_VISITED) {
if (nextNode instanceof CoreNSAwareElement) {
XmlInput input =
((CoreNSAwareElement) nextNode).getXmlInput(preserve, incremental);
if (input != null) {
reader =
input.createReader(
new DocumentElementExtractingFilterHandler(handler));
state = STATE_STREAMING;
}
} else if (nextNode instanceof CoreLeafNode) {
state = STATE_LEAF;
} else if (nextNode instanceof CoreAttribute) {
state = STATE_ATTRIBUTE;
}
}
switch (state) {
case STATE_START_FRAGMENT:
handler.startFragment();
break;
case STATE_LEAF:
((CoreLeafNode) nextNode).internalSerialize(handler, preserve);
break;
case STATE_ATTRIBUTE:
((CoreAttribute) nextNode).internalSerialize(handler, preserve);
break;
case STATE_NOT_VISITED:
((CoreParentNode) nextNode).serializeStartEvent(handler);
break;
case STATE_ATTRIBUTES_VISITED:
handler.attributesCompleted();
break;
case STATE_VISITED:
if (nextNode == null) {
handler.completed();
} else {
((CoreParentNode) nextNode).serializeEndEvent(handler);
}
break;
case STATE_PASS_THROUGH:
{
CoreParentNode parent = (CoreParentNode) nextNode;
parent.coreGetInputContext().getBuilder().next();
if (parent.coreGetInputContext() == null) {
state = STATE_VISITED;
}
break;
}
case STATE_STREAMING:
if (reader.proceed()) {
state = STATE_VISITED;
reader = null;
}
break;
case STATE_CONTENT_VISITED:
handler.processCharacterData(
((CoreParentNode) nextNode).internalGetContent(), false);
break;
default:
throw new IllegalStateException();
}
node = nextNode;
return state == STATE_VISITED && (nextNode == null || nextNode instanceof CoreDocument);
} catch (CoreModelException ex) {
throw new CoreModelStreamException(ex);
}
}