    1   /*
    2    * Copyright 1999-2004 The Apache Software Foundation
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *     http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.jxpath.ri.model.container;
    17
    18  import java.util.Locale;
    19
    20  import org.apache.commons.jxpath.Container;
    21  import org.apache.commons.jxpath.ri.QName;
    22  import org.apache.commons.jxpath.ri.compiler.NodeTest;
    23  import org.apache.commons.jxpath.ri.model.NodeIterator;
    24  import org.apache.commons.jxpath.ri.model.NodePointer;
    25  import org.apache.commons.jxpath.util.ValueUtils;
    26
    27  /***
    28   * Transparent pointer to a Container. The getValue() method
    29   * returns the contents of the container, rather than the container
    30   * itself.
    31   *
    32   * @author Dmitri Plotnikov
    33   * @version $Revision: 1.13 $ $Date: 2004/04/04 22:06:36 $
    34   */
    35  public class ContainerPointer extends NodePointer {
    36      private Container container;
    37      private NodePointer valuePointer;
    38
    39      public ContainerPointer(Container container, Locale locale) {
    40          super(null, locale);
    41          this.container = container;
    42      }
    43
    44      public ContainerPointer(NodePointer parent, Container container) {
    45          super(parent);
    46          this.container = container;
    47      }
    48
    49      /***
    50       * This type of node is auxiliary.
    51       */
    52      public boolean isContainer() {
    53          return true;
    54      }
    55
    56      public QName getName() {
    57          return null;
    58      }
    59
    60      public Object getBaseValue() {
    61          return container;
    62      }
    63
    64      public boolean isCollection() {
    65          Object value = getBaseValue();
    66          return value != null && ValueUtils.isCollection(value);
    67      }
    68
    69      public int getLength() {
    70          Object value = getBaseValue();
    71          if (value == null) {
    72              return 1;
    73          }
    74          return ValueUtils.getLength(value);
    75      }
    76
    77      public boolean isLeaf() {
    78          return getValuePointer().isLeaf();
    79      }
    80
    81      public Object getImmediateNode() {
    82          Object value = getBaseValue();
    83          if (index != WHOLE_COLLECTION) {
    84              if (index >= 0 && index < getLength()) {
    85                  return ValueUtils.getValue(value, index);
    86              }
    87              else {
    88                  return null;
    89              }
    90          }
    91          else {
    92              return ValueUtils.getValue(value);
    93          }
    94      }
    95
    96      public void setValue(Object value) {
    97          // TODO: what if this is a collection?
    98          container.setValue(value);
    99      }
    100
    101     public NodePointer getImmediateValuePointer() {
    102         if (valuePointer == null) {
    103             Object value = getImmediateNode();
    104             valuePointer =
    105                 NodePointer.newChildNodePointer(this, getName(), value);
    106         }
    107         return valuePointer;
    108     }
    109
    110     public int hashCode() {
    111         return System.identityHashCode(container) + index;
    112     }
    113
    114     public boolean equals(Object object) {
    115         if (object == this) {
    116             return true;
    117         }
    118
    119         if (!(object instanceof ContainerPointer)) {
    120             return false;
    121         }
    122
    123         ContainerPointer other = (ContainerPointer) object;
    124         return container == other.container && index == other.index;
    125     }
    126
    127     public NodeIterator childIterator(
    128         NodeTest test,
    129         boolean reverse,
    130         NodePointer startWith)
    131     {
    132         return getValuePointer().childIterator(test, reverse, startWith);
    133     }
    134
    135     public NodeIterator attributeIterator(QName name) {
    136         return getValuePointer().attributeIterator(name);
    137     }
    138
    139     public NodeIterator namespaceIterator() {
    140         return getValuePointer().namespaceIterator();
    141     }
    142
    143     public NodePointer namespacePointer(String namespace) {
    144         return getValuePointer().namespacePointer(namespace);
    145     }
    146
    147     public boolean testNode(NodeTest nodeTest) {
    148         return getValuePointer().testNode(nodeTest);
    149     }
    150
    151     public int compareChildNodePointers(
    152         NodePointer pointer1,
    153         NodePointer pointer2)
    154     {
    155         return pointer1.getIndex() - pointer2.getIndex();
    156     }
    157
    158     public String getNamespaceURI(String prefix) {
    159         return getValuePointer().getNamespaceURI(prefix);
    160     }
    161
    162     public String asPath() {
    163         if (parent != null) {
    164             return parent.asPath();
    165         }
    166         return "/";
    167     }
    168  }