1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Copyright 2001-2005 The Apache Software Foundation.
   7  *
   8  * Licensed under the Apache License, Version 2.0 (the "License");
   9  * you may not use this file except in compliance with the License.
  10  * You may obtain a copy of the License at
  11  *
  12  *     http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 /*
  21  * $Id: SingleNodeCounter.java,v 1.2.4.1 2005/09/12 11:58:23 pvedula Exp $
  22  */
  23 
  24 package com.sun.org.apache.xalan.internal.xsltc.dom;
  25 
  26 import com.sun.org.apache.xalan.internal.xsltc.DOM;
  27 import com.sun.org.apache.xalan.internal.xsltc.Translet;
  28 import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;
  29 import com.sun.org.apache.xml.internal.dtm.Axis;
  30 
  31 
  32 /**
  33  * @author Jacek Ambroziak
  34  * @author Santiago Pericas-Geertsen
  35  */
  36 public abstract class SingleNodeCounter extends NodeCounter {
  37     static private final int[] EmptyArray = new int[] { };
  38     DTMAxisIterator _countSiblings = null;
  39 
  40     public SingleNodeCounter(Translet translet,
  41                              DOM document,
  42                              DTMAxisIterator iterator) {
  43         super(translet, document, iterator);
  44     }
  45 
  46     public SingleNodeCounter(Translet translet,
  47                              DOM document,
  48                              DTMAxisIterator iterator,
  49                              boolean hasFrom) {
  50         super(translet, document, iterator, hasFrom);
  51     }
  52 
  53     public NodeCounter setStartNode(int node) {
  54         _node = node;
  55         _nodeType = _document.getExpandedTypeID(node);
  56     _countSiblings = _document.getAxisIterator(Axis.PRECEDINGSIBLING);
  57         return this;
  58     }
  59 
  60     public String getCounter() {
  61         int result;
  62         if (_value != Integer.MIN_VALUE) {
  63                 //See Errata E24
  64                 if (_value == 0) return "0";
  65                 else if (Double.isNaN(_value)) return "NaN";
  66                 else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
  67                 else if (Double.isInfinite(_value)) return "Infinity";
  68                 else result = (int) _value;
  69         }
  70         else {
  71             int next = _node;
  72             result = 0;
  73             boolean matchesCount = matchesCount(next);
  74 
  75             if (!matchesCount) {
  76                 while ((next = _document.getParent(next)) > END) {
  77                     if (matchesCount(next)) {
  78                         break;          // found target
  79                     }
  80                     if (matchesFrom(next)) {
  81                         next = END;
  82                         break;          // no target found
  83                     }
  84                 }
  85             }
  86 
  87             if (next != END) {
  88                 int from = next;
  89 
  90                 if (!matchesCount && _hasFrom) {
  91                     // Target found, but need to check if ancestor matches from
  92                     while ((from = _document.getParent(from)) > END) {
  93                         if (matchesFrom(from)) {
  94                             break;          // found from
  95                         }
  96                     }
  97                 }
  98 
  99                 // Have we found ancestor matching from?
 100                 if (from != END) {
 101                     _countSiblings.setStartNode(next);
 102                     do {
 103                         if (matchesCount(next)) result++;
 104                     } while ((next = _countSiblings.next()) != END);
 105 
 106                     return formatNumbers(result);
 107                 }
 108             }
 109 
 110             // If no target found then pass the empty list
 111             return formatNumbers(EmptyArray);
 112         }
 113         return formatNumbers(result);
 114     }
 115 
 116     public static NodeCounter getDefaultNodeCounter(Translet translet,
 117                                                     DOM document,
 118                                                     DTMAxisIterator iterator) {
 119         return new DefaultSingleNodeCounter(translet, document, iterator);
 120     }
 121 
 122     static class DefaultSingleNodeCounter extends SingleNodeCounter {
 123         public DefaultSingleNodeCounter(Translet translet,
 124                                         DOM document, DTMAxisIterator iterator) {
 125             super(translet, document, iterator);
 126         }
 127 
 128         public NodeCounter setStartNode(int node) {
 129             _node = node;
 130             _nodeType = _document.getExpandedTypeID(node);
 131             _countSiblings =
 132         _document.getTypedAxisIterator(Axis.PRECEDINGSIBLING,
 133                                                _document.getExpandedTypeID(node));
 134             return this;
 135         }
 136 
 137         public String getCounter() {
 138             int result;
 139             if (_value != Integer.MIN_VALUE) {
 140                 //See Errata E24
 141                 if (_value == 0) return "0";
 142                 else if (Double.isNaN(_value)) return "NaN";
 143                 else if (_value < 0 && Double.isInfinite(_value)) return "-Infinity";
 144                 else if (Double.isInfinite(_value)) return "Infinity";
 145                 else result = (int) _value;
 146             }
 147             else {
 148                 int next;
 149                 result = 1;
 150                 _countSiblings.setStartNode(_node);
 151                 while ((next = _countSiblings.next()) != END) {
 152                     result++;
 153                 }
 154             }
 155             return formatNumbers(result);
 156         }
 157     }
 158 }