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: NthIterator.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     * @author Jacek Ambroziak
030     * @author Morten Jorgensen
031     */
032    public final class NthIterator extends DTMAxisIteratorBase {
033        // ...[N]
034        private DTMAxisIterator _source;
035        private final int _position;
036        private boolean _ready;
037    
038        public NthIterator(DTMAxisIterator source, int n) {
039            _source = source;
040            _position = n;
041        }
042    
043        public void setRestartable(boolean isRestartable) {
044            _isRestartable = isRestartable;
045            _source.setRestartable(isRestartable);
046        }
047        
048        public DTMAxisIterator cloneIterator() {
049            try {
050                final NthIterator clone = (NthIterator) super.clone();
051                clone._source = _source.cloneIterator();    // resets source
052                clone._isRestartable = false;
053                return clone;
054            }
055            catch (CloneNotSupportedException e) {
056                BasisLibrary.runTimeError(BasisLibrary.ITERATOR_CLONE_ERR,
057                                          e.toString());
058                return null;
059            }
060        }
061    
062        public int next() {
063            if (_ready) {
064                _ready = false;
065                return _source.getNodeByPosition(_position);
066            }
067            return DTMAxisIterator.END;
068            /*
069            if (_ready && _position > 0) {
070                final int pos = _source.isReverse()
071                                           ? _source.getLast() - _position + 1
072                                           : _position;
073    
074                _ready = false;
075                int node;
076                while ((node = _source.next()) != DTMAxisIterator.END) {
077                    if (pos == _source.getPosition()) {
078                        return node;
079                    }
080                }
081            }
082            return DTMAxisIterator.END;
083            */
084        }
085    
086        public DTMAxisIterator setStartNode(final int node) {
087            if (_isRestartable) {
088                _source.setStartNode(node);
089                _ready = true;
090            }
091            return this;
092        }
093            
094        public DTMAxisIterator reset() {
095            _source.reset();
096            _ready = true;
097            return this;
098        }
099        
100        public int getLast() {
101            return 1;
102        }
103        
104        public int getPosition() {
105            return 1;
106        }
107        
108        public void setMark() {
109            _source.setMark();
110        }
111        
112        public void gotoMark() {
113            _source.gotoMark();
114        }
115    }