FileDocCategorySizeDatePackage
NodeCounter.javaAPI DocJava SE 5 API9705Fri Aug 26 14:55:40 BST 2005com.sun.org.apache.xalan.internal.xsltc.dom

NodeCounter

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

Fields Summary
public static final int
END
protected int
_node
protected int
_nodeType
protected int
_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 String[]
Thousands
private static String[]
Hundreds
private static String[]
Tens
private static String[]
Ones
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;
	final StringBuffer buffer = new StringBuffer();

	// 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;
	_format = format;
	_groupSep = groupSep;
	_letterValue = letterValue;

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

	final int length = _format.length();
	boolean isFirst = true;
	separFirst = true;
	separLast = false;

        separToks = new Vector();
        formatToks = new Vector();

	/* 
	 * 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 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.

public com.sun.org.apache.xalan.internal.xsltc.dom.NodeCountersetValue(int value)
If the user specified a value attribute, use this instead of counting nodes.

	_value = value;
	return this;