Package javarepl.web

Source Code of javarepl.web.WebConsoleClientHandler

package javarepl.web;

import com.googlecode.totallylazy.*;
import com.googlecode.utterlyidle.RequestBuilder;
import com.googlecode.utterlyidle.Response;
import com.googlecode.utterlyidle.Status;
import com.googlecode.utterlyidle.handlers.ClientHttpHandler;
import javarepl.Repl;
import javarepl.client.JavaREPLClient;
import javarepl.console.ConsoleStatus;

import java.util.UUID;

import static com.googlecode.funclate.Model.persistent.parse;
import static com.googlecode.totallylazy.Option.none;
import static com.googlecode.totallylazy.Option.some;
import static com.googlecode.utterlyidle.RequestBuilder.get;
import static com.googlecode.utterlyidle.Responses.response;
import static com.googlecode.utterlyidle.Status.GATEWAY_TIMEOUT;
import static com.googlecode.utterlyidle.Status.INTERNAL_SERVER_ERROR;
import static javarepl.Utils.randomServerPort;
import static javarepl.console.ConsoleStatus.Idle;
import static javarepl.console.TimingOutConsole.EXPRESSION_TIMEOUT;
import static javarepl.console.TimingOutConsole.INACTIVITY_TIMEOUT;

public final class WebConsoleClientHandler {
    private final String id = UUID.randomUUID().toString();
    private final Option<String> expression;
    private Option<Integer> port = none();
    private Option<Process> process = none();

    public WebConsoleClientHandler(Option<String> expression) {
        this.expression = expression;
    }

    public String id() {
        return id;
    }

    public Option<Integer> port() {
        return port;
    }

    private void createProcess() {
        if (port.isEmpty()) {
            try {
                port = some(randomServerPort());
                ProcessBuilder builder = new ProcessBuilder("java", "-Xmx128M", "-cp", System.getProperty("java.class.path"), Repl.class.getCanonicalName(),
                        "--sandboxed", "--ignoreConsole", "--port=" + port.get(), "--expressionTimeout=5", "--inactivityTimeout=300", expression.map(Strings.format("--expression=%s")).getOrElse(""));
                builder.redirectErrorStream(true);
                process = some(builder.start());

                waitUntilProcessStarted();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    }

    private ConsoleStatus status() {
        try {
            return ConsoleStatus.valueOf(parse(new ClientHttpHandler().handle(get("http://localhost:" + port.get() + "/status").build()).entity().toString())
                    .get("status", String.class));

        } catch (Exception e) {
            return Idle;
        }
    }

    private boolean waitUntilProcessStarted() throws Exception {
        for (int i = 0; i < 500; i++) {
            Thread.sleep(10);
            if (status().isRunning())
                return true;
        }

        return false;
    }

    public void shutdown() {
        if (!process.isEmpty()) {
            process.get().destroy();
            process = none();
        }
    }

    public Response execute(String expression) {
        createProcess();

        try {
            return reportProcessError(new ClientHttpHandler().handle(RequestBuilder.post("http://localhost:" + port.get() + "/" + "execute").form("expression", expression).build()));
        } catch (Exception e) {
            e.printStackTrace();
            return response(INTERNAL_SERVER_ERROR);
        }
    }

    public Response readExpression(String line) {
        createProcess();

        try {
            return reportProcessError(new ClientHttpHandler().handle(RequestBuilder.post("http://localhost:" + port.get() + "/" + "readExpression").form("line", line).build()));
        } catch (Exception e) {
            e.printStackTrace();
            return response(INTERNAL_SERVER_ERROR);
        }
    }

    public Response completions(String expression) {
        createProcess();

        try {
            return reportProcessError(new ClientHttpHandler().handle(RequestBuilder.get("http://localhost:" + port.get() + "/" + "completions").query("expression", expression).build()));
        } catch (Exception e) {
            e.printStackTrace();
            return response(INTERNAL_SERVER_ERROR);
        }
    }

    public Sequence<String> history() {
        createProcess();

        try {
            return new JavaREPLClient("localhost", port.get()).history();
        } catch (Exception e) {
            e.printStackTrace();
            return Sequences.empty();
        }
    }

    private Response reportProcessError(final Response response) {
        if (response.status() == Status.OK)
            return response;

        return exitCode().map(new Mapper<Integer, Response>() {
            public Response call(Integer code) throws Exception {
                switch (code) {
                    case EXPRESSION_TIMEOUT:
                    case INACTIVITY_TIMEOUT: {
                        shutdown();
                        return response(GATEWAY_TIMEOUT);
                    }
                    default:
                        return response;
                }
            }
        }).getOrElse(response);
    }

    public Option<Integer> exitCode() {
        if (process.isEmpty())
            return none();

        try {
            Thread.sleep(100);
            return some(process.get().exitValue());
        } catch (Exception e) {
            return none();
        }
    }
}
TOP

Related Classes of javarepl.web.WebConsoleClientHandler

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.