FileDocCategorySizeDatePackage
ELParser.javaAPI DocApache Tomcat 6.0.1410750Fri Jul 20 04:20:32 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 char
type
private boolean
escapeBS
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;
    
public chargetType()

        return type;
    
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* '}')* 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.type));
            }
        }
        return parser.expr;
    
private ELNode.NodesparseEL()
Parse an EL expression string '${...}'

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 ('${' || '#{') is reached, allowing escape sequences '\\' and '\$' 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.type = prev;
                    prev = 0;
                    break;
                }
                buf.append(prev);
                prev = 0;
            }
            if (ch == '\\" || ch == '$" || ch == '#") {
                prev = ch;
            } else {
                buf.append(ch);
            }
        }
        if (prev != 0) {
            buf.append(prev);
        }
        return buf.toString();