    001    /*
    002     * Licensed to the Apache Software Foundation (ASF) under one or more
    003     * contributor license agreements.  See the NOTICE file distributed with
    004     * this work for additional information regarding copyright ownership.
    005     * The ASF licenses this file to You under the Apache License, Version 2.0
    006     * (the "License"); you may not use this file except in compliance with
    007     * the License.  You may obtain a copy of the License at
    008     *
    009     *     http://www.apache.org/licenses/LICENSE-2.0
    010     *
    011     * Unless required by applicable law or agreed to in writing, software
    012     * distributed under the License is distributed on an "AS IS" BASIS,
    013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    014     * See the License for the specific language governing permissions and
    015     * limitations under the License.
    016     */
    017    package org.apache.commons.jxpath.ri.model.beans;
    018
    019    import org.apache.commons.jxpath.JXPathContext;
    020    import org.apache.commons.jxpath.ri.QName;
    021    import org.apache.commons.jxpath.ri.model.NodePointer;
    022
    023    /**
    024     * Used when there is a need to construct a Pointer for a collection element
    025     * that does not exist.  For example, if the path is "foo[3]", but the
    026     * collection "foo" only has one element or is empty or is null, the
    027     * NullElementPointer can be used to capture this situation without putting a
    028     * regular NodePointer into an invalid state.  Just create a NullElementPointer
    029     * with index 2 (= 3 - 1) and a "foo" pointer as the parent.
    030     *
    031     * @author Dmitri Plotnikov
    032     * @version $Revision: 652884 $ $Date: 2008-05-02 15:02:00 -0500 (Fri, 02 May 2008) $
    033     */
    034    public class NullElementPointer extends CollectionPointer {
    035
    036        private static final long serialVersionUID = 8714236818791036721L;
    037
    038        /**
    039         * Create a new NullElementPointer.
    040         * @param parent parent pointer
    041         * @param index int
    042         */
    043        public NullElementPointer(NodePointer parent, int index) {
    044            super(parent, (Object) null);
    045            this.index = index;
    046        }
    047
    048        public QName getName() {
    049            return null;
    050        }
    051
    052        public Object getBaseValue() {
    053            return null;
    054        }
    055
    056        public Object getImmediateNode() {
    057            return null;
    058        }
    059
    060        public boolean isLeaf() {
    061            return true;
    062        }
    063
    064        public boolean isCollection() {
    065            return false;
    066        }
    067
    068        /**
    069         * Get the property pointer for this.
    070         * @return PropertyPointer
    071         */
    072        public PropertyPointer getPropertyPointer() {
    073            return new NullPropertyPointer(this);
    074        }
    075
    076        public NodePointer getValuePointer() {
    077            return new NullPointer(this, getName());
    078        }
    079
    080        public void setValue(Object value) {
    081            throw new UnsupportedOperationException(
    082                "Collection element does not exist: " + this);
    083        }
    084
    085        public boolean isActual() {
    086            return false;
    087        }
    088
    089        public boolean isContainer() {
    090            return true;
    091        }
    092
    093        public NodePointer createPath(JXPathContext context) {
    094            return parent.createChild(context, null, index);
    095        }
    096
    097        public NodePointer createPath(JXPathContext context, Object value) {
    098            return parent.createChild(context, null, index, value);
    099        }
    100
    101        public int hashCode() {
    102            return getImmediateParentPointer().hashCode() + index;
    103        }
    104
    105        public boolean equals(Object object) {
    106            if (object == this) {
    107                return true;
    108            }
    109
    110            if (!(object instanceof NullElementPointer)) {
    111                return false;
    112            }
    113
    114            NullElementPointer other = (NullElementPointer) object;
    115            return getImmediateParentPointer() == other.getImmediateParentPointer()
    116                    && index == other.index;
    117        }
    118
    119        public int getLength() {
    120            return 0;
    121        }
    122
    123        public String asPath() {
    124            StringBuffer buffer = new StringBuffer();
    125            NodePointer parent = getImmediateParentPointer();
    126            if (parent != null) {
    127                buffer.append(parent.asPath());
    128            }
    129            if (index != WHOLE_COLLECTION) {
    130                // Address the list[1][2] case
    131                if (parent != null && parent.getIndex() != WHOLE_COLLECTION) {
    132                    buffer.append("/.");
    133                }
    134                else if (parent != null
    135                        && parent.getImmediateParentPointer() != null
    136                        && parent.getImmediateParentPointer().getIndex() != WHOLE_COLLECTION) {
    137                    buffer.append("/.");
    138                }
    139                buffer.append("[").append(index + 1).append(']');
    140            }
    141
    142            return buffer.toString();
    143        }
    144    }