Package com.nexirius.framework.htmlview

Source Code of com.nexirius.framework.htmlview.HTMLParser

//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.htmlview;

import com.nexirius.framework.datamodel.DataModel;
import com.nexirius.framework.htmlview.function.HTMLFunction;
import com.nexirius.util.TextToken;
import com.nexirius.util.StringVector;

import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PushbackInputStream;

/**
* This class translates a HTML file which contains special functions into a real HTML output stream<BR>
* special functions:
* <PRE>
* $!include("template")
* $!includeBody("template")
* $!field("field name", "edit|view", "template")
* $!popup("childname", view|edit, "template", "link text", "event", "true|false") if parameter 6 is true, then the actual model is duplicated in the actual state with HTMLState.startDuplicatePopup()
* $!event("event", "link text", "&moreParameter=value")
* $!iconEvent("event", "iconName", "&moreParameter=value")
* $!button("event")
* $!array("field name of the array", "edit|view", "template")
* $!flag("field name", "flag", "on text", "off text")
* $!select("field name")
* $!define("name", "value")
* $!formStart()
* $!formEnd()
* </PRE>
*/
public class HTMLParser {

    public static final String NULL = "null";
    public static final String EDIT = "edit";
    public static final String VIEW = "view";
    public static final String CHECKED = "CHECKED";

    DataModel model;
    boolean isEditor;
    HTMLResolver resolver;
    OutputStream out;
    int translateCount = 0;

    /**
     * creates a new instance of HTMLParser
     *
     * @param model    the actual model which is assotiated to the input stream (see parse)
     * @param isEditor the actual general translation rule
     * @param resolver the resolver wich created this parser (and which is used to handle subsequent nested function calls
     * @param out      the actual output stream
     * @throws Exception
     */
    public HTMLParser(DataModel model, boolean isEditor, HTMLResolver resolver, OutputStream out)
            throws Exception {
        this.model = model;
        this.isEditor = isEditor;
        this.resolver = resolver;
        this.out = out;
    }

    public DataModel getModel() {
        return model;
    }

    public boolean isEditor() {
        return isEditor;
    }

    public HTMLResolver getResolver() {
        return resolver;
    }

    /**
     * Return the model which belongs to the actual state
     * @return
     */
    public DataModel getRootModel() {
        return resolver.getRootModel();
    }

    public OutputStream getOut() {
        return out;
    }

    public void setOut(OutputStream out) {
        this.out = out;
    }

    /**
     * parses the input stream and calls parseFunction when the $! is found
     *
     * @param sessionVariable
     * @param in the actual input stream
     * @return the number of functions which are translated
     * @throws Exception
     */
    public int parse(HTMLSessionVariable sessionVariable, PushbackInputStream in)
            throws Exception {
        int state = 0;
        translateCount = 0;

        while (true) {
            int c = in.read();

            if (c < 0) {

                break;
            }

            switch (state) {
                case 0:
                    if (c == '$') {
                        state = 1;
                    } else {
                        out.write(c);
                    }
                    break;

                case 1:
                    if (c == '!') {
                        state = 0;
                        try {
                            HTMLFunction f = parseFunction(sessionVariable, in);
                            String[] arguments = parseFunctionArguments(sessionVariable, in);

                            f.translate(sessionVariable, this, arguments);
                            ++translateCount;
                        } catch (Exception ex) {
                            ex.printStackTrace(new PrintStream(out));
                        }
                    } else {
                        out.write('$');
                        out.write(c);
                        state = 0;
                    }
                    break;
            }
        }

        return translateCount;
    }

    /**
     * reads the input stream and parses !$function() calls
     *
     * @param in the input stream from which functions are extracted
     * @return the actual function
     * @throws Exception when syntax of the function is not correct
     */
    public HTMLFunction parseFunction(HTMLSessionVariable sessionVariable, PushbackInputStream in)
            throws Exception {
        HTMLFunction ret = null;
        TextToken token = TextToken.nextToken(in);

        if (token == null) {
            throw new Exception("Expecting function name at end of stream");
        }

        if (token.isIdentifier()) {
            ret = resolver.getFunction(token.getString());
        } else {
            throw new Exception("Expecting function name but have " + token.debugString());
        }

        if (ret == null) {
            throw new Exception("Unknown function name " + token.debugString());
        }

        return ret;
    }

    public String[] parseFunctionArguments(HTMLSessionVariable sessionVariable, PushbackInputStream in) throws Exception {
        StringVector functionArgumentList = new StringVector();
        TextToken token;
        token = TextToken.nextToken(in);

        if (token == null) {
            throw new Exception("Expecting '(' after function name");
        }

        if (token.isChar('(')) {
            while (true) {
                token = TextToken.nextToken(in);

                if (token.isChar(')')) {

                    break;
                }

                if (token.isString()) {
                    String s = token.getString();
                    s = resolve(sessionVariable, s);
                    functionArgumentList.append(s);
                } else if (token.isInt()) {
                    functionArgumentList.append(Integer.toString(token.getInt()));
                } else if (token.isIdentifier(NULL)) {
                    functionArgumentList.append((String)null);
                } else if (token.isIdentifier()) {
                    functionArgumentList.append(token.getString());
                } else {
                    throw new Exception("Unexpected token in parameter list:" + token.debugString());
                }

                token = TextToken.nextToken(in);

                if (token.isChar(',')) {
                    // expected
                } else if (token.isChar(')')) {
                    break;
                } else {
                    throw new Exception("Unexpected token in parameter list:" + token.debugString());
                }
            }
        } else {
            throw new Exception("Expecting '(' but have " + token.debugString());
        }

        return functionArgumentList.getArray();
    }

    private String resolve(HTMLSessionVariable sessionVariable, String s) throws Exception {
        byte[] bytes = getResolver().resolve(sessionVariable, model, new ByteArrayInputStream(s.getBytes()), isEditor);
        return new String(bytes);
    }

    /**
     * access the number of translated functions
     *
     * @return
     */
    public int getNumberOfTranslations() {
        return translateCount;
    }
}
TOP

Related Classes of com.nexirius.framework.htmlview.HTMLParser

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.