All Downloads are FREE. Search and download functionalities are using the official Maven repository.

play.templates.TemplateParser Maven / Gradle / Ivy

There is a newer version: 1.5.0
Show newest version
package play.templates;

/**
 * Template parser
 */
public class TemplateParser {

    private String pageSource;
    private int nestedBracesCounter; // counts nested braces in current expression/tag

    public TemplateParser(String pageSource) {
        this.pageSource = pageSource;
        this.len = pageSource.length();
    }

    //
    public enum Token {

        EOF, //
        PLAIN, //
        SCRIPT, // %{...}% or {%...%}
        EXPR, // ${...}
        START_TAG, // #{...}
        END_TAG, // #{/...}
        MESSAGE, // &{...}
        ACTION, // @{...}
        ABS_ACTION, // @@{...}
        COMMENT, // *{...}*
    }
    private int end, begin, end2, begin2, len;
    private Token state = Token.PLAIN;

    private Token found(Token newState, int skip) {
        begin2 = begin;
        end2 = --end;
        begin = end += skip;
        Token lastState = state;
        state = newState;
        return lastState;
    }

    public Integer getLine() {
        String token = pageSource.substring(0, begin2);
        if (token.indexOf("\n") == -1) {
            return 1;
        } else {
            return token.split("\n").length;
        }
    }

    public String getToken() {
        return pageSource.substring(begin2, end2);
    }

    public String checkNext() {
        if (end2 < pageSource.length()) {
            return pageSource.charAt(end2) + "";
        }
        return "";
    }
    
    public Token nextToken() {
        for (;;) {

            int left = len - end;
            if (left == 0) {
                end++;
                return found(Token.EOF, 0);
            }

            char c = pageSource.charAt(end++);
            char c1 = left > 1 ? pageSource.charAt(end) : 0;
            char c2 = left > 2 ? pageSource.charAt(end + 1) : 0;

            switch (state) {
                case PLAIN:
                    if (c == '%' && c1 == '{') {
                        return found(Token.SCRIPT, 2);
                    }
                    if (c == '{' && c1 == '%') {
                        return found(Token.SCRIPT, 2);
                    }
                    if (c == '$' && c1 == '{') {
                        nestedBracesCounter = 0;
                        return found(Token.EXPR, 2);
                    }
                    if (c == '#' && c1 == '{' && c2 == '/') {
                        return found(Token.END_TAG, 3);
                    }
                    if (c == '#' && c1 == '{') {
                        nestedBracesCounter = 0;
                        return found(Token.START_TAG, 2);
                    }
                    if (c == '&' && c1 == '{') {
                        return found(Token.MESSAGE, 2);
                    }
                    if (c == '@' && c1 == '@' && c2 == '{') {
                        return found(Token.ABS_ACTION, 3);
                    }
                    if (c == '@' && c1 == '{') {
                        return found(Token.ACTION, 2);
                    }
                    if (c == '*' && c1 == '{') {
                        return found(Token.COMMENT, 2);
                    }
                    break;
                case SCRIPT:
                    if (c == '}' && c1 == '%') {
                        return found(Token.PLAIN, 2);
                    }
                    if (c == '%' && c1 == '}') {
                        return found(Token.PLAIN, 2);
                    }
                    break;
                case COMMENT:
                    if (c == '}' && c1 == '*') {
                        return found(Token.PLAIN, 2);
                    }
                    break;
                case START_TAG:
                    if (c == '}' && nestedBracesCounter == 0) {
                        return found(Token.PLAIN, 1);
                    }
                    if (c == '/' && c1 == '}') {
                        return found(Token.END_TAG, 1);
                    }
                    if (c == '{') nestedBracesCounter++;
                    if (c == '}') nestedBracesCounter--;
                    break;
                case END_TAG:
                    if (c == '}') {
                        return found(Token.PLAIN, 1);
                    }
                    break;
                case EXPR:
                    if (c == '}' && nestedBracesCounter == 0) {
                        return found(Token.PLAIN, 1);
                    }
                    if (c == '{') nestedBracesCounter++;
                    if (c == '}') nestedBracesCounter--;
                    break;
                case ACTION:
                    if (c == '}') {
                        return found(Token.PLAIN, 1);
                    }
                    break;
                case ABS_ACTION:
                    if (c == '}') {
                        return found(Token.PLAIN, 1);
                    }
                    break;
                case MESSAGE:
                    if (c == '}') {
                        return found(Token.PLAIN, 1);
                    }
                    break;
            }
        }
    }

    void reset() {
        end = begin = end2 = begin2 = 0;
        state = Token.PLAIN;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy