jaxp/src/com/sun/org/apache/xml/internal/dtm/ref/DTMAxisIterNodeList.java
author aefimov
Tue, 01 Oct 2013 17:14:08 +0400
changeset 20580 ec467abf6fc9
parent 12457 c348e06f0e82
permissions -rw-r--r--
8024707: TransformerException : item() return null with node list of length != 1 Reviewed-by: joehw, lancea
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
 * Copyright 1999-2004 The Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * Licensed under the Apache License, Version 2.0 (the "License");
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 * you may not use this file except in compliance with the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * You may obtain a copy of the License at
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *     http://www.apache.org/licenses/LICENSE-2.0
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 * $Id: DTMAxisIterNodeList.java,v 1.2.4.1 2005/09/15 08:14:59 suresh_emailid Exp $
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
package com.sun.org.apache.xml.internal.dtm.ref;
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
import com.sun.org.apache.xml.internal.dtm.DTM;
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
import com.sun.org.apache.xml.internal.utils.IntVector;
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
import org.w3c.dom.Node;
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
 * <code>DTMAxisNodeList</code> gives us an implementation of the DOM's
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
 * NodeList interface wrapped around a DTM Iterator. The author
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
 * considers this something of an abominations, since NodeList was not
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
 * intended to be a general purpose "list of nodes" API and is
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
 * generally considered by the DOM WG to have be a mistake... but I'm
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
 * told that some of the XPath/XSLT folks say they must have this
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
 * solution.
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
 * Please note that this is not necessarily equivlaent to a DOM
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
 * NodeList operating over the same document. In particular:
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
 * <ul>
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 * <li>If there are several Text nodes in logical succession (ie,
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * across CDATASection and EntityReference boundaries), we will return
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 * only the first; the caller is responsible for stepping through
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
 * them.
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
 * (%REVIEW% Provide a convenience routine here to assist, pending
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
 * proposed DOM Level 3 getAdjacentText() operation?) </li>
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
 * <li>Since the whole XPath/XSLT architecture assumes that the source
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
 * document is not altered while we're working with it, we do not
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
 * promise to implement the DOM NodeList's "live view" response to
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
 * document mutation. </li>
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
 * </ul>
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
 * <p>State: In progress!!</p>
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
 * */
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
public class DTMAxisIterNodeList extends DTMNodeListBase {
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
    private DTM m_dtm;
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
    private DTMAxisIterator m_iter;
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
    private IntVector m_cachedNodes;
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
    private int m_last = -1;
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
    //================================================================
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
    // Methods unique to this class
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
    private DTMAxisIterNodeList() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
     * Public constructor: Wrap a DTMNodeList around an existing
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
     * and preconfigured DTMAxisIterator
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
    public DTMAxisIterNodeList(DTM dtm, DTMAxisIterator dtmAxisIterator) {
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
        if (dtmAxisIterator == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
            m_last = 0;
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
        } else {
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
            m_cachedNodes = new IntVector();
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
            m_dtm = dtm;
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
        m_iter = dtmAxisIterator;
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
     * Access the wrapped DTMIterator. I'm not sure whether anyone will
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
     * need this or not, but let's write it and think about it.
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
     *
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
    public DTMAxisIterator getDTMAxisIterator() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
        return m_iter;
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
    //================================================================
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
    // org.w3c.dom.NodeList API follows
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
     * Returns the <code>index</code>th item in the collection. If
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
     * <code>index</code> is greater than or equal to the number of nodes in
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
     * the list, this returns <code>null</code>.
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
     * @param index Index into the collection.
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
     * @return The node at the <code>index</code>th position in the
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
     *   <code>NodeList</code>, or <code>null</code> if that is not a valid
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
     *   index.
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
    public Node item(int index) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
        if (m_iter != null) {
20580
ec467abf6fc9 8024707: TransformerException : item() return null with node list of length != 1
aefimov
parents: 12457
diff changeset
   108
            int node = 0;
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
            int count = m_cachedNodes.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
            if (count > index) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
                node = m_cachedNodes.elementAt(index);
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
                return m_dtm.getNode(node);
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
            } else if (m_last == -1) {
20580
ec467abf6fc9 8024707: TransformerException : item() return null with node list of length != 1
aefimov
parents: 12457
diff changeset
   115
                while (count <= index
ec467abf6fc9 8024707: TransformerException : item() return null with node list of length != 1
aefimov
parents: 12457
diff changeset
   116
                        && ((node = m_iter.next()) != DTMAxisIterator.END)) {
6
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
                    m_cachedNodes.addElement(node);
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
                    count++;
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
                if (node == DTMAxisIterator.END) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
                    m_last = count;
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
                } else {
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
                    return m_dtm.getNode(node);
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
        return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
     * The number of nodes in the list. The range of valid child node indices
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
     * is 0 to <code>length-1</code> inclusive.
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
    public int getLength() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
        if (m_last == -1) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
            int node;
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
            while ((node = m_iter.next()) != DTMAxisIterator.END) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
                m_cachedNodes.addElement(node);
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
            m_last = m_cachedNodes.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
        return m_last;
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
}