View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  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  package org.apache.commons.configuration.tree.xpath;
    18
    19  import java.util.ArrayList;
    20  import java.util.Collections;
    21  import java.util.Iterator;
    22  import java.util.List;
    23
    24  import org.apache.commons.configuration.tree.ConfigurationNode;
    25  import org.apache.commons.jxpath.ri.Compiler;
    26  import org.apache.commons.jxpath.ri.QName;
    27  import org.apache.commons.jxpath.ri.compiler.NodeNameTest;
    28  import org.apache.commons.jxpath.ri.compiler.NodeTest;
    29  import org.apache.commons.jxpath.ri.compiler.NodeTypeTest;
    30  import org.apache.commons.jxpath.ri.model.NodePointer;
    31  import org.apache.commons.lang.StringUtils;
    32
    33  /***
    34   * A specialized iterator implementation for the child nodes of a configuration
    35   * node.
    36   *
    37   * @since 1.3
    38   * @author Oliver Heger
    39   * @version $Id: ConfigurationNodeIteratorChildren.java 439648 2006-09-02 20:42:10Z oheger $
    40   */
    41  class ConfigurationNodeIteratorChildren extends ConfigurationNodeIteratorBase
    42  {
    43      /***
    44       * Creates a new instance of <code>ConfigurationNodeIteratorChildren</code>
    45       * and initializes it.
    46       *
    47       * @param parent the parent pointer
    48       * @param nodeTest the test selecting the sub nodes
    49       * @param reverse the reverse flag
    50       * @param startsWith the first element of the iteration
    51       */
    52      public ConfigurationNodeIteratorChildren(NodePointer parent,
    53              NodeTest nodeTest, boolean reverse, NodePointer startsWith)
    54      {
    55          super(parent, reverse);
    56          ConfigurationNode root = (ConfigurationNode) parent.getNode();
    57          List childNodes = createSubNodeList(root, nodeTest);
    58          initSubNodeList(childNodes);
    59          if (startsWith != null)
    60          {
    61              setStartOffset(findStartIndex(root,
    62                      (ConfigurationNode) startsWith.getNode()));
    63          }
    64      }
    65
    66      /***
    67       * Creates the list with sub nodes. This method gets called during
    68       * initialization phase. It finds out, based on the given test, which nodes
    69       * must be iterated over.
    70       *
    71       * @param node the current node
    72       * @param test the test object
    73       * @return a list with the matching nodes
    74       */
    75      protected List createSubNodeList(ConfigurationNode node, NodeTest test)
    76      {
    77          List children = node.getChildren();
    78
    79          if (test == null)
    80          {
    81              return children;
    82          }
    83          else
    84          {
    85              if (test instanceof NodeNameTest)
    86              {
    87                  NodeNameTest nameTest = (NodeNameTest) test;
    88                  QName name = nameTest.getNodeName();
    89                  if (name.getPrefix() == null)
    90                  {
    91                      if (nameTest.isWildcard())
    92                      {
    93                          return children;
    94                      }
    95
    96                      List result = new ArrayList();
    97                      for (Iterator it = children.iterator(); it.hasNext();)
    98                      {
    99                          ConfigurationNode child = (ConfigurationNode) it.next();
    100                         if (StringUtils.equals(name.getName(), child.getName()))
    101                         {
    102                             result.add(child);
    103                         }
    104                     }
    105                     return result;
    106                 }
    107             }
    108
    109             else if (test instanceof NodeTypeTest)
    110             {
    111                 NodeTypeTest typeTest = (NodeTypeTest) test;
    112                 if (typeTest.getNodeType() == Compiler.NODE_TYPE_NODE
    113                         || typeTest.getNodeType() == Compiler.NODE_TYPE_TEXT)
    114                 {
    115                     return children;
    116                 }
    117             }
    118         }
    119
    120         return Collections.EMPTY_LIST;
    121     }
    122
    123     /***
    124      * Determines the start position of the iteration. Finds the index of the
    125      * given start node in the children of the root node.
    126      *
    127      * @param node the root node
    128      * @param startNode the start node
    129      * @return the start node's index
    130      */
    131     protected int findStartIndex(ConfigurationNode node,
    132             ConfigurationNode startNode)
    133     {
    134         for (int index = 0; index < node.getChildrenCount(); index++)
    135         {
    136             if (node.getChild(index) == startNode)
    137             {
    138                 return index;
    139             }
    140         }
    141
    142         return -1;
    143     }
    144 }