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; 27import com.sun.org.apache.xml.internal.dtm.Axis; 28 29 30/** 31 * @author Jacek Ambroziak 32 * @author Santiago Pericas-Geertsen 33 */ 34public abstract class SingleNodeCounter extends NodeCounter { 35 static private final int[] EmptyArray = new int[] { }; 36 DTMAxisIterator _countSiblings = null; 37 38 public SingleNodeCounter(Translet translet, 39 DOM document, 40 DTMAxisIterator iterator) { 41 super(translet, document, iterator); 42 } 43 44 public SingleNodeCounter(Translet translet, 45 DOM document, 46 DTMAxisIterator iterator, 47 boolean hasFrom) { 48 super(translet, document, iterator, hasFrom); 49 } 50 51 public NodeCounter setStartNode(int node) { 52 _node = node; 53 _nodeType = _document.getExpandedTypeID(node); 54 _countSiblings = _document.getAxisIterator(Axis.PRECEDINGSIBLING); 55 return this; 56 } 57 58 public String getCounter() { 59 int result; 60 if (_value != Integer.MIN_VALUE) { 61 //See Errata E24 62 if (_value == 0) return "0"; 63 else if (Double.isNaN(_value)) return "NaN"; 64 else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity"; 65 else if (Double.isInfinite(_value)) return "Infinity"; 66 else result = (int) _value; 67 } 68 else { 69 int next = _node; 70 result = 0; 71 boolean matchesCount = matchesCount(next); 72 73 if (!matchesCount) { 74 while ((next = _document.getParent(next)) > END) { 75 if (matchesCount(next)) { 76 break; // found target 77 } 78 if (matchesFrom(next)) { 79 next = END; 80 break; // no target found 81 } 82 } 83 } 84 85 if (next != END) { 86 int from = next; 87 88 if (!matchesCount && _hasFrom) { 89 // Target found, but need to check if ancestor matches from 90 while ((from = _document.getParent(from)) > END) { 91 if (matchesFrom(from)) { 92 break; // found from 93 } 94 } 95 } 96 97 // Have we found ancestor matching from? 98 if (from != END) { 99 _countSiblings.setStartNode(next); 100 do { 101 if (matchesCount(next)) result++; 102 } while ((next = _countSiblings.next()) != END); 103 104 return formatNumbers(result); 105 } 106 } 107 108 // If no target found then pass the empty list 109 return formatNumbers(EmptyArray); 110 } 111 return formatNumbers(result); 112 } 113 114 public static NodeCounter getDefaultNodeCounter(Translet translet, 115 DOM document, 116 DTMAxisIterator iterator) { 117 return new DefaultSingleNodeCounter(translet, document, iterator); 118 } 119 120 static class DefaultSingleNodeCounter extends SingleNodeCounter { 121 public DefaultSingleNodeCounter(Translet translet, 122 DOM document, DTMAxisIterator iterator) { 123 super(translet, document, iterator); 124 } 125 126 public NodeCounter setStartNode(int node) { 127 _node = node; 128 _nodeType = _document.getExpandedTypeID(node); 129 _countSiblings = 130 _document.getTypedAxisIterator(Axis.PRECEDINGSIBLING, 131 _document.getExpandedTypeID(node)); 132 return this; 133 } 134 135 public String getCounter() { 136 int result; 137 if (_value != Integer.MIN_VALUE) { 138 //See Errata E24 139 if (_value == 0) return "0"; 140 else if (Double.isNaN(_value)) return "NaN"; 141 else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity"; 142 else if (Double.isInfinite(_value)) return "Infinity"; 143 else result = (int) _value; 144 } 145 else { 146 int next; 147 result = 1; 148 _countSiblings.setStartNode(_node); 149 while ((next = _countSiblings.next()) != END) { 150 result++; 151 } 152 } 153 return formatNumbers(result); 154 } 155 } 156} 157