FileDocCategorySizeDatePackage
NodeCounter.javaAPI DocJava SE 6 API10705Tue Jun 10 00:22:32 BST 2008com.sun.org.apache.xalan.internal.xsltc.dom

NodeCounter

public abstract class NodeCounter extends Object
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen
author
Morten Jorgensen

Fields Summary
public static final int
END
protected int
_node
protected int
_nodeType
protected double
_value
public final DOM
_document
public final DTMAxisIterator
_iterator
public final Translet
_translet
protected String
_format
protected String
_lang
protected String
_letterValue
protected String
_groupSep
protected int
_groupSize
private boolean
_separFirst
private boolean
_separLast
private Vector
_separToks
private Vector
_formatToks
private int
_nSepars
private int
_nFormats
private static final String[]
Thousands
private static final String[]
Hundreds
private static final String[]
Tens
private static final String[]
Ones
private StringBuffer
_tempBuffer
Constructors Summary
protected NodeCounter(Translet translet, DOM document, DTMAxisIterator iterator)

    
      
                  
    _translet = translet;
    _document = document;
    _iterator = iterator;
    
Methods Summary
private java.lang.StringalphaValue(int value, int min, int max)

        if (value <= 0) {
        return "" + value;
    }

        int range = max - min + 1;
        char last = (char)(((value-1) % range) + min);
        if (value > range) {
            return alphaValue((value-1) / range, min, max) + last;
        } 
    else {
            return "" + last;
        }
    
protected java.lang.StringformatNumbers(int value)
Format a single value according to the format parameters.

    return formatNumbers(new int[] { value });
    
protected java.lang.StringformatNumbers(int[] values)
Format a sequence of values according to the format paramaters set by calling setFormatting().

    final int nValues = values.length;
    final int length = _format.length();

    boolean isEmpty = true;
    for (int i = 0; i < nValues; i++)
        if (values[i] != Integer.MIN_VALUE)
        isEmpty = false;
    if (isEmpty) return("");

    // Format the output string using the values array and the fmt. tokens
    boolean isFirst = true;
    int t = 0, n = 0, s = 1;
  _tempBuffer.setLength(0);
    final StringBuffer buffer = _tempBuffer;

    // Append separation token before first digit/letter/numeral
    if (_separFirst) buffer.append((String)_separToks.elementAt(0));

    // Append next digit/letter/numeral and separation token
    while (n < nValues) {
        final int value = values[n];
        if (value != Integer.MIN_VALUE) {
        if (!isFirst) buffer.append((String) _separToks.elementAt(s++));
        formatValue(value, (String)_formatToks.elementAt(t++), buffer);
        if (t == _nFormats) t--;
        if (s >= _nSepars) s--;
        isFirst = false;
        }
        n++;
    }

    // Append separation token after last digit/letter/numeral
    if (_separLast) buffer.append((String)_separToks.lastElement());
    return buffer.toString();
    
private voidformatValue(int value, java.lang.String format, java.lang.StringBuffer buffer)
Format a single value based on the appropriate formatting token. This method is based on saxon (Michael Kay) and only implements lang="en".

        char c = format.charAt(0);

        if (Character.isDigit(c)) {
            char zero = (char)(c - Character.getNumericValue(c));

            StringBuffer temp = buffer;
            if (_groupSize > 0) {
                temp = new StringBuffer();
            }
            String s = "";
            int n = value;
            while (n > 0) {
                s = (char) ((int) zero + (n % 10)) + s;
                n = n / 10;
            }
                
            for (int i = 0; i < format.length() - s.length(); i++) {
                temp.append(zero);
            }
            temp.append(s);
            
            if (_groupSize > 0) {
                for (int i = 0; i < temp.length(); i++) {
                    if (i != 0 && ((temp.length() - i) % _groupSize) == 0) {
                        buffer.append(_groupSep);
                    }
                    buffer.append(temp.charAt(i));
                }
            }
        } 
    else if (c == 'i" && !_letterValue.equals("alphabetic")) {
            buffer.append(romanValue(value));
        } 
    else if (c == 'I" && !_letterValue.equals("alphabetic")) {
            buffer.append(romanValue(value).toUpperCase());
        } 
    else {
        int min = (int) c;
        int max = (int) c;

        // Special case for Greek alphabet 
        if (c >= 0x3b1 && c <= 0x3c9) {
        max = 0x3c9;    // omega
        }
        else {
        // General case: search for end of group
        while (Character.isLetterOrDigit((char) (max + 1))) {
            max++;
        }
        }
            buffer.append(alphaValue(value, min, max));
        }
    
public abstract java.lang.StringgetCounter()
Returns the position of node according to the level and the from and count patterns.

public java.lang.StringgetCounter(java.lang.String format, java.lang.String lang, java.lang.String letterValue, java.lang.String groupSep, java.lang.String groupSize)
Returns the position of node according to the level and the from and count patterns. This position is converted into a string based on the arguments passed.

    setFormatting(format, lang, letterValue, groupSep, groupSize);
    return getCounter();
    
public booleanmatchesCount(int node)
Returns true if node matches the count pattern. By default a node matches the count patterns if it is of the same type as the starting node.

    return _nodeType == _document.getExpandedTypeID(node);
    
public booleanmatchesFrom(int node)
Returns true if node matches the from pattern. By default, no node matches the from pattern.

    return false;
    
private java.lang.StringromanValue(int n)

        if (n <= 0 || n > 4000) {
        return "" + n;
    }
        return
        Thousands[n / 1000] +
        Hundreds[(n / 100) % 10] +
        Tens[(n/10) % 10] +
        Ones[n % 10];
    
public com.sun.org.apache.xalan.internal.xsltc.dom.NodeCountersetDefaultFormatting()
Sets formatting fields to their default values.

    setFormatting("1", "en", "alphabetic", null, null);
    return this;
    
protected voidsetFormatting(java.lang.String format, java.lang.String lang, java.lang.String letterValue, java.lang.String groupSep, java.lang.String groupSize)
Sets formatting fields before calling formatNumbers().

    _lang = lang;
    _groupSep = groupSep;
    _letterValue = letterValue;

    try {
        _groupSize = Integer.parseInt(groupSize);
    }
    catch (NumberFormatException e) {
       _groupSize = 0;
    }
    setTokens(format);

 
public abstract com.sun.org.apache.xalan.internal.xsltc.dom.NodeCountersetStartNode(int node)
Set the start node for this counter. The same NodeCounter object can be used multiple times by resetting the starting node.

private final voidsetTokens(java.lang.String format)

     if( (_format!=null) &&(format.equals(_format)) ){// has already been set
        return;
     }
     _format = format;
     // reset
     final int length = _format.length();
     boolean isFirst = true;
     _separFirst = true;
     _separLast = false;
     _nSepars  = 0;
     _nFormats = 0;
     _separToks.clear() ;
     _formatToks.clear();

         /* 
          * Tokenize the format string into alphanumeric and non-alphanumeric
          * tokens as described in M. Kay page 241.
          */
         for (int j = 0, i = 0; i < length;) {
                 char c = format.charAt(i);
                 for (j = i; Character.isLetterOrDigit(c);) {
                     if (++i == length) break;
             c = format.charAt(i);
                 }
                 if (i > j) {
                     if (isFirst) {
                         _separToks.addElement(".");
                         isFirst = _separFirst = false;
                     }
                     _formatToks.addElement(format.substring(j, i));
                 }

                 if (i == length) break;

                 c = format.charAt(i);
                 for (j = i; !Character.isLetterOrDigit(c);) {
                     if (++i == length) break;
                     c = format.charAt(i);
                     isFirst = false;
                 }
                 if (i > j) {
                     _separToks.addElement(format.substring(j, i));
                 }
             }

         _nSepars = _separToks.size();
         _nFormats = _formatToks.size(); 
         if (_nSepars > _nFormats) _separLast = true;

         if (_separFirst) _nSepars--;
         if (_separLast) _nSepars--;
         if (_nSepars == 0) {
             _separToks.insertElementAt(".", 1);
             _nSepars++;
         }
         if (_separFirst) _nSepars ++;
 
 
public com.sun.org.apache.xalan.internal.xsltc.dom.NodeCountersetValue(double value)
If the user specified a value attribute, use this instead of counting nodes.

    _value = value;
    return this;