Home | History | Annotate | Download | only in dom
      1 /*
      2  * Copyright (C) 2007 Esmertec AG.
      3  * Copyright (C) 2007 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 package com.android.mms.dom;
     19 
     20 import java.util.ArrayList;
     21 
     22 import org.w3c.dom.Node;
     23 import org.w3c.dom.NodeList;
     24 
     25 public class NodeListImpl implements NodeList {
     26     private ArrayList<Node> mSearchNodes;
     27     private ArrayList<Node> mStaticNodes;
     28     private Node mRootNode;
     29     private String mTagName;
     30     private boolean mDeepSearch;
     31 
     32     /*
     33      * Internal Interface
     34      */
     35 
     36     /**
     37      * Constructs a NodeList by searching for all descendants or the direct
     38      * children of a root node with a given tag name.
     39      * @param rootNode The root <code>Node</code> of the search.
     40      * @param tagName The tag name to be searched for. If null, all descendants
     41      *              will be returned.
     42      * @param deep Limit the search to the direct children of rootNode if false,
     43      *              to all descendants otherwise.
     44      */
     45     public NodeListImpl(Node rootNode, String tagName, boolean deepSearch) {
     46         mRootNode = rootNode;
     47         mTagName  = tagName;
     48         mDeepSearch = deepSearch;
     49     }
     50 
     51     /**
     52      * Constructs a NodeList for a given static node list.
     53      * @param nodes The static node list.
     54      */
     55     public NodeListImpl(ArrayList<Node> nodes) {
     56         mStaticNodes = nodes;
     57     }
     58 
     59     /*
     60      * NodeListImpl Interface
     61      */
     62 
     63     public int getLength() {
     64         if (mStaticNodes == null) {
     65             fillList(mRootNode);
     66             return mSearchNodes.size();
     67         } else {
     68             return mStaticNodes.size();
     69         }
     70     }
     71 
     72     public Node item(int index) {
     73         Node node = null;
     74         if (mStaticNodes == null) {
     75             fillList(mRootNode);
     76             try {
     77                 node = mSearchNodes.get(index);
     78             } catch (IndexOutOfBoundsException e) {
     79                 // Do nothing and return null
     80             }
     81         } else {
     82             try {
     83                 node = mStaticNodes.get(index);
     84             } catch (IndexOutOfBoundsException e) {
     85                 // Do nothing and return null
     86             }
     87         }
     88         return node;
     89     }
     90 
     91     /**
     92      * A preorder traversal is done in the following order:
     93      * <ul>
     94      *   <li> Visit root.
     95      *   <li> Traverse children from left to right in preorder.
     96      * </ul>
     97      * This method fills the live node list.
     98      * @param The root of preorder traversal
     99      * @return The next match
    100      */
    101     private void fillList(Node node) {
    102         // (Re)-initialize the container if this is the start of the search.
    103         // Visit the root of this iteration otherwise.
    104         if (node == mRootNode) {
    105             mSearchNodes = new ArrayList<Node>();
    106         } else {
    107             if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
    108                 mSearchNodes.add(node);
    109             }
    110         }
    111 
    112         // Descend one generation...
    113         node = node.getFirstChild();
    114 
    115         // ...and visit in preorder the children if we are in deep search
    116         // or directly add the children to the list otherwise.
    117         while (node != null) {
    118             if (mDeepSearch) {
    119                 fillList(node);
    120             } else {
    121                 if ((mTagName == null) || node.getNodeName().equals(mTagName)) {
    122                     mSearchNodes.add(node);
    123                 }
    124             }
    125             node = node.getNextSibling();
    126         }
    127     }
    128 }
    129