1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/*
6 * Licensed to the Apache Software Foundation (ASF) under one or more
7 * contributor license agreements.  See the NOTICE file distributed with
8 * this work for additional information regarding copyright ownership.
9 * The ASF licenses this file to You under the Apache License, Version 2.0
10 * (the "License"); you may not use this file except in compliance with
11 * the License.  You may obtain a copy of the License at
12 *
13 *      http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22package com.sun.org.apache.xalan.internal.xsltc.dom;
23
24import com.sun.org.apache.xalan.internal.xsltc.DOM;
25import com.sun.org.apache.xalan.internal.xsltc.Translet;
26import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
27
28/**
29 * @author Jacek Ambroziak
30 * @author Santiago Pericas-Geertsen
31 */
32public abstract class AnyNodeCounter extends NodeCounter {
33    public AnyNodeCounter(Translet translet,
34                          DOM document, DTMAxisIterator iterator) {
35        super(translet, document, iterator);
36    }
37
38    public AnyNodeCounter(Translet translet,
39                          DOM document,
40                          DTMAxisIterator iterator,
41                          boolean hasFrom) {
42        super(translet, document, iterator, hasFrom);
43    }
44
45    public NodeCounter setStartNode(int node) {
46        _node = node;
47        _nodeType = _document.getExpandedTypeID(node);
48        return this;
49    }
50
51    public String getCounter() {
52        int result;
53        if (_value != Integer.MIN_VALUE) {
54            //See Errata E24
55            if (_value == 0) return "0";
56            else if (Double.isNaN(_value)) return "NaN";
57            else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
58            else if (Double.isInfinite(_value)) return "Infinity";
59            else return formatNumbers((int)_value);
60        }
61        else {
62            int next = _node;
63            final int root = _document.getDocument();
64            result = 0;
65            while (next >= root && !matchesFrom(next)) {
66                if (matchesCount(next)) {
67                    ++result;
68                }
69                next--;
70//%HZ%:  Is this the best way of finding the root?  Is it better to check
71//%HZ%:  parent(next)?
72                /*
73                if (next == root) {
74                    break;
75                }
76                else {
77                    --next;
78                }
79                */
80            }
81        }
82        return formatNumbers(result);
83    }
84
85    public static NodeCounter getDefaultNodeCounter(Translet translet,
86                                                    DOM document,
87                                                    DTMAxisIterator iterator) {
88        return new DefaultAnyNodeCounter(translet, document, iterator);
89    }
90
91    static class DefaultAnyNodeCounter extends AnyNodeCounter {
92        public DefaultAnyNodeCounter(Translet translet,
93                                     DOM document, DTMAxisIterator iterator) {
94            super(translet, document, iterator);
95        }
96
97        public String getCounter() {
98            int result;
99            if (_value != Integer.MIN_VALUE) {
100                    //See Errata E24
101                    if (_value == 0) return "0";
102                    else if (Double.isNaN(_value)) return "NaN";
103                    else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
104                    else if (Double.isInfinite(_value)) return "Infinity";
105                    else result = (int) _value;
106            }
107            else {
108                int next = _node;
109                result = 0;
110                final int ntype = _document.getExpandedTypeID(_node);
111                final int root = _document.getDocument();
112                while (next >= 0) {
113                    if (ntype == _document.getExpandedTypeID(next)) {
114                        result++;
115                    }
116//%HZ%:  Is this the best way of finding the root?  Is it better to check
117//%HZ%:  parent(next)?
118                    if (next == root) {
119                        break;
120                    }
121                    else {
122                        --next;
123                    }
124                }
125            }
126            return formatNumbers(result);
127        }
128    }
129}
130