FileDocCategorySizeDatePackage
AttributeValueTemplate.javaAPI DocJava SE 5 API9830Fri Aug 26 14:55:34 BST 2005com.sun.org.apache.xalan.internal.xsltc.compiler

AttributeValueTemplate

public final class AttributeValueTemplate extends AttributeValue
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen

Fields Summary
static final int
OUT_EXPR
static final int
IN_EXPR
static final int
IN_EXPR_SQUOTES
static final int
IN_EXPR_DQUOTES
static final String
DELIMITER
Constructors Summary
public AttributeValueTemplate(String value, Parser parser, SyntaxTreeNode parent)

      // A Unicode nonchar

         
	  
    
	setParent(parent);
	setParser(parser);
        
        try {
            parseAVTemplate(value, parser);
        }
        catch (NoSuchElementException e) {
            reportError(parent, parser,
                        ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value);            
        }
    
Methods Summary
private voidparseAVTemplate(java.lang.String text, com.sun.org.apache.xalan.internal.xsltc.compiler.Parser parser)
Two-pass parsing of ATVs. In the first pass, double curly braces are replaced by one, and expressions are delimited using DELIMITER. The second pass splits up the resulting buffer into literal and non-literal expressions. Errors are reported during the first pass.

        StringTokenizer tokenizer = 
            new StringTokenizer(text, "{}\"\'", true);
        
        /*
          * First pass: replace double curly braces and delimit expressions
          * Simple automaton to parse ATVs, delimit expressions and report
          * errors.
          */
        String t = null;
        String lookahead = null;
        StringBuffer buffer = new StringBuffer();
        int state = OUT_EXPR;
        
        while (tokenizer.hasMoreTokens()) {            
            // Use lookahead if available
            if (lookahead != null) {
                t = lookahead;
                lookahead = null;
            }
            else {
                t = tokenizer.nextToken();
            }
            
            if (t.length() == 1) {
                switch (t.charAt(0)) {
                    case '{":
                        switch (state) {
                            case OUT_EXPR:
                                lookahead = tokenizer.nextToken();
                                if (lookahead.equals("{")) {
                                    buffer.append(lookahead);    // replace {{ by {
                                    lookahead = null;
                                }
                                else {
                                    buffer.append(DELIMITER);
                                    state = IN_EXPR;                                    
                                }
                                break;
                            case IN_EXPR:
                            case IN_EXPR_SQUOTES:
                            case IN_EXPR_DQUOTES:
                                reportError(getParent(), parser,
                                            ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text);
                                break;
                        }                                                
                        break;
                    case '}":
                        switch (state) {
                            case OUT_EXPR:
                                lookahead = tokenizer.nextToken();
                                if (lookahead.equals("}")) {
                                    buffer.append(lookahead);    // replace }} by }
                                    lookahead = null;
                                }
                                else {
                                    reportError(getParent(), parser,
                                            ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text);
                                }
                                break;
                            case IN_EXPR:
                                buffer.append(DELIMITER);
                                state = OUT_EXPR;
                                break;
                            case IN_EXPR_SQUOTES:
                            case IN_EXPR_DQUOTES:
                                buffer.append(t);
                                break;
                        }
                        break;
                    case '\'":
                        switch (state) {
                            case IN_EXPR:
                                state = IN_EXPR_SQUOTES;
                                break;
                            case IN_EXPR_SQUOTES:
                                state = IN_EXPR;
                                break;
                            case OUT_EXPR:
                            case IN_EXPR_DQUOTES:
                                break;
                        }
                        buffer.append(t);
                        break;
                    case '\"":
                        switch (state) {
                            case IN_EXPR:
                                state = IN_EXPR_DQUOTES;
                                break;
                            case IN_EXPR_DQUOTES:
                                state = IN_EXPR;
                                break;
                            case OUT_EXPR:
                            case IN_EXPR_SQUOTES:
                                break;
                        }
                        buffer.append(t);
                        break;
                    default:
                        buffer.append(t);
                        break;
                }
            }
            else {
                buffer.append(t);
            }
        }

        // Must be in OUT_EXPR at the end of parsing
        if (state != OUT_EXPR) {
            reportError(getParent(), parser,
                        ErrorMsg.ATTR_VAL_TEMPLATE_ERR, text);
        }
        
        /*
          * Second pass: split up buffer into literal and non-literal expressions.
          */
        tokenizer = new StringTokenizer(buffer.toString(), DELIMITER, true);
        
        while (tokenizer.hasMoreTokens()) {
            t = tokenizer.nextToken();
            
            if (t.equals(DELIMITER)) {
		addElement(parser.parseExpression(this, tokenizer.nextToken()));
                tokenizer.nextToken();      // consume other delimiter
            }
            else {
		addElement(new LiteralExpr(t)); 
            }
        }               
    
public java.lang.StringtoString()

	final StringBuffer buffer = new StringBuffer("AVT:[");
	final int count = elementCount();
	for (int i = 0; i < count; i++) {
	    buffer.append(elementAt(i).toString());
	    if (i < count - 1)
		buffer.append(' ");
	}
	return buffer.append(']").toString();
    
public voidtranslate(com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator classGen, com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator methodGen)

	if (elementCount() == 1) {
	    final Expression exp = (Expression)elementAt(0);
	    exp.translate(classGen, methodGen);
	}
	else {
	    final ConstantPoolGen cpg = classGen.getConstantPool();
	    final InstructionList il = methodGen.getInstructionList();
	    final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS,
						    "<init>", "()V");
	    final Instruction append =
		new INVOKEVIRTUAL(cpg.addMethodref(STRING_BUFFER_CLASS,
						   "append",
						   "(" + STRING_SIG + ")"
						   + STRING_BUFFER_SIG));
	    
	    final int toString = cpg.addMethodref(STRING_BUFFER_CLASS,
						  "toString",
						  "()"+STRING_SIG);
	    il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS)));
	    il.append(DUP);
	    il.append(new INVOKESPECIAL(initBuffer));
	    // StringBuffer is on the stack
	    final Enumeration elements = elements();
	    while (elements.hasMoreElements()) {
		final Expression exp = (Expression)elements.nextElement();
		exp.translate(classGen, methodGen);
		il.append(append);
	    }
	    il.append(new INVOKEVIRTUAL(toString));
	}
    
public com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypetypeCheck(com.sun.org.apache.xalan.internal.xsltc.compiler.SymbolTable stable)

	final Vector contents = getContents();
	final int n = contents.size();
	for (int i = 0; i < n; i++) {
	    final Expression exp = (Expression)contents.elementAt(i);
	    if (!exp.typeCheck(stable).identicalTo(Type.String)) {
		contents.setElementAt(new CastExpr(exp, Type.String), i);
	    }
	}
	return _type = Type.String;