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 22 package com.sun.org.apache.xalan.internal.xsltc.dom; 23 24 import com.sun.org.apache.xalan.internal.xsltc.DOM; 25 import com.sun.org.apache.xalan.internal.xsltc.Translet; 26 import com.sun.org.apache.xalan.internal.xsltc.util.IntegerArray; 27 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator; 28 import com.sun.org.apache.xml.internal.dtm.Axis; 29 30 /** 31 * @author Jacek Ambroziak 32 * @author Santiago Pericas-Geertsen 33 */ 34 public abstract class MultipleNodeCounter extends NodeCounter { 35 private DTMAxisIterator _precSiblings = null; 36 37 public MultipleNodeCounter(Translet translet, 38 DOM document, DTMAxisIterator iterator) { 39 super(translet, document, iterator); 40 } 41 42 public MultipleNodeCounter(Translet translet, 43 DOM document, 44 DTMAxisIterator iterator, 45 boolean hasFrom) { 46 super(translet, document, iterator, hasFrom); 47 } 48 49 public NodeCounter setStartNode(int node) { 50 _node = node; 51 _nodeType = _document.getExpandedTypeID(node); 52 _precSiblings = _document.getAxisIterator(Axis.PRECEDINGSIBLING); 53 return this; 54 } 55 56 public String getCounter() { 57 if (_value != Integer.MIN_VALUE) { 58 //See Errata E24 59 if (_value == 0) return "0"; 60 else if (Double.isNaN(_value)) return "NaN"; 61 else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity"; 62 else if (Double.isInfinite(_value)) return "Infinity"; 63 else return formatNumbers((int)_value); 64 } 65 66 IntegerArray ancestors = new IntegerArray(); 67 68 // Gather all ancestors that do not match from pattern 69 int next = _node; 70 ancestors.add(next); // include self 71 while ((next = _document.getParent(next)) > END && 72 !matchesFrom(next)) { 73 ancestors.add(next); 74 } 75 76 // Create an array of counters 77 final int nAncestors = ancestors.cardinality(); 78 final int[] counters = new int[nAncestors]; 79 for (int i = 0; i < nAncestors; i++) { 80 counters[i] = Integer.MIN_VALUE; 81 } 82 83 // Increment array of counters according to semantics 84 for (int j = 0, i = nAncestors - 1; i >= 0 ; i--, j++) { 85 final int counter = counters[j]; 86 final int ancestor = ancestors.at(i); 87 88 if (matchesCount(ancestor)) { 89 _precSiblings.setStartNode(ancestor); 90 while ((next = _precSiblings.next()) != END) { 91 if (matchesCount(next)) { 92 counters[j] = (counters[j] == Integer.MIN_VALUE) ? 1 93 : counters[j] + 1; 94 } 95 } 96 // Count the node itself 97 counters[j] = counters[j] == Integer.MIN_VALUE 98 ? 1 99 : counters[j] + 1; 100 } 101 } 102 return formatNumbers(counters); 103 } 104 105 public static NodeCounter getDefaultNodeCounter(Translet translet, 106 DOM document, 107 DTMAxisIterator iterator) { 108 return new DefaultMultipleNodeCounter(translet, document, iterator); 109 } 110 111 static class DefaultMultipleNodeCounter extends MultipleNodeCounter { 112 public DefaultMultipleNodeCounter(Translet translet, 113 DOM document, 114 DTMAxisIterator iterator) { 115 super(translet, document, iterator); 116 } 117 } 118 }