blob: 4df651ae82f6c4b4d151bf4f340780cd4064be57 [file] [log] [blame]
/*
* Copyright (C) 2007 Esmertec AG.
* Copyright (C) 2007 The Android Open Source Project
*
* 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 com.android.mms.dom;
import java.util.ArrayList;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class NodeListImpl implements NodeList {
private ArrayList<Node> mSearchNodes;
private ArrayList<Node> mStaticNodes;
private Node mRootNode;
private String mTagName;
private boolean mDeepSearch;
/*
* Internal Interface
*/
/**
* Constructs a NodeList by searching for all descendants or the direct
* children of a root node with a given tag name.
* @param rootNode The root <code>Node</code> of the search.
* @param tagName The tag name to be searched for. If null, all descendants
* will be returned.
* @param deep Limit the search to the direct children of rootNode if false,
* to all descendants otherwise.
*/
public NodeListImpl(Node rootNode, String tagName, boolean deepSearch) {
mRootNode = rootNode;
mTagName = tagName;
mDeepSearch = deepSearch;
}
/**
* Constructs a NodeList for a given static node list.
* @param nodes The static node list.
*/
public NodeListImpl(ArrayList<Node> nodes) {
mStaticNodes = nodes;
}
/*
* NodeListImpl Interface
*/
public int getLength() {
if (mStaticNodes == null) {
fillList(mRootNode);
return mSearchNodes.size();
} else {
return mStaticNodes.size();
}
}
public Node item(int index) {
Node node = null;
if (mStaticNodes == null) {
fillList(mRootNode);
try {
node = mSearchNodes.get(index);
} catch (IndexOutOfBoundsException e) {
// Do nothing and return null
}
} else {
try {
node = mStaticNodes.get(index);
} catch (IndexOutOfBoundsException e) {
// Do nothing and return null
}
}
return node;
}
/**
* A preorder traversal is done in the following order:
* <ul>
* <li> Visit root.
* <li> Traverse children from left to right in preorder.
* </ul>
* This method fills the live node list.
* @param The root of preorder traversal
* @return The next match
*/
private void fillList(Node node) {
// (Re)-initialize the container if this is the start of the search.
// Visit the root of this iteration otherwise.
if (node == mRootNode) {
mSearchNodes = new ArrayList<Node>();
} else {
if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
mSearchNodes.add(node);
}
}
// Descend one generation...
node = node.getFirstChild();
// ...and visit in preorder the children if we are in deep search
// or directly add the children to the list otherwise.
while (node != null) {
if (mDeepSearch) {
fillList(node);
} else {
if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
mSearchNodes.add(node);
}
}
node = node.getNextSibling();
}
}
}