Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.apache.jasper.compiler;
 
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(s):
Kin-man Chung
 
 
 public class ELParser {
 
     private Token curToken;  // current token
     private Token prevToken// previous token
     private String whiteSpace = "";
 
     private final ELNode.Nodes expr;
 
     private ELNode.Nodes ELexpr;
 
     private int index// Current index of the expression
 
     private final String expression// The EL expression
 
     private char type;
 
     private final boolean isDeferredSyntaxAllowedAsLiteral;
 
     private static final String reservedWords[] = { "and""div""empty",
             "eq""false""ge""gt""instanceof""le""lt""mod""ne",
             "not""null""or""true" };
 
     public ELParser(String expressionboolean isDeferredSyntaxAllowedAsLiteral) {
          = 0;
         this. = expression;
         this. = isDeferredSyntaxAllowedAsLiteral;
          = new ELNode.Nodes();
     }

    
Parse an EL expression

Parameters:
expression The input expression string of the form Char* ('${' Char* '}')* Char*
isDeferredSyntaxAllowedAsLiteral Are deferred expressions treated as literals?
Returns:
Parsed EL expression in ELNode.Nodes
 
     public static ELNode.Nodes parse(String expression,
             boolean isDeferredSyntaxAllowedAsLiteral) {
         ELParser parser = new ELParser(expression,
                 isDeferredSyntaxAllowedAsLiteral);
         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(elexprparser.type));
             }
         }
         return parser.expr;
     }

    
Parse an EL expression string '${...}'. Currently only separates the EL into functions and everything else.

Returns:
An ELNode.Nodes representing the EL expression Note: This can not be refactored to use the standard EL implementation as the EL API does not provide the level of access required to the parsed expression.
    private ELNode.Nodes parseEL() {
        StringBuilder buf = new StringBuilder();
         = new ELNode.Nodes();
         = null;
         = null;
        while (hasNext()) {
             = nextToken();
            if ( instanceof Char) {
                if (.toChar() == '}') {
                    break;
                }
                buf.append(.toString());
            } else {
                // Output whatever is in buffer
                if (buf.length() > 0) {
                    .add(new ELNode.ELText(buf.toString()));
                    buf.setLength(0);
                }
                if (!parseFunction()) {
                    .add(new ELNode.ELText(.toString()));
                }
            }
        }
        if ( != null) {
            buf.append(.getWhiteSpace());
        }
        if (buf.length() > 0) {
            .add(new ELNode.ELText(buf.toString()));
        }
        return ;
    }

    
Parse for a function FunctionInvokation ::= (identifier ':')? identifier '(' (Expression (,Expression)*)? ')' Note: currently we don't parse arguments
    private boolean parseFunction() {
        if (!( instanceof Id) || isELReserved(.toTrimmedString()) ||
                 instanceof Char && .toChar() == '.') {
            return false;
        }
        String s1 = null// Function prefix
        String s2 = .toTrimmedString(); // Function name
        int start =  - .toString().length();
        Token original = ;
        if (hasNext()) {
            int mark = getIndex() - .length();
             = nextToken();
            if (.toChar() == ':') {
                if (hasNext()) {
                    Token t2 = nextToken();
                    if (t2 instanceof Id) {
                        s1 = s2;
                        s2 = t2.toTrimmedString();
                        if (hasNext()) {
                             = nextToken();
                        }
                    }
                }
            }
            if (.toChar() == '(') {
                .add(new ELNode.Function(s1s2.substring(start - 1)));
                return true;
            }
             = original;
            setIndex(mark);
        }
        return false;
    }

    
Test if an id is a reserved word in EL
    private boolean isELReserved(String id) {
        int i = 0;
        int j = .;
        while (i < j) {
            int k = (i + j) / 2;
            int result = [k].compareTo(id);
            if (result == 0) {
                return true;
            }
            if (result < 0) {
                i = k + 1;
            } else {
                j = k;
            }
        }
        return false;
    }

    
Skip until an EL expression ('${' || '#{') is reached, allowing escape sequences '\\' and '\$' and '\#'.

Returns:
The text string up to the EL expression
    private String skipUntilEL() {
        char prev = 0;
        StringBuilder buf = new StringBuilder();
        while (hasNextChar()) {
            char ch = nextChar();
            if (prev == '\\') {
                prev = 0;
                if (ch == '\\') {
                    buf.append('\\');
                    prev = '\\';
                } else if (ch == '$'
                        || (! && ch == '#')) {
                    buf.append(ch);
                }
                // else error!
            } else if (prev == '$'
                    || (! && prev == '#')) {
                if (ch == '{') {
                    this. = 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();
    }
    /*
     * @return true if there is something left in EL expression buffer other
     * than white spaces.
     */
    private boolean hasNext() {
        skipSpaces();
        return hasNextChar();
    }
    private String getAndResetWhiteSpace() {
        String result = ;
         = "";
        return result;
    }
    /*
     * Implementation note: This method assumes that it is always preceded by a
     * call to hasNext() in order for whitespace handling to be correct.
     *
     * @return The next token in the EL expression buffer.
     */
    private Token nextToken() {
         = ;
        if (hasNextChar()) {
            char ch = nextChar();
            if (Character.isJavaIdentifierStart(ch)) {
                int start =  - 1;
                while ( < .length() &&
                        Character.isJavaIdentifierPart(
                                ch = .charAt())) {
                    nextChar();
                }
                return new Id(getAndResetWhiteSpace(), .substring(start));
            }
            if (ch == '\'' || ch == '"') {
                return parseQuotedChars(ch);
            } else {
                // For now...
                return new Char(getAndResetWhiteSpace(), ch);
            }
        }
        return null;
    }
    /*
     * Parse a string in single or double quotes, allowing for escape sequences
     * '\\', and ('\"', or "\'")
     */
    private Token parseQuotedChars(char quote) {
        StringBuilder buf = new StringBuilder();
        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(getAndResetWhiteSpace(), buf.toString());
    }
    /*
     * A collection of low level parse methods dealing with character in the EL
     * expression buffer.
     */
    private void skipSpaces() {
        int start = ;
        while (hasNextChar()) {
            char c = .charAt();
            if (c > ' ')
                break;
            ++;
        }
         = .substring(start);
    }
    private boolean hasNextChar() {
        return  < .length();
    }
    private char nextChar() {
        if ( >= .length()) {
            return (char) -1;
        }
        return .charAt(++);
    }
    private int getIndex() {
        return ;
    }
    private void setIndex(int i) {
         = i;
    }
    /*
     * Represents a token in EL expression string
     */
    private static class Token {
        protected final String whiteSpace;
        Token(String whiteSpace) {
            this. = whiteSpace;
        }
        char toChar() {
            return 0;
        }
        @Override
        public String toString() {
            return ;
        }
        String toTrimmedString() {
            return "";
        }
        String getWhiteSpace() {
            return ;
        }
    }
    /*
     * Represents an ID token in EL
     */
    private static class Id extends Token {
        String id;
        Id(String whiteSpaceString id) {
            super(whiteSpace);
            this. = id;
        }
        @Override
        public String toString() {
            return  + ;
        }
        @Override
        String toTrimmedString() {
            return ;
        }
    }
    /*
     * Represents a character token in EL
     */
    private static class Char extends Token {
        private char ch;
        Char(String whiteSpacechar ch) {
            super(whiteSpace);
            this. = ch;
        }
        @Override
        char toChar() {
            return ;
        }
        @Override
        public String toString() {
            return  + ;
        }
        @Override
        String toTrimmedString() {
            return "" + ;
        }
    }
    /*
     * Represents a quoted (single or double) string token in EL
     */
    private static class QuotedString extends Token {
        private String value;
        QuotedString(String whiteSpaceString v) {
            super(whiteSpace);
            this. = v;
        }
        @Override
        public String toString() {
            return  + ;
        }
        @Override
        String toTrimmedString() {
            return ;
        }
    }
    public char getType() {
        return ;
    }
    protected static class TextBuilder extends ELNode.Visitor {
        protected StringBuilder output = new StringBuilder();
        public String getText() {
            return .toString();
        }
        @Override
        public void visit(Root nthrows JasperException {
            .append(n.getType());
            .append('{');
            n.getExpression().visit(this);
            .append('}');
        }
        @Override
        public void visit(Function nthrows JasperException {
            .append(n.getOriginalText());
            .append('(');
        }
        @Override
        public void visit(Text nthrows JasperException {
            .append(n.getText());
        }
        @Override
        public void visit(ELText nthrows JasperException {
            .append(n.getText());
        }
    }
New to GrepCode? Check out our FAQ X