286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 2001-2004 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A/*
286N/A * $Id: MultipleNodeCounter.java,v 1.2.4.1 2005/09/12 11:49:56 pvedula Exp $
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xalan.internal.xsltc.dom;
286N/A
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.DOM;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.Translet;
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.util.IntegerArray;
286N/Aimport com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
286N/Aimport com.sun.org.apache.xml.internal.dtm.Axis;
286N/A
286N/A/**
286N/A * @author Jacek Ambroziak
286N/A * @author Santiago Pericas-Geertsen
286N/A */
286N/Apublic abstract class MultipleNodeCounter extends NodeCounter {
286N/A private DTMAxisIterator _precSiblings = null;
286N/A
286N/A public MultipleNodeCounter(Translet translet,
286N/A DOM document, DTMAxisIterator iterator) {
286N/A super(translet, document, iterator);
286N/A }
286N/A
286N/A public MultipleNodeCounter(Translet translet,
286N/A DOM document,
286N/A DTMAxisIterator iterator,
286N/A boolean hasFrom) {
286N/A super(translet, document, iterator, hasFrom);
286N/A }
286N/A
286N/A public NodeCounter setStartNode(int node) {
286N/A _node = node;
286N/A _nodeType = _document.getExpandedTypeID(node);
286N/A _precSiblings = _document.getAxisIterator(Axis.PRECEDINGSIBLING);
286N/A return this;
286N/A }
286N/A
286N/A public String getCounter() {
286N/A if (_value != Integer.MIN_VALUE) {
286N/A //See Errata E24
286N/A if (_value == 0) return "0";
286N/A else if (Double.isNaN(_value)) return "NaN";
286N/A else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
286N/A else if (Double.isInfinite(_value)) return "Infinity";
286N/A else return formatNumbers((int)_value);
286N/A }
286N/A
286N/A IntegerArray ancestors = new IntegerArray();
286N/A
286N/A // Gather all ancestors that do not match from pattern
286N/A int next = _node;
286N/A ancestors.add(next); // include self
286N/A while ((next = _document.getParent(next)) > END &&
286N/A !matchesFrom(next)) {
286N/A ancestors.add(next);
286N/A }
286N/A
286N/A // Create an array of counters
286N/A final int nAncestors = ancestors.cardinality();
286N/A final int[] counters = new int[nAncestors];
286N/A for (int i = 0; i < nAncestors; i++) {
286N/A counters[i] = Integer.MIN_VALUE;
286N/A }
286N/A
286N/A // Increment array of counters according to semantics
286N/A for (int j = 0, i = nAncestors - 1; i >= 0 ; i--, j++) {
286N/A final int counter = counters[j];
286N/A final int ancestor = ancestors.at(i);
286N/A
286N/A if (matchesCount(ancestor)) {
286N/A _precSiblings.setStartNode(ancestor);
286N/A while ((next = _precSiblings.next()) != END) {
286N/A if (matchesCount(next)) {
286N/A counters[j] = (counters[j] == Integer.MIN_VALUE) ? 1
286N/A : counters[j] + 1;
286N/A }
286N/A }
286N/A // Count the node itself
286N/A counters[j] = counters[j] == Integer.MIN_VALUE
286N/A ? 1
286N/A : counters[j] + 1;
286N/A }
286N/A }
286N/A return formatNumbers(counters);
286N/A }
286N/A
286N/A public static NodeCounter getDefaultNodeCounter(Translet translet,
286N/A DOM document,
286N/A DTMAxisIterator iterator) {
286N/A return new DefaultMultipleNodeCounter(translet, document, iterator);
286N/A }
286N/A
286N/A static class DefaultMultipleNodeCounter extends MultipleNodeCounter {
286N/A public DefaultMultipleNodeCounter(Translet translet,
286N/A DOM document,
286N/A DTMAxisIterator iterator) {
286N/A super(translet, document, iterator);
286N/A }
286N/A }
286N/A}