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.List;
    20
    21  import org.apache.commons.configuration.tree.ConfigurationNode;
    22  import org.apache.commons.jxpath.ri.model.NodeIterator;
    23  import org.apache.commons.jxpath.ri.model.NodePointer;
    24
    25  /***
    26   * <p>
    27   * A base class for implementing iterators over configuration nodes.
    28   * </p>
    29   * <p>
    30   * This class already provides common functionality for implementing the
    31   * iteration process. Derived classes will implement specific behavior based on
    32   * the concrete node type (child node or attribute node).
    33   * </p>
    34   *
    35   * @since 1.3
    36   * @author Oliver Heger
    37   * @version $Id: ConfigurationNodeIteratorBase.java 439648 2006-09-02 20:42:10Z oheger $
    38   */
    39  abstract class ConfigurationNodeIteratorBase implements NodeIterator
    40  {
    41      /*** Stores the parent node pointer. */
    42      private NodePointer parent;
    43
    44      /*** Stores the list with the sub nodes. */
    45      private List subNodes;
    46
    47      /*** Stores the current position. */
    48      private int position;
    49
    50      /*** Stores the start offset of the iterator. */
    51      private int startOffset;
    52
    53      /*** Stores the reverse flag. */
    54      private boolean reverse;
    55
    56      /***
    57       * Creates a new instance of <code>ConfigurationNodeIteratorBase</code>
    58       * and initializes it.
    59       *
    60       * @param parent the parent pointer
    61       * @param reverse the reverse flag
    62       */
    63      protected ConfigurationNodeIteratorBase(NodePointer parent, boolean reverse)
    64      {
    65          this.parent = parent;
    66          this.reverse = reverse;
    67      }
    68
    69      /***
    70       * Returns the position of the iteration.
    71       *
    72       * @return the position
    73       */
    74      public int getPosition()
    75      {
    76          return position;
    77      }
    78
    79      /***
    80       * Sets the position of the iteration.
    81       *
    82       * @param pos the new position
    83       * @return a flag if this is a valid position
    84       */
    85      public boolean setPosition(int pos)
    86      {
    87          position = pos;
    88          return pos >= 1 && pos <= getMaxPosition();
    89      }
    90
    91      /***
    92       * Returns the current node pointer.
    93       *
    94       * @return the current pointer in this iteration
    95       */
    96      public NodePointer getNodePointer()
    97      {
    98          if (getPosition() < 1 && !setPosition(1))
    99          {
    100             return null;
    101         }
    102
    103         return createNodePointer((ConfigurationNode) subNodes
    104                 .get(positionToIndex(getPosition())));
    105     }
    106
    107     /***
    108      * Returns the parent node pointer.
    109      *
    110      * @return the parent node pointer
    111      */
    112     protected NodePointer getParent()
    113     {
    114         return parent;
    115     }
    116
    117     /***
    118      * Returns the start offset of the iteration.
    119      *
    120      * @return the start offset
    121      */
    122     protected int getStartOffset()
    123     {
    124         return startOffset;
    125     }
    126
    127     /***
    128      * Sets the start offset of the iteration. This is used when a start element
    129      * was set.
    130      *
    131      * @param startOffset the start offset
    132      */
    133     protected void setStartOffset(int startOffset)
    134     {
    135         this.startOffset = startOffset;
    136         if (reverse)
    137         {
    138             this.startOffset--;
    139         }
    140         else
    141         {
    142             this.startOffset++;
    143         }
    144     }
    145
    146     /***
    147      * Initializes the list of sub nodes for the iteration. This method must be
    148      * called during initialization phase.
    149      *
    150      * @param nodes the list with the sub nodes
    151      */
    152     protected void initSubNodeList(List nodes)
    153     {
    154         subNodes = nodes;
    155         if (reverse)
    156         {
    157             setStartOffset(subNodes.size());
    158         }
    159     }
    160
    161     /***
    162      * Returns the maximum position for this iterator.
    163      *
    164      * @return the maximum allowed position
    165      */
    166     protected int getMaxPosition()
    167     {
    168         return reverse ? getStartOffset() + 1 : subNodes.size()
    169                 - getStartOffset();
    170     }
    171
    172     /***
    173      * Creates the configuration node pointer for the current position. This
    174      * method is called by <code>getNodePointer()</code>. Derived classes
    175      * must create the correct pointer object.
    176      *
    177      * @param node the current configuration node
    178      * @return the node pointer
    179      */
    180     protected NodePointer createNodePointer(ConfigurationNode node)
    181     {
    182         return new ConfigurationNodePointer(getParent(), node);
    183     }
    184
    185     /***
    186      * Returns the index in the data list for the given position. This method
    187      * also checks the reverse flag.
    188      *
    189      * @param pos the position (1-based)
    190      * @return the corresponding list index
    191      */
    192     protected int positionToIndex(int pos)
    193     {
    194         return (reverse ? 1 - pos : pos - 1) + getStartOffset();
    195     }
    196 }