19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one
39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file
49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information
59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file
69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the  "License");
79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License.
89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at
99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *     http://www.apache.org/licenses/LICENSE-2.0
119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *
129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software
139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS,
149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and
169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License.
179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/*
199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: ElemNumber.java 468643 2006-10-28 06:56:03Z minchau $
209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xalan.templates;
229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.text.DecimalFormat;
249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.text.DecimalFormatSymbols;
259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.text.NumberFormat;
269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.Locale;
279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport java.util.NoSuchElementException;
289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException;
309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLTErrorResources;
329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.transformer.CountersTable;
339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.transformer.DecimalToRoman;
349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.transformer.TransformerImpl;
359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.dtm.DTM;
369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.FastStringBuffer;
379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.NodeVector;
389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.PrefixResolver;
399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.StringBufferPool;
409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.res.XResourceBundle;
419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.res.CharArrayWrapper;
429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.res.IntArrayWrapper;
439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.res.LongArrayWrapper;
449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xml.utils.res.StringArrayWrapper;
459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.NodeSetDTM;
469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPath;
479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.XPathContext;
489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject;
499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.w3c.dom.Node;
519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.xml.sax.SAXException;
539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson// import org.apache.xalan.dtm.*;
559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/**
579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Implement xsl:number.
589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <pre>
599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <!ELEMENT xsl:number EMPTY>
609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <!ATTLIST xsl:number
619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    level (single|multiple|any) "single"
629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    count %pattern; #IMPLIED
639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    from %pattern; #IMPLIED
649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    value %expr; #IMPLIED
659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    format %avt; '1'
669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    lang %avt; #IMPLIED
679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    letter-value %avt; #IMPLIED
689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    grouping-separator %avt; #IMPLIED
699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson *    grouping-size %avt; #IMPLIED
709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * >
719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * </pre>
729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @see <a href="http://www.w3.org/TR/xslt#number">number in XSLT Specification</a>
739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage advanced
749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */
759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class ElemNumber extends ElemTemplateElement
769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{
779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    static final long serialVersionUID = 8118472298274407610L;
789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Chars for converting integers into alpha counts.
819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see TransformerImpl#int2alphaCount
829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private CharArrayWrapper m_alphaCountTable = null;
849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private class MyPrefixResolver implements PrefixResolver {
869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        DTM dtm;
889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int handle;
899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        boolean handleNullPrefix;
909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		/**
929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 * Constructor for MyPrefixResolver.
939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 * @param xpathExpressionContext
949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 */
959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		public MyPrefixResolver(Node xpathExpressionContext, DTM dtm, int handle, boolean handleNullPrefix) {
969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.dtm = dtm;
979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.handle = handle;
989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            this.handleNullPrefix = handleNullPrefix;
999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		}
1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    	/**
1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 * @see PrefixResolver#getNamespaceForPrefix(String, Node)
1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 */
1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		public String getNamespaceForPrefix(String prefix) {
1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return dtm.getNamespaceURI(handle);
1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		}
1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        /**
1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * @see PrefixResolver#getNamespaceForPrefix(String, Node)
1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         * this shouldn't get called.
1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson         */
1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        public String getNamespaceForPrefix(String prefix, Node context) {
1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            return getNamespaceForPrefix(prefix);
1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		/**
1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 * @see PrefixResolver#getBaseIdentifier()
1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 */
1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		public String getBaseIdentifier() {
1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			return ElemNumber.this.getBaseIdentifier();
1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		}
1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		/**
1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 * @see PrefixResolver#handlesNullPrefixes()
1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		 */
1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		public boolean handlesNullPrefixes() {
1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson			return handleNullPrefix;
1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson		}
1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only nodes are counted that match this pattern.
1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private XPath m_countMatchPattern = null;
1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "count" attribute.
1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The count attribute is a pattern that specifies what nodes
1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * should be counted at those levels. If count attribute is not
1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specified, then it defaults to the pattern that matches any
1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * node with the same node type as the current node and, if the
1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * current node has an expanded-name, with the same expanded-name
1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as the current node.
1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "count" attribute.
1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setCount(XPath v)
1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_countMatchPattern = v;
1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "count" attribute.
1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The count attribute is a pattern that specifies what nodes
1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * should be counted at those levels. If count attribute is not
1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specified, then it defaults to the pattern that matches any
1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * node with the same node type as the current node and, if the
1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * current node has an expanded-name, with the same expanded-name
1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * as the current node.
1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "count" attribute.
1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPath getCount()
1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_countMatchPattern;
1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Specifies where to count from.
1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For level="single" or level="multiple":
1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only ancestors that are searched are
1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * those that are descendants of the nearest ancestor that matches
1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the from pattern.
1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For level="any:
1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only nodes after the first node before the
1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * current node that match the from pattern are considered.
1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private XPath m_fromMatchPattern = null;
1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "from" attribute. Specifies where to count from.
1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For level="single" or level="multiple":
1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only ancestors that are searched are
1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * those that are descendants of the nearest ancestor that matches
1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the from pattern.
1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For level="any:
1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only nodes after the first node before the
1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * current node that match the from pattern are considered.
1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "from" attribute.
1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setFrom(XPath v)
1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_fromMatchPattern = v;
1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "from" attribute.
2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For level="single" or level="multiple":
2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only ancestors that are searched are
2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * those that are descendants of the nearest ancestor that matches
2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the from pattern.
2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * For level="any:
2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Only nodes after the first node before the
2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * current node that match the from pattern are considered.
2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "from" attribute.
2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPath getFrom()
2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_fromMatchPattern;
2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * When level="single", it goes up to the first node in the ancestor-or-self axis
2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that matches the count pattern, and constructs a list of length one containing
2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * one plus the number of preceding siblings of that ancestor that match the count
2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * pattern. If there is no such ancestor, it constructs an empty list. If the from
2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * attribute is specified, then the only ancestors that are searched are those
2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that are descendants of the nearest ancestor that matches the from pattern.
2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Preceding siblings has the same meaning here as with the preceding-sibling axis.
2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * When level="multiple", it constructs a list of all ancestors of the current node
2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in document order followed by the element itself; it then selects from the list
2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * those nodes that match the count pattern; it then maps each node in the list to
2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * one plus the number of preceding siblings of that node that match the count pattern.
2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * If the from attribute is specified, then the only ancestors that are searched are
2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * those that are descendants of the nearest ancestor that matches the from pattern.
2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Preceding siblings has the same meaning here as with the preceding-sibling axis.
2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * When level="any", it constructs a list of length one containing the number of
2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * nodes that match the count pattern and belong to the set containing the current
2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * node and all nodes at any level of the document that are before the current node
2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * in document order, excluding any namespace and attribute nodes (in other words
2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the union of the members of the preceding and ancestor-or-self axes). If the
2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * from attribute is specified, then only nodes after the first node before the
2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * current node that match the from pattern are considered.
2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int m_level = Constants.NUMBERLEVEL_SINGLE;
2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "level" attribute.
2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The level attribute specifies what levels of the source tree should
2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be considered; it has the values single, multiple or any. The default
2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is single.
2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "level" attribute.
2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setLevel(int v)
2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_level = v;
2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "level" attribute.
2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The level attribute specifies what levels of the source tree should
2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * be considered; it has the values single, multiple or any. The default
2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * is single.
2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "level" attribute.
2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getLevel()
2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_level;
2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The value attribute contains an expression. The expression is evaluated
2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and the resulting object is converted to a number as if by a call to the
2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * number function.
2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private XPath m_valueExpr = null;
2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "value" attribute.
2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The value attribute contains an expression. The expression is evaluated
2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and the resulting object is converted to a number as if by a call to the
2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * number function.
2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "value" attribute.
2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setValue(XPath v)
2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_valueExpr = v;
2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "value" attribute.
2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The value attribute contains an expression. The expression is evaluated
2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and the resulting object is converted to a number as if by a call to the
2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * number function.
2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "value" attribute.
2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public XPath getValue()
3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_valueExpr;
3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The "format" attribute is used to control conversion of a list of
3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * numbers into a string.
3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private AVT m_format_avt = null;
3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "format" attribute.
3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The "format" attribute is used to control conversion of a list of
3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * numbers into a string.
3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "format" attribute.
3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setFormat(AVT v)
3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_format_avt = v;
3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "format" attribute.
3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The "format" attribute is used to control conversion of a list of
3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * numbers into a string.
3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "format" attribute.
3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public AVT getFormat()
3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_format_avt;
3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * When numbering with an alphabetic sequence, the lang attribute
3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specifies which language's alphabet is to be used.
3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private AVT m_lang_avt = null;
3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "lang" attribute.
3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * When numbering with an alphabetic sequence, the lang attribute
3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specifies which language's alphabet is to be used; it has the same
3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * range of values as xml:lang [XML]; if no lang value is specified,
3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the language should be determined from the system environment.
3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implementers should document for which languages they support numbering.
3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "lang" attribute.
3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setLang(AVT v)
3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_lang_avt = v;
3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "lang" attribute.
3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * When numbering with an alphabetic sequence, the lang attribute
3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * specifies which language's alphabet is to be used; it has the same
3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * range of values as xml:lang [XML]; if no lang value is specified,
3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * the language should be determined from the system environment.
3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Implementers should document for which languages they support numbering.
3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value ofr "lang" attribute.
3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public AVT getLang()
3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_lang_avt;
3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The letter-value attribute disambiguates between numbering
3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * sequences that use letters.
3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private AVT m_lettervalue_avt = null;
3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "letter-value" attribute.
3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The letter-value attribute disambiguates between numbering sequences
3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that use letters.
3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "letter-value" attribute.
3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setLetterValue(AVT v)
3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_lettervalue_avt = v;
3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "letter-value" attribute.
4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The letter-value attribute disambiguates between numbering sequences
4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * that use letters.
4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value to set for "letter-value" attribute.
4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public AVT getLetterValue()
4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_lettervalue_avt;
4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The grouping-separator attribute gives the separator
4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * used as a grouping (e.g. thousands) separator in decimal
4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * numbering sequences.
4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private AVT m_groupingSeparator_avt = null;
4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "grouping-separator" attribute.
4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The grouping-separator attribute gives the separator
4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * used as a grouping (e.g. thousands) separator in decimal
4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * numbering sequences.
4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "grouping-separator" attribute.
4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setGroupingSeparator(AVT v)
4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_groupingSeparator_avt = v;
4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "grouping-separator" attribute.
4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The grouping-separator attribute gives the separator
4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * used as a grouping (e.g. thousands) separator in decimal
4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * numbering sequences.
4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "grouping-separator" attribute.
4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public AVT getGroupingSeparator()
4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_groupingSeparator_avt;
4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optional grouping-size specifies the size (normally 3) of the grouping.
4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @serial
4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private AVT m_groupingSize_avt = null;
4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Set the "grouping-size" attribute.
4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optional grouping-size specifies the size (normally 3) of the grouping.
4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param v Value to set for "grouping-size" attribute.
4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void setGroupingSize(AVT v)
4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    m_groupingSize_avt = v;
4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the "grouping-size" attribute.
4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * The optional grouping-size specifies the size (normally 3) of the grouping.
4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see <a href="http://www.w3.org/TR/xslt#convert">convert in XSLT Specification</a>
4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Value of "grouping-size" attribute.
4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public AVT getGroupingSize()
4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return m_groupingSize_avt;
4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Shouldn't this be in the transformer?  Big worries about threads...
4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  // private XResourceBundle thisBundle;
4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Table to help in converting decimals to roman numerals.
4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.apache.xalan.transformer.DecimalToRoman
4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private final static DecimalToRoman m_romanConvertTable[] = {
4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(1000, "M", 900, "CM"),
4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(500, "D", 400, "CD"),
4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(100L, "C", 90L, "XC"),
4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(50L, "L", 40L, "XL"),
4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(10L, "X", 9L, "IX"),
4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(5L, "V", 4L, "IV"),
4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    new DecimalToRoman(1L, "I", 1L, "I") };
4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This function is called after everything else has been
4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * recomposed, and allows the template to set remaining
4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * values that may be based on some other property that
5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * depends on recomposition.
5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void compose(StylesheetRoot sroot) throws TransformerException
5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super.compose(sroot);
5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StylesheetRoot.ComposeState cstate = sroot.getComposeState();
5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    java.util.Vector vnames = cstate.getVariableNames();
5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_countMatchPattern)
5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_countMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_format_avt)
5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_format_avt.fixupVariables(vnames, cstate.getGlobalsSize());
5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_fromMatchPattern)
5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_fromMatchPattern.fixupVariables(vnames, cstate.getGlobalsSize());
5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_groupingSeparator_avt)
5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_groupingSeparator_avt.fixupVariables(vnames, cstate.getGlobalsSize());
5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_groupingSize_avt)
5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_groupingSize_avt.fixupVariables(vnames, cstate.getGlobalsSize());
5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_lang_avt)
5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_lang_avt.fixupVariables(vnames, cstate.getGlobalsSize());
5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_lettervalue_avt)
5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_lettervalue_avt.fixupVariables(vnames, cstate.getGlobalsSize());
5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if(null != m_valueExpr)
5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      m_valueExpr.fixupVariables(vnames, cstate.getGlobalsSize());
5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get an int constant identifying the type of element.
5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see org.apache.xalan.templates.Constants
5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The token ID for this element
5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getXSLToken()
5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return Constants.ELEMNAME_NUMBER;
5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Return the node name.
5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The element's name
5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public String getNodeName()
5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return Constants.ELEMNAME_NUMBER_STRING;
5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Execute an xsl:number instruction. The xsl:number element is
5499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * used to insert a formatted number into the result tree.
5509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param transformer non-null reference to the the current transform-time state.
5529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
5549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void execute(
5569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          TransformerImpl transformer)
5579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException
5589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int sourceNode = transformer.getXPathContext().getCurrentNode();
5619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String countString = getCountString(transformer, sourceNode);
5629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
5649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      transformer.getResultTreeHandler().characters(countString.toCharArray(),
5669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                                    0, countString.length());
5679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    catch(SAXException se)
5699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
5709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      throw new TransformerException(se);
5719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
5729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Add a child to the child list.
5769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param newChild Child to add to child list
5789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Child just added to child list
5809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws DOMException
5829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
5839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public ElemTemplateElement appendChild(ElemTemplateElement newChild)
5849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
5859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    error(XSLTErrorResources.ER_CANNOT_ADD,
5879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          new Object[]{ newChild.getNodeName(),
5889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        this.getNodeName() });  //"Can not add " +((ElemTemplateElement)newChild).m_elemName +
5899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //" to " + this.m_elemName);
5919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return null;
5929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
5939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
5949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
5959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a 'from' pattern (ala xsl:number), a match pattern
5969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and a context, find the first ancestor that matches the
5979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * pattern (including the context handed in).
5989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
5999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The XPath runtime state for this.
6009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param fromMatchPattern The ancestor must match this pattern.
6019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param countMatchPattern The ancestor must also match this pattern.
6029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param context The node that "." expresses.
6039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param namespaceContext The context in which namespaces in the
6049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * queries are supposed to be expanded.
6059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the first ancestor that matches the given pattern
6079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
6099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  int findAncestor(
6119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XPathContext xctxt, XPath fromMatchPattern, XPath countMatchPattern,
6129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int context, ElemNumber namespaceContext)
6139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
6149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTM dtm = xctxt.getDTM(context);
6169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (DTM.NULL != context)
6179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != fromMatchPattern)
6199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fromMatchPattern.getMatchScore(xctxt, context)
6219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                != XPath.MATCH_SCORE_NONE)
6229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          //context = null;
6259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
6269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != countMatchPattern)
6309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (countMatchPattern.getMatchScore(xctxt, context)
6329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                != XPath.MATCH_SCORE_NONE)
6339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
6359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      context = dtm.getParent(context);
6399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
6409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return context;
6429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
6439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
6459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given a 'from' pattern (ala xsl:number), a match pattern
6469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * and a context, find the first ancestor that matches the
6479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * pattern (including the context handed in).
6489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The XPath runtime state for this.
6499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param fromMatchPattern The ancestor must match this pattern.
6509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param countMatchPattern The ancestor must also match this pattern.
6519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param context The node that "." expresses.
6529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param namespaceContext The context in which namespaces in the
6539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * queries are supposed to be expanded.
6549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the first preceding, ancestor or self node that
6569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * matches the given pattern
6579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
6589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
6599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
6609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private int findPrecedingOrAncestorOrSelf(
6619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XPathContext xctxt, XPath fromMatchPattern, XPath countMatchPattern,
6629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int context, ElemNumber namespaceContext)
6639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
6649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
6659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTM dtm = xctxt.getDTM(context);
6669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (DTM.NULL != context)
6679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
6689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != fromMatchPattern)
6699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (fromMatchPattern.getMatchScore(xctxt, context)
6719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                != XPath.MATCH_SCORE_NONE)
6729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          context = DTM.NULL;
6749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
6769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != countMatchPattern)
6809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (countMatchPattern.getMatchScore(xctxt, context)
6829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                != XPath.MATCH_SCORE_NONE)
6839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
6849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
6859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
6869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int prevSibling = dtm.getPreviousSibling(context);
6899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (DTM.NULL == prevSibling)
6919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        context = dtm.getParent(context);
6939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
6949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
6959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
6969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
6979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Now go down the chain of children of this sibling
6989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        context = dtm.getLastChild(prevSibling);
6999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (context == DTM.NULL)
7019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          context = prevSibling;
7029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return context;
7069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the count match pattern, or a default value.
7109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param support The XPath runtime state for this.
7129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param contextNode The node that "." expresses.
7139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the count match pattern, or a default value.
7159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
7179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  XPath getCountMatchPattern(XPathContext support, int contextNode)
7199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws javax.xml.transform.TransformerException
7209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XPath countMatchPattern = m_countMatchPattern;
7239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTM dtm = support.getDTM(contextNode);
7249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null == countMatchPattern)
7259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      switch (dtm.getNodeType(contextNode))
7279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
7289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.ELEMENT_NODE :
7299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        MyPrefixResolver resolver;
7309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (dtm.getNamespaceURI(contextNode) == null) {
7329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             resolver =  new MyPrefixResolver(dtm.getNode(contextNode), dtm,contextNode, false);
7339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        } else {
7349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            resolver = new MyPrefixResolver(dtm.getNode(contextNode), dtm,contextNode, true);
7359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
7369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = new XPath(dtm.getNodeName(contextNode), this, resolver,
7389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                      XPath.MATCH, support.getErrorListener());
7399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.ATTRIBUTE_NODE :
7429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // countMatchPattern = m_stylesheet.createMatchPattern("@"+contextNode.getNodeName(), this);
7449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = new XPath("@" + dtm.getNodeName(contextNode), this,
7459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                      this, XPath.MATCH, support.getErrorListener());
7469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.CDATA_SECTION_NODE :
7489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.TEXT_NODE :
7499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // countMatchPattern = m_stylesheet.createMatchPattern("text()", this);
7519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = new XPath("text()", this, this, XPath.MATCH, support.getErrorListener());
7529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.COMMENT_NODE :
7549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // countMatchPattern = m_stylesheet.createMatchPattern("comment()", this);
7569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = new XPath("comment()", this, this, XPath.MATCH, support.getErrorListener());
7579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.DOCUMENT_NODE :
7599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // countMatchPattern = m_stylesheet.createMatchPattern("/", this);
7619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = new XPath("/", this, this, XPath.MATCH, support.getErrorListener());
7629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      case DTM.PROCESSING_INSTRUCTION_NODE :
7649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // countMatchPattern = m_stylesheet.createMatchPattern("pi("+contextNode.getNodeName()+")", this);
7669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = new XPath("pi(" + dtm.getNodeName(contextNode)
7679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                      + ")", this, this, XPath.MATCH, support.getErrorListener());
7689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
7699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      default :
7709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        countMatchPattern = null;
7719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
7729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
7739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return countMatchPattern;
7759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
7769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
7789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Given an XML source node, get the count according to the
7799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * parameters set up by the xsl:number attributes.
7809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param transformer non-null reference to the the current transform-time state.
7819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param sourceNode The source node being counted.
7829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The count of nodes
7849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
7859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
7869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
7879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  String getCountString(TransformerImpl transformer, int sourceNode)
7889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws TransformerException
7899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
7909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    long[] list = null;
7929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XPathContext xctxt = transformer.getXPathContext();
7939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    CountersTable ctable = transformer.getCountersTable();
7949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
7959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_valueExpr)
7969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
7979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XObject countObj = m_valueExpr.execute(xctxt, sourceNode, this);
7989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      //According to Errata E24
7999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      double d_count = java.lang.Math.floor(countObj.num()+ 0.5);
8009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (Double.isNaN(d_count)) return "NaN";
8019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (d_count < 0 && Double.isInfinite(d_count)) return "-Infinity";
8029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (Double.isInfinite(d_count)) return "Infinity";
8039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else if (d_count == 0) return "0";
8049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else{
8059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              long count = (long)d_count;
8069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              list = new long[1];
8079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              list[0] = count;
8089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
8119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (Constants.NUMBERLEVEL_ANY == m_level)
8139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        list = new long[1];
8159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        list[0] = ctable.countNode(xctxt, this, sourceNode);
8169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
8189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        NodeVector ancestors =
8209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          getMatchingAncestors(xctxt, sourceNode,
8219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                               Constants.NUMBERLEVEL_SINGLE == m_level);
8229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int lastIndex = ancestors.size() - 1;
8239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (lastIndex >= 0)
8259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          list = new long[lastIndex + 1];
8279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          for (int i = lastIndex; i >= 0; i--)
8299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
8309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            int target = ancestors.elementAt(i);
8319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            list[lastIndex - i] = ctable.countNode(xctxt, this, target);
8339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
8349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
8369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
8379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return (null != list)
8399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson           ? formatNumberList(transformer, list, sourceNode) : "";
8409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
8419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
8439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the previous node to be counted.
8449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The XPath runtime state for this.
8469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param pos The current node
8479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the previous node to be counted.
8499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
8509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
8519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
8529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getPreviousNode(XPathContext xctxt, int pos)
8539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws TransformerException
8549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
8559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XPath countMatchPattern = getCountMatchPattern(xctxt, pos);
8579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTM dtm = xctxt.getDTM(pos);
8589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (Constants.NUMBERLEVEL_ANY == m_level)
8609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
8619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XPath fromMatchPattern = m_fromMatchPattern;
8629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Do a backwards document-order walk 'till a node is found that matches
8649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // the 'from' pattern, or a node is found that matches the 'count' pattern,
8659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // or the top of the tree is found.
8669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != pos)
8679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
8689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Get the previous sibling, if there is no previous sibling,
8709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // then count the parent, but if there is a previous sibling,
8719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // dive down to the lowest right-hand (last) child of that sibling.
8729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int next = dtm.getPreviousSibling(pos);
8739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (DTM.NULL == next)
8759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          next = dtm.getParent(pos);
8779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if ((DTM.NULL != next) && ((((null != fromMatchPattern) && (fromMatchPattern.getMatchScore(
8799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  xctxt, next) != XPath.MATCH_SCORE_NONE)))
8809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              || (dtm.getNodeType(next) == DTM.DOCUMENT_NODE)))
8819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
8829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            pos = DTM.NULL;  // return null from function.
8839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            break;  // from while loop
8859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
8869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
8879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
8889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
8899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // dive down to the lowest right child.
8919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int child = next;
8929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          while (DTM.NULL != child)
8949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
8959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            child = dtm.getLastChild(next);
8969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
8979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (DTM.NULL != child)
8989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              next = child;
8999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
9009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        pos = next;
9039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((DTM.NULL != pos)
9059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && ((null == countMatchPattern)
9069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    || (countMatchPattern.getMatchScore(xctxt, pos)
9079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        != XPath.MATCH_SCORE_NONE)))
9089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
9109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else  // NUMBERLEVEL_MULTI or NUMBERLEVEL_SINGLE
9149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (DTM.NULL != pos)
9169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
9179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        pos = dtm.getPreviousSibling(pos);
9189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((DTM.NULL != pos)
9209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && ((null == countMatchPattern)
9219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    || (countMatchPattern.getMatchScore(xctxt, pos)
9229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                        != XPath.MATCH_SCORE_NONE)))
9239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
9249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
9259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
9269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
9279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return pos;
9309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the target node that will be counted..
9349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The XPath runtime state for this.
9369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param sourceNode non-null reference to the <a href="http://www.w3.org/TR/xslt#dt-current-node">current source node</a>.
9379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return the target node that will be counted
9399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
9419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public int getTargetNode(XPathContext xctxt, int sourceNode)
9439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws TransformerException
9449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int target = DTM.NULL;
9479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XPath countMatchPattern = getCountMatchPattern(xctxt, sourceNode);
9489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (Constants.NUMBERLEVEL_ANY == m_level)
9509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      target = findPrecedingOrAncestorOrSelf(xctxt, m_fromMatchPattern,
9529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                             countMatchPattern, sourceNode,
9539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                             this);
9549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
9569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      target = findAncestor(xctxt, m_fromMatchPattern, countMatchPattern,
9589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                            sourceNode, this);
9599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
9609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return target;
9629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
9639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
9659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the ancestors, up to the root, that match the
9669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * pattern.
9679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param xctxt The XPath runtime state for this.
9699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param node Count this node and it's ancestors.
9709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stopAtFirstFound Flag indicating to stop after the
9719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * first node is found (difference between level = single
9729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * or multiple)
9739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The number of ancestors that match the pattern.
9749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
9759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
9769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
9779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  NodeVector getMatchingAncestors(
9789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          XPathContext xctxt, int node, boolean stopAtFirstFound)
9799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
9809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
9819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    NodeSetDTM ancestors = new NodeSetDTM(xctxt.getDTMManager());
9839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XPath countMatchPattern = getCountMatchPattern(xctxt, node);
9849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DTM dtm = xctxt.getDTM(node);
9859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (DTM.NULL != node)
9879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
9889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((null != m_fromMatchPattern)
9899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && (m_fromMatchPattern.getMatchScore(xctxt, node)
9909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  != XPath.MATCH_SCORE_NONE))
9919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
9929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
9939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // The following if statement gives level="single" different
9949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // behavior from level="multiple", which seems incorrect according
9959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // to the XSLT spec.  For now we are leaving this in to replicate
9969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // the same behavior in XT, but, for all intents and purposes we
9979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // think this is a bug, or there is something about level="single"
9989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // that we still don't understand.
9999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (!stopAtFirstFound)
10009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
10019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == countMatchPattern)
10049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        System.out.println(
10059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          "Programmers error! countMatchPattern should never be null!");
10069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (countMatchPattern.getMatchScore(xctxt, node)
10089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              != XPath.MATCH_SCORE_NONE)
10099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ancestors.addElement(node);
10119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (stopAtFirstFound)
10139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
10149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      node = dtm.getParent(node);
10179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return ancestors;
10209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end getMatchingAncestors method
10219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the locale we should be using.
10249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param transformer non-null reference to the the current transform-time state.
10269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param contextNode The node that "." expresses.
10279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return The locale to use. May be specified by "lang" attribute,
10299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * but if not, use default locale on the system.
10309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
10329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  Locale getLocale(TransformerImpl transformer, int contextNode)
10349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          throws TransformerException
10359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Locale locale = null;
10389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (null != m_lang_avt)
10409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      XPathContext xctxt = transformer.getXPathContext();
10429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String langValue = m_lang_avt.evaluate(xctxt, contextNode, this);
10439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null != langValue)
10459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
10469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Not really sure what to do about the country code, so I use the
10489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // default from the system.
10499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // TODO: fix xml:lang handling.
10509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        locale = new Locale(langValue.toUpperCase(), "");
10519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        //Locale.getDefault().getDisplayCountry());
10539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null == locale)
10549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
10559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          transformer.getMsgMgr().warn(this, null, xctxt.getDTM(contextNode).getNode(contextNode),
10569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                       XSLTErrorResources.WG_LOCALE_NOT_FOUND,
10579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                       new Object[]{ langValue });  //"Warning: Could not find locale for xml:lang="+langValue);
10589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          locale = Locale.getDefault();
10609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
10619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
10629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
10649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
10659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      locale = Locale.getDefault();
10669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
10679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return locale;
10699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
10709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
10729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get the number formatter to be used the format the numbers
10739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param transformer non-null reference to the the current transform-time state.
10759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param contextNode The node that "." expresses.
10769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * ($objectName$) @return The number formatter to be used
10789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
10799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
10809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
10819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private DecimalFormat getNumberFormatter(
10829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          TransformerImpl transformer, int contextNode) throws TransformerException
10839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
10849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Patch from Steven Serocki
10859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Maybe we really want to do the clone in getLocale() and return
10869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // a clone of the default Locale??
10879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    Locale locale = (Locale)getLocale(transformer, contextNode).clone();
10889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Helper to format local specific numbers to strings.
10909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    DecimalFormat formatter = null;
10919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //synchronized (locale)
10939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //{
10949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //     formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale);
10959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //}
10969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
10979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String digitGroupSepValue =
10989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (null != m_groupingSeparator_avt)
10999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ? m_groupingSeparator_avt.evaluate(
11009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      transformer.getXPathContext(), contextNode, this) : null;
11019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Validate grouping separator if an AVT was used; otherwise this was
11049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // validated statically in XSLTAttributeDef.java.
11059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if ((digitGroupSepValue != null) && (!m_groupingSeparator_avt.isSimple()) &&
11069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        (digitGroupSepValue.length() != 1))
11079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            transformer.getMsgMgr().warn(
11099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               this, XSLTErrorResources.WG_ILLEGAL_ATTRIBUTE_VALUE,
11109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               new Object[]{ Constants.ATTRNAME_NAME, m_groupingSeparator_avt.getName()});
11119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String nDigitsPerGroupValue =
11159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (null != m_groupingSize_avt)
11169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ? m_groupingSize_avt.evaluate(
11179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      transformer.getXPathContext(), contextNode, this) : null;
11189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // TODO: Handle digit-group attributes
11209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if ((null != digitGroupSepValue) && (null != nDigitsPerGroupValue) &&
11219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Ignore if separation value is empty string
11229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        (digitGroupSepValue.length() > 0))
11239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
11259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatter = (DecimalFormat) NumberFormat.getNumberInstance(locale);
11279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatter.setGroupingSize(
11289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          Integer.valueOf(nDigitsPerGroupValue).intValue());
11299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
11319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        symbols.setGroupingSeparator(digitGroupSepValue.charAt(0));
11329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatter.setDecimalFormatSymbols(symbols);
11339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatter.setGroupingUsed(true);
11349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      catch (NumberFormatException ex)
11369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatter.setGroupingUsed(false);
11389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
11399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
11409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return formatter;
11429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
11439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
11459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Format a vector of numbers into a formatted string.
11469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param transformer non-null reference to the the current transform-time state.
11489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param list Array of one or more long integer numbers.
11499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param contextNode The node that "." expresses.
11509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String that represents list according to
11519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * %conversion-atts; attributes.
11529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * TODO: Optimize formatNumberList so that it caches the last count and
11539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * reuses that info for the next count.
11549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
11559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws TransformerException
11569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
11579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  String formatNumberList(
11589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          TransformerImpl transformer, long[] list, int contextNode)
11599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws TransformerException
11609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
11619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String numStr;
11639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    FastStringBuffer formattedNumber = StringBufferPool.get();
11649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    try
11669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
11679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nNumbers = list.length, numberWidth = 1;
11689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      char numberType = '1';
11699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String formatToken, lastSepString = null, formatTokenString = null;
11709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // If a seperator hasn't been specified, then use "."
11729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // as a default separator.
11739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // For instance: [2][1][5] with a format value of "1 "
11749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // should format to "2.1.5 " (I think).
11759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Otherwise, use the seperator specified in the format string.
11769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // For instance: [2][1][5] with a format value of "01-001. "
11779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // should format to "02-001-005 ".
11789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String lastSep = ".";
11799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      boolean isFirstToken = true;  // true if first token
11809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String formatValue =
11819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        (null != m_format_avt)
11829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ? m_format_avt.evaluate(
11839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        transformer.getXPathContext(), contextNode, this) : null;
11849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (null == formatValue)
11869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatValue = "1";
11879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      NumberFormatStringTokenizer formatTokenizer =
11899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        new NumberFormatStringTokenizer(formatValue);
11909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // int sepCount = 0;                  // keep track of seperators
11929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Loop through all the numbers in the list.
11939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int i = 0; i < nNumbers; i++)
11949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
11959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
11969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // Loop to the next digit, letter, or separator.
11979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (formatTokenizer.hasMoreTokens())
11989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
11999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          formatToken = formatTokenizer.nextToken();
12009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // If the first character of this token is a character or digit, then
12029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // it is a number format directive.
12039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (Character.isLetterOrDigit(
12049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  formatToken.charAt(formatToken.length() - 1)))
12059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
12069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            numberWidth = formatToken.length();
12079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            numberType = formatToken.charAt(numberWidth - 1);
12089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
12099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // If there is a number format directive ahead,
12119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // then append the formatToken.
12129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else if (formatTokenizer.isLetterOrDigitAhead())
12139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
12149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            formatTokenString = formatToken;
12159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Append the formatToken string...
12179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // For instance [2][1][5] with a format value of "1--1. "
12189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // should format to "2--1--5. " (I guess).
12199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (formatTokenizer.nextIsSep())
12209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
12219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              formatToken = formatTokenizer.nextToken();
12229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              formatTokenString += formatToken;
12239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
12249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Record this separator, so it can be used as the
12269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // next separator, if the next is the last.
12279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // For instance: [2][1][5] with a format value of "1-1 "
12289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // should format to "2-1-5 ".
12299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (!isFirstToken)
12309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              lastSep = formatTokenString;
12319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Since we know the next is a number or digit, we get it now.
12339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            formatToken = formatTokenizer.nextToken();
12349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            numberWidth = formatToken.length();
12359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            numberType = formatToken.charAt(numberWidth - 1);
12369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
12379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else  // only separators left
12389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
12399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // Set up the string for the trailing characters after
12419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // the last number is formatted (i.e. after the loop).
12429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            lastSepString = formatToken;
12439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            // And append any remaining characters to the lastSepString.
12459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            while (formatTokenizer.hasMoreTokens())
12469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
12479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              formatToken = formatTokenizer.nextToken();
12489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              lastSepString += formatToken;
12499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }
12509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }  // else
12519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }  // end if(formatTokenizer.hasMoreTokens())
12529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // if this is the first token and there was a prefix
12549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // append the prefix else, append the separator
12559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // For instance, [2][1][5] with a format value of "(1-1.) "
12569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // should format to "(2-1-5.) " (I guess).
12579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null != formatTokenString && isFirstToken)
12589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
12599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          formattedNumber.append(formatTokenString);
12609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
12619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (null != lastSep &&!isFirstToken)
12629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          formattedNumber.append(lastSep);
12639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        getFormattedNumber(transformer, contextNode, numberType, numberWidth,
12659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                           list[i], formattedNumber);
12669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        isFirstToken = false;  // After the first pass, this should be false
12689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }  // end for loop
12699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Check to see if we finished up the format string...
12719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // Skip past all remaining letters or digits
12729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (formatTokenizer.isLetterOrDigitAhead())
12739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatTokenizer.nextToken();
12759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (lastSepString != null)
12789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(lastSepString);
12799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (formatTokenizer.hasMoreTokens())
12819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
12829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formatToken = formatTokenizer.nextToken();
12839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(formatToken);
12859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
12869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      numStr = formattedNumber.toString();
12889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    finally
12909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
12919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      StringBufferPool.free(formattedNumber);
12929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
12939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return numStr;
12959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end formatNumberList method
12969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
12979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /*
12989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  * Get Formatted number
12999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  */
13009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
13029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Format the given number and store it in the given buffer
13039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param transformer non-null reference to the the current transform-time state.
13069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param contextNode The node that "." expresses.
13079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param numberType Type to format to
13089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param numberWidth Maximum length of formatted number
13099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param listElement Number to format
13109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param formattedNumber Buffer to store formatted number
13119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
13129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @throws javax.xml.transform.TransformerException
13139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
13149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  private void getFormattedNumber(
13159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          TransformerImpl transformer, int contextNode,
13169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          char numberType, int numberWidth, long listElement,
13179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          FastStringBuffer formattedNumber)
13189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            throws javax.xml.transform.TransformerException
13199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
13209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String letterVal =
13239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (m_lettervalue_avt != null)
13249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      ? m_lettervalue_avt.evaluate(
13259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      transformer.getXPathContext(), contextNode, this) : null;
13269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
13289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Wrapper of Chars for converting integers into alpha counts.
13299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
13309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    CharArrayWrapper alphaCountTable = null;
13319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    XResourceBundle thisBundle = null;
13339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    switch (numberType)
13359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 'A' :
13379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null == m_alphaCountTable){
13389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                thisBundle =
13399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  (XResourceBundle) XResourceBundle.loadResourceBundle(
13409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, getLocale(transformer, contextNode));
13419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_alphaCountTable = (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET);
13429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int2alphaCount(listElement, m_alphaCountTable, formattedNumber);
13449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
13459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 'a' :
13469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (null == m_alphaCountTable){
13479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                thisBundle =
13489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  (XResourceBundle) XResourceBundle.loadResourceBundle(
13499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, getLocale(transformer, contextNode));
13509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                m_alphaCountTable = (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET);
13519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
13529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      FastStringBuffer stringBuf = StringBufferPool.get();
13539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      try
13559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
13569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement, m_alphaCountTable, stringBuf);
13579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(
13589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          stringBuf.toString().toLowerCase(
13599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            getLocale(transformer, contextNode)));
13609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      finally
13629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
13639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        StringBufferPool.free(stringBuf);
13649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
13659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
13669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 'I' :
13679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      formattedNumber.append(long2roman(listElement, true));
13689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
13699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 'i' :
13709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      formattedNumber.append(
13719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        long2roman(listElement, true).toLowerCase(
13729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          getLocale(transformer, contextNode)));
13739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
13749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x3042 :
13759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
13789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "HA"));
13799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
13819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
13829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
13839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
13849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(
13859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int2singlealphaCount(
13869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            listElement,
13879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
13889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
13909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
13919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x3044 :
13929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
13939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
13959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "HI"));
13969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
13979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((letterVal != null)
13989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
13999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
14009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
14019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(
14029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int2singlealphaCount(
14039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            listElement,
14049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
14059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
14079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x30A2 :
14099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
14129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "A"));
14139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
14159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
14169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
14179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
14189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(
14199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int2singlealphaCount(
14209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            listElement,
14219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
14229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
14249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x30A4 :
14269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
14299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ja", "JP", "I"));
14309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
14329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
14339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
14349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
14359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(
14369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int2singlealphaCount(
14379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            listElement,
14389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET)));
14399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
14419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x4E00 :
14439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
14469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("zh", "CN"));
14479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
14499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
14509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
14519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
14529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
14539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
14549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
14559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
14569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
14579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
14599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x58F9 :
14619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
14649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("zh", "TW"));
14659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
14679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
14689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
14699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
14709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
14719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
14729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
14739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
14759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x0E51 :
14779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
14809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("th", ""));
14819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
14839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
14849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
14859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
14869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
14879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
14889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
14899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
14919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
14929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x05D0 :
14939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
14949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
14969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("he", ""));
14979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
14989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
14999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
15009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
15019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
15029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
15039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
15049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
15059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
15079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x10D0 :
15099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
15129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("ka", ""));
15139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
15159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
15169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
15179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
15189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
15199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
15209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
15219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
15239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x03B1 :
15259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
15289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("el", ""));
15299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
15319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
15329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
15339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
15349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
15359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
15369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
15379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
15399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    case 0x0430 :
15419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
15429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      thisBundle = (XResourceBundle) XResourceBundle.loadResourceBundle(
15449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        org.apache.xml.utils.res.XResourceBundle.LANG_BUNDLE_NAME, new Locale("cy", ""));
15459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (letterVal != null
15479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && letterVal.equals(Constants.ATTRVAL_TRADITIONAL))
15489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(tradAlphaCount(listElement, thisBundle));
15499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else  //if (m_lettervalue_avt != null && m_lettervalue_avt.equals(Constants.ATTRVAL_ALPHABETIC))
15509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int2alphaCount(listElement,
15519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       (CharArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_ALPHABET),
15529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                       formattedNumber);
15539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      break;
15559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    default :  // "1"
15579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      DecimalFormat formatter = getNumberFormatter(transformer, contextNode);
15589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String padString = formatter == null ? String.valueOf(0) : formatter.format(0);
15599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String numString = formatter == null ? String.valueOf(listElement) : formatter.format(listElement);
15609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int nPadding = numberWidth - numString.length();
15619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      for (int k = 0; k < nPadding; k++)
15639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
15649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        formattedNumber.append(padString);
15659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
15669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      formattedNumber.append(numString);
15689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
15699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
15709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Get a string value for zero, which is not really defined by the 1.0 spec,
15739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * thought I think it might be cleared up by the erreta.
15749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   String getZeroString()
15769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   {
15779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     return ""+0;
15789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   }
15799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
15819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Convert a long integer into alphabetic counting, in other words
15829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * count using the sequence A B C ... Z.
15839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param val Value to convert -- must be greater than zero.
15859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param table a table containing one character for each digit in the radix
15869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String representing alpha count of number.
15879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see TransformerImpl#DecimalToRoman
15889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
15899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note that the radix of the conversion is inferred from the size
15909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of the table.
15919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
15929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected String int2singlealphaCount(long val, CharArrayWrapper table)
15939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
15949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int radix = table.getLength();
15969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
15979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // TODO:  throw error on out of range input
15989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (val > radix)
15999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getZeroString();
16019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
16039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (new Character(table.getChar((int)val - 1))).toString();  // index into table is off one, starts at 0
16049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
16059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
16079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Convert a long integer into alphabetic counting, in other words
16089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * count using the sequence A B C ... Z AA AB AC.... etc.
16099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param val Value to convert -- must be greater than zero.
16119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param table a table containing one character for each digit in the radix
16129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param aTable Array of alpha characters representing numbers
16139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param stringBuf Buffer where to save the string representing alpha count of number.
16149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see TransformerImpl#DecimalToRoman
16169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
16179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note that the radix of the conversion is inferred from the size
16189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of the table.
16199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
16209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected void int2alphaCount(long val, CharArrayWrapper aTable,
16219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                                FastStringBuffer stringBuf)
16229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
16239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int radix = aTable.getLength();
16259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char[] table = new char[radix];
16269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // start table at 1, add last char at index 0. Reason explained above and below.
16289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int i;
16299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    for (i = 0; i < radix - 1; i++)
16319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      table[i + 1] = aTable.getChar(i);
16339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
16349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    table[0] = aTable.getChar(i);
16369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Create a buffer to hold the result
16389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // TODO:  size of the table can be detereined by computing
16399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // logs of the radix.  For now, we fake it.
16409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char buf[] = new char[100];
16419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //some languages go left to right(ie. english), right to left (ie. Hebrew),
16439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //top to bottom (ie.Japanese), etc... Handle them differently
16449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
16459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // next character to set in the buffer
16469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int charPos;
16479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    charPos = buf.length - 1;  // work backward through buf[]
16499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // index in table of the last character that we stored
16519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int lookupIndex = 1;  // start off with anything other than zero to make correction work
16529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //                                          Correction number
16549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
16559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //  Correction can take on exactly two values:
16569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
16579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //          0       if the next character is to be emitted is usual
16589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
16599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //      radix - 1
16609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //                  if the next char to be emitted should be one less than
16619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //                  you would expect
16629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
16639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // For example, consider radix 10, where 1="A" and 10="J"
16649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
16659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // In this scheme, we count: A, B, C ...   H, I, J (not A0 and certainly
16669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // not AJ), A1
16679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //
16689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // So, how do we keep from emitting AJ for 10?  After correctly emitting the
16699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // J, lookupIndex is zero.  We now compute a correction number of 9 (radix-1).
16709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // In the following line, we'll compute (val+correction) % radix, which is,
16719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // (val+9)/10.  By this time, val is 1, so we compute (1+9) % 10, which
16729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // is 10 % 10 or zero.  So, we'll prepare to emit "JJ", but then we'll
16739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // later suppress the leading J as representing zero (in the mod system,
16749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // it can represent either 10 or zero).  In summary, the correction value of
16759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // "radix-1" acts like "-1" when run through the mod operator, but with the
16769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // desireable characteristic that it never produces a negative number.
16779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    long correction = 0;
16789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // TODO:  throw error on out of range input
16809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    do
16819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
16829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // most of the correction calculation is explained above,  the reason for the
16849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // term after the "|| " is that it correctly propagates carries across
16859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // multiple columns.
16869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      correction =
16879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ((lookupIndex == 0) || (correction != 0 && lookupIndex == radix - 1))
16889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        ? (radix - 1) : 0;
16899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // index in "table" of the next char to emit
16919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      lookupIndex = (int)(val + correction) % radix;
16929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // shift input by one "column"
16949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      val = (val / radix);
16959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
16969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // if the next value we'd put out would be a leading zero, we're done.
16979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (lookupIndex == 0 && val == 0)
16989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        break;
16999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // put out the next character of output
17019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      buf[charPos--] = table[lookupIndex];  // left to right or top to bottom
17029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (val > 0);
17049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    stringBuf.append(buf, charPos + 1, (buf.length - charPos - 1));
17069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
17079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
17099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Convert a long integer into traditional alphabetic counting, in other words
17109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * count using the traditional numbering.
17119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
17129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param val Value to convert -- must be greater than zero.
17139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param thisBundle Resource bundle to use
17149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
17159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return String representing alpha count of number.
17169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see XSLProcessor#DecimalToRoman
17179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   *
17189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Note that the radix of the conversion is inferred from the size
17199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * of the table.
17209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
17219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected String tradAlphaCount(long val, XResourceBundle thisBundle)
17229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
17239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // if this number is larger than the largest number we can represent, error!
17259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (val > Long.MAX_VALUE)
17269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this.error(XSLTErrorResources.ER_NUMBER_TOO_BIG);
17289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return XSLTErrorResources.ERROR_STRING;
17299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
17309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char[] table = null;
17319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // index in table of the last character that we stored
17339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int lookupIndex = 1;  // start off with anything other than zero to make correction work
17349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Create a buffer to hold the result
17369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // TODO:  size of the table can be detereined by computing
17379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // logs of the radix.  For now, we fake it.
17389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    char buf[] = new char[100];
17399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //some languages go left to right(ie. english), right to left (ie. Hebrew),
17419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //top to bottom (ie.Japanese), etc... Handle them differently
17429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //String orientation = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_ORIENTATION);
17439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // next character to set in the buffer
17449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int charPos;
17459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    charPos = 0;  //start at 0
17479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // array of number groups: ie.1000, 100, 10, 1
17499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    IntArrayWrapper groups = (IntArrayWrapper) thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERGROUPS);
17509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // array of tables of hundreds, tens, digits...
17529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    StringArrayWrapper tables =
17539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      (StringArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_NUM_TABLES));
17549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //some languages have additive alphabetical notation,
17569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    //some multiplicative-additive, etc... Handle them differently.
17579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String numbering = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.LANG_NUMBERING);
17589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // do multiplicative part first
17609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (numbering.equals(org.apache.xml.utils.res.XResourceBundle.LANG_MULT_ADD))
17619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
17629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      String mult_order = thisBundle.getString(org.apache.xml.utils.res.XResourceBundle.MULT_ORDER);
17639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      LongArrayWrapper multiplier =
17649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        (LongArrayWrapper) (thisBundle.getObject(org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER));
17659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      CharArrayWrapper zeroChar = (CharArrayWrapper) thisBundle.getObject("zero");
17669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int i = 0;
17679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      // skip to correct multiplier
17699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (i < multiplier.getLength() && val < multiplier.getLong(i))
17709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
17719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        i++;
17729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
17739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
17759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
17769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (i >= multiplier.getLength())
17779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;  //number is smaller than multipliers
17789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // some languages (ie chinese) put a zero character (and only one) when
17809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // the multiplier is multiplied by zero. (ie, 1001 is 1X1000 + 0X100 + 0X10 + 1)
17819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // 0X100 is replaced by the zero character, we don't need one for 0X10
17829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (val < multiplier.getLong(i))
17839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
17849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (zeroChar.getLength() == 0)
17859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
17869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            i++;
17879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
17889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          else
17899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
17909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (buf[charPos - 1] != zeroChar.getChar(0))
17919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              buf[charPos++] = zeroChar.getChar(0);
17929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
17939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            i++;
17949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
17959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
17969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else if (val >= multiplier.getLong(i))
17979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
17989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          long mult = val / multiplier.getLong(i);
17999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          val = val % multiplier.getLong(i);  // save this.
18019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          int k = 0;
18039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          while (k < groups.getLength())
18059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
18069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            lookupIndex = 1;  // initialize for each table
18079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            if (mult / groups.getInt(k) <= 0)  // look for right table
18099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              k++;
18109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            else
18119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            {
18129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // get the table
18149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              CharArrayWrapper THEletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(k));
18159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              table = new char[THEletters.getLength() + 1];
18179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              int j;
18199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              for (j = 0; j < THEletters.getLength(); j++)
18219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              {
18229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                table[j + 1] = THEletters.getChar(j);
18239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              }
18249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              table[0] = THEletters.getChar(j - 1);  // don't need this
18269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // index in "table" of the next char to emit
18289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              lookupIndex = (int)mult / groups.getInt(k);
18299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              //this should not happen
18319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (lookupIndex == 0 && mult == 0)
18329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;
18339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              char multiplierChar = ((CharArrayWrapper) (thisBundle.getObject(
18359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                org.apache.xml.utils.res.XResourceBundle.LANG_MULTIPLIER_CHAR))).getChar(i);
18369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              // put out the next character of output
18389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              if (lookupIndex < table.length)
18399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              {
18409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                if (mult_order.equals(org.apache.xml.utils.res.XResourceBundle.MULT_PRECEDES))
18419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
18429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  buf[charPos++] = multiplierChar;
18439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  buf[charPos++] = table[lookupIndex];
18449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
18459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                else
18469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                {
18479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  // don't put out 1 (ie 1X10 is just 10)
18499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  if (lookupIndex == 1 && i == multiplier.getLength() - 1){}
18509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  else
18519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                    buf[charPos++] = table[lookupIndex];
18529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                  buf[charPos++] = multiplierChar;
18549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                }
18559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                break;  // all done!
18579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              }
18589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              else
18599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                return XSLTErrorResources.ERROR_STRING;
18609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            }  //end else
18619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }  // end while
18629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          i++;
18649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }  // end else if
18659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }  // end do while
18669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (i < multiplier.getLength());
18679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
18689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // Now do additive part...
18709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int count = 0;
18719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String tableName;
18729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // do this for each table of hundreds, tens, digits...
18749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    while (count < groups.getLength())
18759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
18769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (val / groups.getInt(count) <= 0)  // look for correct table
18779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        count++;
18789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
18799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
18809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        CharArrayWrapper theletters = (CharArrayWrapper) thisBundle.getObject(tables.getString(count));
18819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        table = new char[theletters.getLength() + 1];
18839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int j;
18859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // need to start filling the table up at index 1
18879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        for (j = 0; j < theletters.getLength(); j++)
18889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
18899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          table[j + 1] = theletters.getChar(j);
18909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
18919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        table[0] = theletters.getChar(j - 1);  // don't need this
18939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // index in "table" of the next char to emit
18959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        lookupIndex = (int)val / groups.getInt(count);
18969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
18979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // shift input by one "column"
18989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        val = val % groups.getInt(count);
18999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        // this should not happen
19019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (lookupIndex == 0 && val == 0)
19029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          break;
19039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (lookupIndex < table.length)
19059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          // put out the next character of output
19089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          buf[charPos++] = table[lookupIndex];  // left to right or top to bottom
19099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        else
19119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return XSLTErrorResources.ERROR_STRING;
19129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        count++;
19149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
19159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }  // end while
19169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    // String s = new String(buf, 0, charPos);
19189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return new String(buf, 0, charPos);
19199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
19209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Convert a long integer into roman numerals.
19239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param val Value to convert.
19249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param prefixesAreOK true_ to enable prefix notation (e.g. 4 = "IV"),
19259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * false_ to disable prefix notation (e.g. 4 = "IIII").
19269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @return Roman numeral string.
19279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see DecimalToRoman
19289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @see m_romanConvertTable
19299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  protected String long2roman(long val, boolean prefixesAreOK)
19319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (val <= 0)
19349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return getZeroString();
19369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    String roman = "";
19399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    int place = 0;
19409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    if (val <= 3999L)
19429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      do
19449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
19459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while (val >= m_romanConvertTable[place].m_postValue)
19469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          roman += m_romanConvertTable[place].m_postLetter;
19489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          val -= m_romanConvertTable[place].m_postValue;
19499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (prefixesAreOK)
19529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
19539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          if (val >= m_romanConvertTable[place].m_preValue)
19549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          {
19559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            roman += m_romanConvertTable[place].m_preLetter;
19569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson            val -= m_romanConvertTable[place].m_preValue;
19579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          }
19589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
19599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        place++;
19619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
19629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (val > 0);
19639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    else
19659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
19669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      roman = XSLTErrorResources.ERROR_STRING;
19679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
19689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    return roman;
19709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end long2roman
19719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
19739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * Call the children visitors.
19749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * @param visitor The visitor whose appropriate method will be called.
19759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
19769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  public void callChildVisitors(XSLTVisitor visitor, boolean callAttrs)
19779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
19789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	if(callAttrs)
19799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	{
19809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_countMatchPattern)
19819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_countMatchPattern.getExpression().callVisitors(m_countMatchPattern, visitor);
19829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_fromMatchPattern)
19839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_fromMatchPattern.getExpression().callVisitors(m_fromMatchPattern, visitor);
19849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_valueExpr)
19859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_valueExpr.getExpression().callVisitors(m_valueExpr, visitor);
19869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_format_avt)
19889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_format_avt.callVisitors(visitor);
19899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_groupingSeparator_avt)
19909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_groupingSeparator_avt.callVisitors(visitor);
19919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_groupingSize_avt)
19929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_groupingSize_avt.callVisitors(visitor);
19939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_lang_avt)
19949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_lang_avt.callVisitors(visitor);
19959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  	if(null != m_lettervalue_avt)
19969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson	  		m_lettervalue_avt.callVisitors(visitor);
19979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  	}
19989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
19999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    super.callChildVisitors(visitor, callAttrs);
20009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }
20019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  /**
20049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * This class returns tokens using non-alphanumberic
20059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   * characters as delimiters.
20069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson   */
20079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  class NumberFormatStringTokenizer
20089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  {
20099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Current position in the format string          */
20119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private int currentPosition;
20129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Index of last character in the format string      */
20149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private int maxPosition;
20159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /** Format string to be tokenized        */
20179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    private String str;
20189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
20209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Construct a NumberFormatStringTokenizer.
20219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
20229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @param str Format string to be tokenized
20239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
20249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public NumberFormatStringTokenizer(String str)
20259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      this.str = str;
20279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      maxPosition = str.length();
20289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
20319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Reset tokenizer so that nextToken() starts from the beginning.
20329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
20339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public void reset()
20349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      currentPosition = 0;
20369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
20399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Returns the next token from this string tokenizer.
20409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
20419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return     the next token from this string tokenizer.
20429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @throws  NoSuchElementException  if there are no more tokens in this
20439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *               tokenizer's string.
20449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
20459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public String nextToken()
20469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (currentPosition >= maxPosition)
20499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
20509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        throw new NoSuchElementException();
20519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
20529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int start = currentPosition;
20549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while ((currentPosition < maxPosition)
20569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson             && Character.isLetterOrDigit(str.charAt(currentPosition)))
20579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
20589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        currentPosition++;
20599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
20609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if ((start == currentPosition)
20629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson              && (!Character.isLetterOrDigit(str.charAt(currentPosition))))
20639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
20649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        currentPosition++;
20659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
20669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return str.substring(start, currentPosition);
20689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
20719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if there is a digit or a letter character ahead.
20729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
20739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return     true if there is a number or character ahead.
20749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
20759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean isLetterOrDigitAhead()
20769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int pos = currentPosition;
20799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (pos < maxPosition)
20819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
20829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if (Character.isLetterOrDigit(str.charAt(pos)))
20839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          return true;
20849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        pos++;
20869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
20879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return false;
20899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
20909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
20929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if there is a digit or a letter character ahead.
20939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
20949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return     true if there is a number or character ahead.
20959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
20969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean nextIsSep()
20979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
20989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
20999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      if (Character.isLetterOrDigit(str.charAt(currentPosition)))
21009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return false;
21019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      else
21029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        return true;
21039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
21069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Tells if <code>nextToken</code> will throw an exception
21079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * if it is called.
21089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
21099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return true if <code>nextToken</code> can be called
21109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * without throwing an exception.
21119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
21129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public boolean hasMoreTokens()
21139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
21149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return (currentPosition >= maxPosition) ? false : true;
21159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    /**
21189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * Calculates the number of times that this tokenizer's
21199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * <code>nextToken</code> method can be called before it generates an
21209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * exception.
21219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *
21229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @return  the number of tokens remaining in the string using the current
21239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     *          delimiter set.
21249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     * @see     java.util.StringTokenizer#nextToken()
21259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson     */
21269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    public int countTokens()
21279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    {
21289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int count = 0;
21309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      int currpos = currentPosition;
21319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      while (currpos < maxPosition)
21339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      {
21349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        int start = currpos;
21359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        while ((currpos < maxPosition)
21379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson               && Character.isLetterOrDigit(str.charAt(currpos)))
21389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
21399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          currpos++;
21409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
21419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        if ((start == currpos)
21439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson                && (Character.isLetterOrDigit(str.charAt(currpos)) == false))
21449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        {
21459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson          currpos++;
21469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        }
21479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson        count++;
21499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      }
21509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson      return count;
21529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson    }
21539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson  }  // end NumberFormatStringTokenizer
21549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson
21579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson}
2158