/* | |
* Copyright 2004,2005 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.axiom.om.impl.llom; | |
import org.apache.axiom.om.OMContainer; | |
import org.apache.axiom.om.OMElement; | |
import org.apache.axiom.om.OMNode; | |
/** | |
* Refer to the testClass to find out how to use | |
* features like isNavigable, isComplete and step. | |
*/ | |
public class OMNavigator { | |
/** | |
* Field node | |
*/ | |
protected OMNode node; | |
/** | |
* Field visited | |
*/ | |
private boolean visited; | |
/** | |
* Field next | |
*/ | |
private OMNode next; | |
// root is the starting element. Once the navigator comes back to the | |
// root, the traversal is terminated | |
/** | |
* Field root | |
*/ | |
private OMNode root; | |
/** | |
* Field backtracked | |
*/ | |
private boolean backtracked; | |
// flags that tell the status of the navigator | |
/** | |
* Field end | |
*/ | |
private boolean end = false; | |
/** | |
* Field start | |
*/ | |
private boolean start = true; | |
/** | |
* Constructor OMNavigator. | |
*/ | |
public OMNavigator() { | |
} | |
/** | |
* Constructor OMNavigator. | |
* | |
* @param node | |
*/ | |
public OMNavigator(OMNode node) { | |
init(node); | |
} | |
/** | |
* Method init. | |
* | |
* @param node | |
*/ | |
public void init(OMNode node) { | |
next = node; | |
root = node; | |
backtracked = false; | |
} | |
/** | |
* Gets the next node. | |
* | |
* @return Returns OMnode in the sequence of preorder traversal. Note however | |
* that an element node is treated slightly differently. Once the | |
* element is passed it returns the same element in the next encounter as well. | |
*/ | |
public OMNode next() { | |
if (next == null) { | |
return null; | |
} | |
node = next; | |
visited = backtracked; | |
backtracked = false; | |
updateNextNode(); | |
// set the starting and ending flags | |
if (root.equals(node)) { | |
if (!start) { | |
end = true; | |
} else { | |
start = false; | |
} | |
} | |
return node; | |
} | |
/** | |
* Private method to encapsulate the searching logic. | |
*/ | |
private void updateNextNode() { | |
if ((next instanceof OMElement) && !visited) { | |
OMElementImpl e = (OMElementImpl) next; | |
if (e.firstChild != null) { | |
next = e.firstChild; | |
} else if (e.isComplete()) { | |
backtracked = true; | |
} else { | |
next = null; | |
} | |
} else { | |
OMNode nextSibling = ((OMNodeImpl) next).nextSibling; | |
//OMNode parent = next.getParent(); | |
OMContainer parent = next.getParent(); | |
if (nextSibling != null) { | |
next = nextSibling; | |
} else if ((parent != null) && parent.isComplete()) { | |
next = (OMNodeImpl) parent; | |
backtracked = true; | |
} else { | |
next = null; | |
} | |
} | |
} | |
/** | |
* Method visited. | |
* | |
* @return Returns boolean. | |
*/ | |
public boolean visited() { | |
return visited; | |
} | |
/** | |
* This is a very special method. This allows the navigator to step | |
* once it has reached the existing OM. At this point the isNavigable | |
* method will return false but the isComplete method may return false | |
* which means that the navigating the given element is not complete and | |
* the navigator cannot proceed. | |
*/ | |
public void step() { | |
if (!end) { | |
next = node; | |
updateNextNode(); | |
} | |
} | |
/** | |
* Returns the navigable status. | |
* | |
* @return Returns boolean. | |
*/ | |
public boolean isNavigable() { | |
if (end) { | |
return false; | |
} else { | |
return !(next == null); | |
} | |
} | |
/** | |
* Returns the completed status. | |
* | |
* @return Returns boolean. | |
*/ | |
public boolean isCompleted() { | |
return end; | |
} | |
} |