    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.beans;
    17
    18  import org.apache.commons.jxpath.JXPathContext;
    19  import org.apache.commons.jxpath.ri.QName;
    20  import org.apache.commons.jxpath.ri.model.NodePointer;
    21
    22  /***
    23   * Used when there is a need to construct a Pointer for a collection element
    24   * that does not exist.  For example, if the path is "foo[3]", but the
    25   * collection "foo" only has one element or is empty or is null, the
    26   * NullElementPointer can be used to capture this situation without putting a
    27   * regular NodePointer into an invalid state.  Just create a NullElementPointer
    28   * with index 2 (= 3 - 1) and a "foo" pointer as the parent.
    29   *
    30   * @author Dmitri Plotnikov
    31   * @version $Revision: 1.17 $ $Date: 2004/03/25 03:49:50 $
    32   */
    33  public class NullElementPointer extends CollectionPointer {
    34
    35      public NullElementPointer(NodePointer parent, int index) {
    36          super(parent, (Object) null);
    37          this.index = index;
    38      }
    39
    40      public QName getName() {
    41          return null;
    42      }
    43
    44      public Object getBaseValue() {
    45          return null;
    46      }
    47
    48      public Object getImmediateNode() {
    49          return null;
    50      }
    51
    52      public boolean isLeaf() {
    53          return true;
    54      }
    55
    56      public boolean isCollection() {
    57          return false;
    58      }
    59
    60      public PropertyPointer getPropertyPointer() {
    61          return new NullPropertyPointer(this);
    62      }
    63
    64      public NodePointer getValuePointer() {
    65          return new NullPointer(this, getName());
    66      }
    67
    68      public void setValue(Object value) {
    69          throw new UnsupportedOperationException(
    70              "Collection element does not exist: " + this);
    71      }
    72
    73      public boolean isActual() {
    74          return false;
    75      }
    76
    77      public boolean isContainer() {
    78          return true;
    79      }
    80
    81      public NodePointer createPath(JXPathContext context) {
    82          return parent.createChild(context, null, index);
    83      }
    84
    85      public NodePointer createPath(JXPathContext context, Object value) {
    86          return parent.createChild(context, null, index, value);
    87      }
    88
    89      public int hashCode() {
    90          return getImmediateParentPointer().hashCode() + index;
    91      }
    92
    93      public boolean equals(Object object) {
    94          if (object == this) {
    95              return true;
    96          }
    97
    98          if (!(object instanceof NullElementPointer)) {
    99              return false;
    100         }
    101
    102         NullElementPointer other = (NullElementPointer) object;
    103         return getImmediateParentPointer() == other.getImmediateParentPointer()
    104             && index == other.index;
    105     }
    106
    107     public int getLength() {
    108         return 0;
    109     }
    110
    111     public String asPath() {
    112         StringBuffer buffer = new StringBuffer();
    113         NodePointer parent = getImmediateParentPointer();
    114         if (parent != null) {
    115             buffer.append(parent.asPath());
    116         }
    117         if (index != WHOLE_COLLECTION) {
    118             // Address the list[1][2] case
    119             if (parent != null && parent.getIndex() != WHOLE_COLLECTION) {
    120                 buffer.append("/.");
    121             }
    122             else if (parent != null
    123                     && parent.getImmediateParentPointer() != null
    124                     && parent.getImmediateParentPointer().getIndex() !=
    125                             WHOLE_COLLECTION)
    126             {
    127                 buffer.append("/.");
    128             }
    129             buffer.append("[").append(index + 1).append(']');
    130         }
    131
    132         return buffer.toString();
    133     }
    134 }