FileDocCategorySizeDatePackage
ELParser.javaAPI DocGlassfish v2 API9928Fri May 04 22:32:52 BST 2007org.apache.jasper.compiler

ELParser

public class ELParser extends Object
This class implements a parser for EL expressions. It takes strings of the form xxx${..}yyy${..}zzz etc, and turn it into a ELNode.Nodes. Currently, it only handles text outside ${..} and functions in ${ ..}.
author
Kin-man Chung

Fields Summary
private Token
curToken
private ELNode.Nodes
expr
private ELNode.Nodes
ELexpr
private int
index
private String
expression
private boolean
escapeBS
private boolean
isDollarExpr
private static final String[]
reservedWords
Constructors Summary
public ELParser(String expression)


       
	index = 0;
	this.expression = expression;
	expr = new ELNode.Nodes();
    
Methods Summary
private intgetIndex()

	return index;
    
private booleanhasNext()

	skipSpaces();
	return hasNextChar();
    
private booleanhasNextChar()

	return index < expression.length();
    
private booleanisELReserved(java.lang.String id)
Test if an id is a reserved word in EL

        int i = 0;
        int j = reservedWords.length;
        while (i < j) {
            int k = (i+j)/2;
            int result = reservedWords[k].compareTo(id);
            if (result == 0) {
                return true;
            }
            if (result < 0) {
                i = k+1;
            } else {
                j = k;
            }
        }
        return false;
    
private charnextChar()

	if (index >= expression.length()) {
	    return (char)-1;
	}
	return expression.charAt(index++);
    
private org.apache.jasper.compiler.ELParser$TokennextToken()

	skipSpaces();
	if (hasNextChar()) {
	    char ch = nextChar();
	    if (Character.isJavaIdentifierStart(ch)) {
		StringBuffer buf = new StringBuffer();
		buf.append(ch);
		while ((ch = peekChar()) != -1 &&
				Character.isJavaIdentifierPart(ch)) {
		    buf.append(ch);
		    nextChar();
		}
		return new Id(buf.toString());
	    }

	    if (ch == '\'" || ch == '"") {
		return parseQuotedChars(ch);
	    } else {
		// For now...
		return new Char(ch);
	    }
	}
	return null;
    
public static ELNode.Nodesparse(java.lang.String expression)
Parse an EL expression

param
expression The input expression string of the form ( (Char* | (('${' | '#{') Char* '}') )+
return
Parsed EL expression in ELNode.Nodes

	ELParser parser = new ELParser(expression);
	while (parser.hasNextChar()) {
	    String text = parser.skipUntilEL();
	    if (text.length() > 0) {
		parser.expr.add(new ELNode.Text(text));
	    }
	    ELNode.Nodes elexpr = parser.parseEL();
	    if (! elexpr.isEmpty()) {
		parser.expr.add(new ELNode.Root(elexpr, parser.isDollarExpr));
	    }
	}
	return parser.expr;
    
private ELNode.NodesparseEL()
Parse an EL expression string '${...} or #{...}'

return
An ELNode.Nodes representing the EL expression TODO: Currently only parsed into functions and text strings. This should be rewritten for a full parser.


	StringBuffer buf = new StringBuffer();
	ELexpr = new ELNode.Nodes();
	while (hasNext()) {
	    curToken = nextToken();
	    if (curToken instanceof Char) {
		if (curToken.toChar() == '}") {
		    break;
		}
		buf.append(curToken.toChar());
	    } else {
		// Output whatever is in buffer
		if (buf.length() > 0) {
		    ELexpr.add(new ELNode.ELText(buf.toString()));
		}
		if (!parseFunction()) {
		    ELexpr.add(new ELNode.ELText(curToken.toString()));
		}
	    }
	}
	if (buf.length() > 0) {
	    ELexpr.add(new ELNode.ELText(buf.toString()));
	}

	return ELexpr;
    
private booleanparseFunction()
Parse for a function FunctionInvokation ::= (identifier ':')? identifier '(' (Expression (,Expression)*)? ')' Note: currently we don't parse arguments

	if (! (curToken instanceof Id) || isELReserved(curToken.toString())) {
	    return false;
	}
	String s1 = null;                 // Function prefix
	String s2 = curToken.toString();  // Function name
	int mark = getIndex();
	if (hasNext()) {
	    Token t = nextToken();
	    if (t.toChar() == ':") {
		if (hasNext()) {
		    Token t2 = nextToken();
		    if (t2 instanceof Id) {
			s1 = s2;
			s2 = t2.toString();
			if (hasNext()) {
			    t = nextToken();
			}
		    }
		}
	    }
	    if (t.toChar() == '(") {
		ELexpr.add(new ELNode.Function(s1, s2));
		return true;
	    }
	}
	setIndex(mark);
	return false;
    
private org.apache.jasper.compiler.ELParser$TokenparseQuotedChars(char quote)

	StringBuffer buf = new StringBuffer();
	buf.append(quote);
	while (hasNextChar()) {
	    char ch = nextChar();
	    if (ch == '\\") {
		ch = nextChar();
		if (ch == '\\" || ch == quote) {
		    buf.append(ch);
		}
		// else error!
	    } else if (ch == quote) {
		buf.append(ch);
		break;
	    } else {
		buf.append(ch);
	    }
	}
	return new QuotedString(buf.toString());
    
private charpeekChar()

	if (index >= expression.length()) {
	    return (char)-1;
	}
	return expression.charAt(index);
    
private voidsetIndex(int i)

	index = i;
    
private voidskipSpaces()

	while (hasNextChar()) {
	    if (expression.charAt(index) > ' ")
		break;
	    index++;
	}
    
private java.lang.StringskipUntilEL()
Skip until an EL expression ('${' or '#{') is reached, allowing escape sequences '\\', '\$', and '\#'.

return
The text string up to the EL expression

	char prev = 0;
	StringBuffer buf = new StringBuffer();
	while (hasNextChar()) {
	    char ch = nextChar();
	    if (prev == '\\") {
		prev = 0;
		if (ch == '\\") {
		    buf.append('\\");
		    if (!escapeBS)
			prev = '\\";
		} else if (ch == '$" || ch == '#") {
		    buf.append(ch);
		}
		// else error!
	    } else if (prev == '$" || prev == '#") {
		if (ch == '{") {
                    this.isDollarExpr = (prev == '$");
		    prev = 0;
		    break;
		} 
		buf.append(prev);
                if (ch == '\\" || ch == '$" || ch == '#") {
                    prev = ch;
                } else {
                    buf.append(ch);
                }
	    } else if (ch == '\\" || ch == '$" || ch == '#") {
		prev = ch;
	    } else {
		buf.append(ch);
	    }
	}
	if (prev != 0) {
	    buf.append(prev);
	}
	return buf.toString();