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