001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements. See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership. The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the  "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    /*
019     * $Id: ForwardPositionIterator.java 468651 2006-10-28 07:04:25Z minchau $
020     */
021    
022    package org.apache.xalan.xsltc.dom;
023    
024    import org.apache.xalan.xsltc.runtime.BasisLibrary;
025    import org.apache.xml.dtm.DTMAxisIterator;
026    import org.apache.xml.dtm.ref.DTMAxisIteratorBase;
027    
028    /**
029     * This iterator is a wrapper that always returns the position of
030     * a node in document order. It is needed for the case where 
031     * a call to position() occurs in the context of an XSLT element
032     * such as xsl:for-each, xsl:apply-templates, etc. 
033     *
034     * The getPosition() methods in DTMAxisIterators defined
035     * in DTMDefaultBaseIterators always return the position
036     * in document order, which is backwards for XPath in the
037     * case of the ancestor, ancestor-or-self, previous and
038     * previous-sibling.
039     *
040     * XSLTC implements position() with the
041     * BasisLibrary.positionF() method, and uses the
042     * DTMAxisIterator.isReverse() method to determine
043     * whether the result of getPosition() should be
044     * interpreted as being equal to position().
045     * But when the expression appears in apply-templates of
046     * for-each, the position() function operates in document
047     * order.
048     *
049     * The only effect of the ForwardPositionIterator is to force
050     * the result of isReverse() to false, so that
051     * BasisLibrary.positionF() calculates position() in a way
052     * that's consistent with the context in which the
053     * iterator is being used."
054     *
055     * (Apparently the correction of isReverse() occurs
056     * implicitly, by inheritance. This class also appears
057     * to maintain its own position counter, which seems
058     * redundant.)
059     *
060     * @deprecated This class exists only for backwards compatibility with old
061     *             translets.  New code should not reference it.
062     */
063    public final class ForwardPositionIterator extends DTMAxisIteratorBase {
064    
065        private DTMAxisIterator _source;
066    
067        public ForwardPositionIterator(DTMAxisIterator source) {
068            _source = source;
069        }
070    
071        public DTMAxisIterator cloneIterator() {
072            try {
073                final ForwardPositionIterator clone = 
074                    (ForwardPositionIterator) super.clone();
075                clone._source = _source.cloneIterator();
076                clone._isRestartable = false;
077                return clone.reset();
078            }
079            catch (CloneNotSupportedException e) {
080                BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
081                                          e.toString());
082                return null;
083            }
084        }
085    
086        public int next() {
087            return returnNode(_source.next());
088        }
089            
090        public DTMAxisIterator setStartNode(int node) {
091            _source.setStartNode(node);
092            return this;
093        }
094    
095        public DTMAxisIterator reset() {
096            _source.reset();
097            return resetPosition();
098        }
099    
100        public void setMark() {
101            _source.setMark();
102        }
103    
104        public void gotoMark() {
105            _source.gotoMark();
106        }
107    }