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.jxpath.ri.model.container;
18  
19  import java.util.Locale;
20  
21  import org.apache.commons.jxpath.Container;
22  import org.apache.commons.jxpath.ri.QName;
23  import org.apache.commons.jxpath.ri.compiler.NodeTest;
24  import org.apache.commons.jxpath.ri.model.NodeIterator;
25  import org.apache.commons.jxpath.ri.model.NodePointer;
26  import org.apache.commons.jxpath.util.ValueUtils;
27  
28  /**
29   * Transparent pointer to a Container. The {@link #getValue()} method
30   * returns the contents of the container, rather than the container
31   * itself.
32   *
33   * @author Dmitri Plotnikov
34   * @version $Revision: 652884 $ $Date: 2008-05-02 22:02:00 +0200 (Fr, 02 Mai 2008) $
35   */
36  public class ContainerPointer extends NodePointer {
37      private Container container;
38      private NodePointer valuePointer;
39  
40      private static final long serialVersionUID = 6140752946621686118L;
41  
42      /**
43       * Create a new ContainerPointer.
44       * @param container Container object
45       * @param locale Locale
46       */
47      public ContainerPointer(Container container, Locale locale) {
48          super(null, locale);
49          this.container = container;
50      }
51  
52      /**
53       * Create a new ContainerPointer.
54       * @param parent parent pointer
55       * @param container Container object
56       */
57      public ContainerPointer(NodePointer parent, Container container) {
58          super(parent);
59          this.container = container;
60      }
61  
62      /**
63       * This type of node is auxiliary.
64       * @return <code>true</code>.
65       */
66      public boolean isContainer() {
67          return true;
68      }
69  
70      public QName getName() {
71          return null;
72      }
73  
74      public Object getBaseValue() {
75          return container;
76      }
77  
78      public boolean isCollection() {
79          Object value = getBaseValue();
80          return value != null && ValueUtils.isCollection(value);
81      }
82  
83      public int getLength() {
84          Object value = getBaseValue();
85          return value == null ? 1 : ValueUtils.getLength(value);
86      }
87  
88      public boolean isLeaf() {
89          return getValuePointer().isLeaf();
90      }
91  
92      public Object getImmediateNode() {
93          Object value = getBaseValue();
94          if (index != WHOLE_COLLECTION) {
95              return index >= 0 && index < getLength() ? ValueUtils.getValue(value, index) : null;
96          }
97          return ValueUtils.getValue(value);
98      }
99  
100     public void setValue(Object value) {
101         // TODO: what if this is a collection?
102         container.setValue(value);
103     }
104 
105     public NodePointer getImmediateValuePointer() {
106         if (valuePointer == null) {
107             Object value = getImmediateNode();
108             valuePointer = NodePointer.newChildNodePointer(this, getName(), value);
109         }
110         return valuePointer;
111     }
112 
113     public int hashCode() {
114         return System.identityHashCode(container) + index;
115     }
116 
117     public boolean equals(Object object) {
118         if (object == this) {
119             return true;
120         }
121 
122         if (!(object instanceof ContainerPointer)) {
123             return false;
124         }
125 
126         ContainerPointer other = (ContainerPointer) object;
127         return container == other.container && index == other.index;
128     }
129 
130     public NodeIterator childIterator(
131         NodeTest test,
132         boolean reverse,
133         NodePointer startWith) {
134         return getValuePointer().childIterator(test, reverse, startWith);
135     }
136 
137     public NodeIterator attributeIterator(QName name) {
138         return getValuePointer().attributeIterator(name);
139     }
140 
141     public NodeIterator namespaceIterator() {
142         return getValuePointer().namespaceIterator();
143     }
144 
145     public NodePointer namespacePointer(String namespace) {
146         return getValuePointer().namespacePointer(namespace);
147     }
148 
149     public boolean testNode(NodeTest nodeTest) {
150         return getValuePointer().testNode(nodeTest);
151     }
152 
153     public int compareChildNodePointers(
154         NodePointer pointer1,
155         NodePointer pointer2) {
156         return pointer1.getIndex() - pointer2.getIndex();
157     }
158 
159     public String getNamespaceURI(String prefix) {
160         return getValuePointer().getNamespaceURI(prefix);
161     }
162 
163     public String asPath() {
164         return parent == null ? "/" : parent.asPath();
165     }
166 }