Package cn.aprilsoft.TinyAppServer.jssp

Source Code of cn.aprilsoft.TinyAppServer.jssp.JsspExecutor

package cn.aprilsoft.TinyAppServer.jssp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.SocketException;
import java.util.Scanner;

import javax.script.Bindings;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;

import org.apache.log4j.Logger;

import cn.aprilsoft.TinyAppServer.configuare.Configuare;
import cn.aprilsoft.TinyAppServer.exception.ClientAbortException;
import cn.aprilsoft.TinyAppServer.exception.ServerException;
import cn.aprilsoft.TinyAppServer.mailer.AppMailer;
import cn.aprilsoft.TinyAppServer.reqNrep.Request;
import cn.aprilsoft.TinyAppServer.reqNrep.Response;
import cn.aprilsoft.TinyAppServer.session.Session;
import cn.aprilsoft.io.FileUtil;
import cn.aprilsoft.io.IOUtil;
import cn.aprilsoft.lang.EnvTool;
import cn.aprilsoft.lang.StringUtil;

public class JsspExecutor {

    private static final String              JSSP_SCRIPT_LANGUAGE = "JavaScript";

    private static final Logger              JSSP_LOG             = Logger.getLogger("JsspLog");

    private static final ScriptEngineManager JSSP_ENG_MAN         = new ScriptEngineManager();

    public static void clearJsspWork() {
        File work = new File(Configuare.WORK_PATH);
        if (work.exists() && work.isDirectory()) {
            FileUtil.removeFilesEndsWith(work, Configuare.EXPLAINED_EXT);
            FileUtil.removeFilesEndsWith(work, Configuare.COMPILED_EXT);
        } else {
            work.mkdirs();
        }
    }

    public static File explainJssp(File file) throws IOException {
        File explainedFile = new File(getExplainedFileName(file));

        if (explainedFile.exists()) {
            if (explainedFile.lastModified() > file.lastModified()) {
                return explainedFile;
            }
        }
        Scanner scanner = new Scanner(file, "UTF-8");
        try {
            PrintWriter pw = new PrintWriter(explainedFile, "UTF-8");
            // support return
            pw.write("(function() {\r\n");
            StringBuilder sb = new StringBuilder();
            boolean inScript = false;
            boolean isStart = false;
            boolean isEnd = false;
            try {
                while (scanner.hasNext()) {
                    String line = scanner.nextLine() + "\\r\\n";

                    for (int i = 0; i < line.length(); i++) {
                        char c = line.charAt(i);
                        if (inScript) {
                            if ((c == '%') && (i < (line.length() - 1)) && (line.charAt(i + 1) == '>')) {
                                isStart = false;
                                isEnd = true;
                                inScript = false;
                                i += 1;
                            } else {
                                isStart = false;
                                isEnd = false;
                            }
                        } else {
                            if ((c == '<') && (i < (line.length() - 1)) && (line.charAt(i + 1) == '%')) {
                                isStart = true;
                                isEnd = false;
                                inScript = true;
                                i += 1;
                            } else {
                                isStart = false;
                                isEnd = false;
                            }
                        }

                        boolean process = false;

                        if (isStart || isEnd) {
                            process = true;
                        } else {
                            sb.append(c);
                            if (i == (line.length() - 1)) {
                                process = true;
                            }
                        }

                        if (process) {
                            String sbs = sb.toString();
                            sb = new StringBuilder();
                            if (isStart) {
                                if (sbs.length() > 0) {
                                    explainPlain(pw, sbs);
                                }
                            } else if (isEnd) {
                                if (sbs.length() > 0) {
                                    explainScript(pw, sbs);
                                }
                            } else if (i == (line.length() - 1)) {
                                if (!inScript) {
                                    explainPlain(pw, sbs);
                                } else {
                                    explainScript(pw, sbs);
                                }
                            } else if (line.length() == 0) {
                                if (!inScript) {
                                    explainPlain(pw, sbs);
                                } else {
                                    explainScript(pw, sbs);
                                }
                            }
                        }
                    }
                }
                pw.write("})();\r\n");
                pw.flush();
            } finally {
                pw.close();
            }
        } finally {
            scanner.close();
        }

        return explainedFile;
    }

    public static void executeJssp(File file, Request request, Response response) {
        File explained;
        try {
            explained = explainJssp(file);
        } catch (IOException e) {
            throw new ServerException(e);
        }
        executeExplained(explained, request, response);
    }

    public static void executeExplained(File file, Request request, Response response) {
        ScriptEngine se = JSSP_ENG_MAN.getEngineByName(JSSP_SCRIPT_LANGUAGE);

        ByteArrayOutputStream cache = new ByteArrayOutputStream();
        BufferWriter out = new BufferWriter(cache, request.getCharset());

        Session session = request.getSession();

        Bindings b = new SimpleBindings();
        // variants (Java -> JSSP)
        b.put("envTool", EnvTool.INSTANCE);
        b.put("log", JSSP_LOG);
        b.put("mailer", AppMailer.getMailer());

        b.put("request", request);
        b.put("session", session);
        b.put("response", response);
        b.put("out", out);

        try {
            se.eval(FileUtil.readFileToString(file, "UTF-8"), b);
            out.flush();

            if (response.getLocation() != null) {
                response.flush();
                return;
            }

            InputStream is = new ByteArrayInputStream(cache.toByteArray());
            if (is.available() > 0) {
                response.setContentSize(is.available());
                IOUtil.copy(is, response.getOutputStream());
            }
        } catch (SocketException e) {
            throw new ClientAbortException();
        } catch (IOException e) {
            throw new ServerException(e);
        } catch (ScriptException e) {
            throw new ServerException(e);
        }
    }

    private static final String getExplainedFileName(File file) {
        String explained = file.getPath() + Configuare.EXPLAINED_EXT;
        explained = explained.replaceAll("[:\\\\/]", "_");
        explained = Configuare.WORK_PATH + File.separator + explained;
        return explained;
    }

    private static final void explainPlain(Writer pw, String plain) throws IOException {
        plain = plain.replace("\"", "\\\"");
        plain = "out.write(\"" + plain + "\");";
        pw.write(plain);
        pw.write("\r\n");
    }

    private static final void explainScript(Writer pw, String script) throws IOException {
        if (script.endsWith("\\r\\n")) {
            script = script.substring(0, (script.length() - "\\r\\n".length()));
        }
        if (script.length() == 0) {
            return;
        }
        if (script.trim().startsWith("=")) {
            int equal = script.indexOf('=');
            String expression = script.substring(equal + 1);
            pw.write("out.writeEscape(");
            pw.write(expression);
            pw.write(");");
        } else if (script.trim().startsWith("!=")) {
            int equal = script.indexOf('!');
            String expression = script.substring(equal + 2);
            pw.write("out.write(");
            pw.write(expression);
            pw.write(");");
        } else {
            pw.write(script);
        }
        pw.write("\r\n");
    }
}

class BufferWriter {

    private PrintWriter pw;

    public BufferWriter(OutputStream out, String encoding) {
        try {
            this.pw = new PrintWriter(new OutputStreamWriter(out, encoding));
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public void writeEscape(Object o) {
        pw.write(StringUtil.escapeHtml(objectToString(o)));
    }

    public void write(Object o) {
        pw.write(objectToString(o));
    }

    public void flush() {
        pw.flush();
    }

    public void close() {
        pw.close();
    }

    private String objectToString(Object o) {
        if (o instanceof Double) {
            double doubleValue = ((Double) o).doubleValue();
            if (Double.compare(Math.ceil(doubleValue), Math.floor(doubleValue)) == 0) {
                o = Double.valueOf(doubleValue).longValue();
            }
        }
        return ((o == null) ? "" : o.toString());
    }
}
TOP

Related Classes of cn.aprilsoft.TinyAppServer.jssp.JsspExecutor

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.