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