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: SingleNodeCounter.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.DOM;
025    import org.apache.xalan.xsltc.Translet;
026    import org.apache.xml.dtm.DTMAxisIterator;
027    import org.apache.xml.dtm.Axis;
028    
029    
030    /**
031     * @author Jacek Ambroziak
032     * @author Santiago Pericas-Geertsen
033     */
034    public abstract class SingleNodeCounter extends NodeCounter {
035        static private final int[] EmptyArray = new int[] { };
036        DTMAxisIterator _countSiblings = null;
037    
038        public SingleNodeCounter(Translet translet,
039                                 DOM document,
040                                 DTMAxisIterator iterator) {
041            super(translet, document, iterator);
042        }
043    
044        public NodeCounter setStartNode(int node) {
045            _node = node;
046            _nodeType = _document.getExpandedTypeID(node);
047        _countSiblings = _document.getAxisIterator(Axis.PRECEDINGSIBLING);
048            return this;
049        }
050    
051        public String getCounter() {
052            int result;
053            if (_value != Integer.MIN_VALUE) {
054                    //See Errata E24
055                    if (_value == 0) return "0";
056                    else if (Double.isNaN(_value)) return "NaN";
057                    else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
058                    else if (Double.isInfinite(_value)) return "Infinity";
059                    else result = (int) _value;
060            }
061            else {
062                int next = _node;
063                result = 0;
064                if (!matchesCount(next)) {
065                    while ((next = _document.getParent(next)) > END) {
066                        if (matchesCount(next)) {
067                            break;          // found target
068                        }
069                        if (matchesFrom(next)) {
070                            next = END;
071                            break;          // no target found
072                        }
073                    }
074                }
075    
076                if (next != END) {
077                    _countSiblings.setStartNode(next);
078                    do {
079                        if (matchesCount(next)) result++;
080                    } while ((next = _countSiblings.next()) != END);
081                }
082                else {
083                    // If no target found then pass the empty list
084                    return formatNumbers(EmptyArray);
085                }
086            }
087            return formatNumbers(result);
088        }
089    
090        public static NodeCounter getDefaultNodeCounter(Translet translet,
091                                                        DOM document,
092                                                        DTMAxisIterator iterator) {
093            return new DefaultSingleNodeCounter(translet, document, iterator);
094        }
095    
096        static class DefaultSingleNodeCounter extends SingleNodeCounter {
097            public DefaultSingleNodeCounter(Translet translet,
098                                            DOM document, DTMAxisIterator iterator) {
099                super(translet, document, iterator);
100            }
101    
102            public NodeCounter setStartNode(int node) {
103                _node = node;
104                _nodeType = _document.getExpandedTypeID(node);
105                _countSiblings =
106            _document.getTypedAxisIterator(Axis.PRECEDINGSIBLING,
107                                                   _document.getExpandedTypeID(node));
108                return this;
109            }
110    
111            public String getCounter() {
112                int result;
113                if (_value != Integer.MIN_VALUE) {
114                    //See Errata E24
115                    if (_value == 0) return "0";
116                    else if (Double.isNaN(_value)) return "NaN";
117                    else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
118                    else if (Double.isInfinite(_value)) return "Infinity";
119                    else result = (int) _value;
120                }
121                else {
122                    int next;
123                    result = 1;
124                    _countSiblings.setStartNode(_node);
125                    while ((next = _countSiblings.next()) != END) {
126                        result++;
127                    }
128                }
129                return formatNumbers(result);
130            }
131        }
132    }
133