Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Routing now simpler and ignores the HASH UUID to main URL #61

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
157 changes: 24 additions & 133 deletions src/org/antlr/v4/server/ANTLRHttpServer.java
Original file line number Diff line number Diff line change
@@ -1,149 +1,44 @@
package org.antlr.v4.server;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.stream.JsonReader;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.antlr.v4.server.persistent.PersistenceLayer;
import org.antlr.v4.server.persistent.cloudstorage.CloudStoragePersistenceLayer;
import org.antlr.v4.server.unique.DummyUniqueKeyGenerator;
import org.antlr.v4.server.unique.UniqueKeyGenerator;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.server.persistence.PersistenceLayer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.resource.PathResource;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.slf4j.LoggerFactory;



import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;

import static org.antlr.v4.server.GrammarProcessor.interp;
import java.nio.file.Paths;

public class ANTLRHttpServer {
public static final String IMAGES_DIR = "/tmp/antlr-images";
public static final int UUID_LEN = 36;

public static class ParseServlet extends DefaultServlet {
static final ch.qos.logback.classic.Logger LOGGER =
(ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ANTLRHttpServer.class);
public static final PersistenceLayer<String> persistenceLayer = PersistenceLayer.newInstance("local");

public static class RouterServlet extends DefaultServlet {
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException
{

JsonObject jsonResponse = new JsonObject();
try {
response.setContentType("text/plain;charset=utf-8");
response.setContentType("text/html;");
response.addHeader("Access-Control-Allow-Origin", "*");

JsonObject jsonObj = JsonParser.parseReader(request.getReader()).getAsJsonObject();
// System.out.println(jsonObj);

String grammar = jsonObj.get("grammar").getAsString();
String lexGrammar = jsonObj.get("lexgrammar").getAsString(); // can be null
String input = jsonObj.get("input").getAsString();
String startRule = jsonObj.get("start").getAsString();

StringBuilder logMsg = new StringBuilder();
logMsg.append("GRAMMAR:\n");
logMsg.append(grammar);
logMsg.append("\nLEX GRAMMAR:\n");
logMsg.append(lexGrammar);
logMsg.append("\nINPUT:\n\"\"\"");
logMsg.append(input);
logMsg.append("\"\"\"\n");
logMsg.append("STARTRULE: ");
logMsg.append(startRule);
logMsg.append('\n');
LOGGER.info(logMsg.toString());

if (grammar.strip().length() == 0 && lexGrammar.strip().length() == 0) {
jsonResponse.addProperty("arg_error", "missing either combined grammar or lexer and " +
"parser both");
}
else if (grammar.strip().length() == 0 && lexGrammar.strip().length() > 0) {
jsonResponse.addProperty("arg_error", "missing parser grammar");
}
else if (startRule.strip().length() == 0) {
jsonResponse.addProperty("arg_error", "missing start rule");
}
else if (input.length() == 0) {
jsonResponse.addProperty("arg_error", "missing input");
}
else {
try {
jsonResponse = interp(grammar, lexGrammar, input, startRule);
}
catch (ParseCancellationException pce) {
jsonResponse.addProperty("exception_trace", "parser timeout ("+GrammarProcessor.MAX_PARSE_TIME_MS+"ms)");
}
catch (Throwable e) {
e.printStackTrace(System.err);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String path = request.getPathInfo();
path = path.substring(1); // remove '/' on front
if ( path.length()== UUID_LEN ) {
System.out.printf("UUID "+path);
// Redirect to the usual "/" ULR (index.html) with ?uuid=UUID
response.sendRedirect("/?uuid="+path);
}
catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
jsonResponse.addProperty("exception_trace", sw.toString());
jsonResponse.addProperty("exception", e.getMessage());
else {
super.doGet(request, response);
}
LOGGER.info("RESULT:\n"+jsonResponse);
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter w = response.getWriter();
w.write(new Gson().toJson(jsonResponse));
w.flush();
}
}

public static class ShareServlet extends DefaultServlet {
static final ch.qos.logback.classic.Logger LOGGER =
(ch.qos.logback.classic.Logger)LoggerFactory.getLogger(ANTLRHttpServer.class);

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException
{
final JsonObject jsonResponse = new JsonObject();
try {
response.setContentType("text/plain;charset=utf-8");
response.setContentType("text/html;");
response.addHeader("Access-Control-Allow-Origin", "*");

JsonObject jsonObj = JsonParser.parseReader(request.getReader()).getAsJsonObject();
PersistenceLayer<String> persistenceLayer = new CloudStoragePersistenceLayer();
UniqueKeyGenerator keyGen = new DummyUniqueKeyGenerator();
Optional<String> uniqueKey = keyGen.generateKey();
persistenceLayer.persist(new Gson().toJson(jsonResponse).getBytes(StandardCharsets.UTF_8),
uniqueKey.orElseThrow());

jsonResponse.addProperty("resource_id", uniqueKey.orElseThrow());
}
catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
jsonResponse.addProperty("exception_trace", sw.toString());
jsonResponse.addProperty("exception", e.getMessage());

}
LOGGER.info("RESULT:\n"+jsonResponse);
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter w = response.getWriter();
w.write(new Gson().toJson(jsonResponse));
w.flush();
}
}

Expand All @@ -166,15 +61,11 @@ public static void main(String[] args) throws Exception {

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.addServlet(new ServletHolder(new ParseServlet()), "/parse/*");
context.addServlet(new ServletHolder(new ShareServlet()), "/share/*");

ServletHolder holderHome = new ServletHolder("static-home", DefaultServlet.class);
holderHome.setInitParameter("resourceBase", "static");
holderHome.setInitParameter("dirAllowed","true");
holderHome.setInitParameter("pathInfoOnly","true");
context.addServlet(holderHome,"/*");

context.setBaseResource(new PathResource(Paths.get("static")));
context.addServlet(RouterServlet.class, "/*");
context.addServlet(ParseServlet.class, "/parse/*");
context.addServlet(ShareServlet.class, "/share/*");
context.addServlet(LoadServlet.class, "/load/*");
server.setHandler(context);

server.start();
Expand Down
2 changes: 1 addition & 1 deletion src/org/antlr/v4/server/GrammarProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import static org.antlr.v4.gui.Interpreter.profilerColumnNames;
import static org.antlr.v4.server.ANTLRHttpServer.IMAGES_DIR;
import static org.antlr.v4.server.ANTLRHttpServer.ParseServlet.LOGGER;
import static org.antlr.v4.server.ParseServlet.LOGGER;
import static us.parr.lib.ParrtSys.execInDir;

import java.io.*;
Expand Down
43 changes: 43 additions & 0 deletions src/org/antlr/v4/server/LoadServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package org.antlr.v4.server;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class LoadServlet extends DefaultServlet {
static final ch.qos.logback.classic.Logger LOGGER =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ANTLRHttpServer.class);

@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
String uuid = request.getParameter("uuid");
final JsonObject jsonResponse = new JsonObject();
try {
response.setContentType("text/plain;charset=utf-8");
response.setContentType("text/html;");
response.addHeader("Access-Control-Allow-Origin", "*");
System.err.println("uuid: " + uuid);
byte[] jsonBytes = ANTLRHttpServer.persistenceLayer.retrieve(uuid);
LOGGER.info("LOAD:\n" + jsonResponse);
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter w = response.getWriter();
w.write(new String(jsonBytes));
w.flush();
}
catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
jsonResponse.addProperty("exception_trace", sw.toString());
jsonResponse.addProperty("exception", e.getMessage());
}
}
}
84 changes: 84 additions & 0 deletions src/org/antlr/v4/server/ParseServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package org.antlr.v4.server;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import static org.antlr.v4.server.GrammarProcessor.interp;

public class ParseServlet extends DefaultServlet {
static final ch.qos.logback.classic.Logger LOGGER =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ANTLRHttpServer.class);

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {

JsonObject jsonResponse = new JsonObject();
try {
response.setContentType("text/plain;charset=utf-8");
response.setContentType("text/html;");
response.addHeader("Access-Control-Allow-Origin", "*");

JsonObject jsonObj = JsonParser.parseReader(request.getReader()).getAsJsonObject();
// System.out.println(jsonObj);

String grammar = jsonObj.get("grammar").getAsString();
String lexGrammar = jsonObj.get("lexgrammar").getAsString(); // can be null
String input = jsonObj.get("input").getAsString();
String startRule = jsonObj.get("start").getAsString();

StringBuilder logMsg = new StringBuilder();
logMsg.append("GRAMMAR:\n");
logMsg.append(grammar);
logMsg.append("\nLEX GRAMMAR:\n");
logMsg.append(lexGrammar);
logMsg.append("\nINPUT:\n\"\"\"");
logMsg.append(input);
logMsg.append("\"\"\"\n");
logMsg.append("STARTRULE: ");
logMsg.append(startRule);
logMsg.append('\n');
LOGGER.info(logMsg.toString());

if (grammar.strip().length() == 0 && lexGrammar.strip().length() == 0) {
jsonResponse.addProperty("arg_error", "missing either combined grammar or lexer and " +
"parser both");
} else if (grammar.strip().length() == 0 && lexGrammar.strip().length() > 0) {
jsonResponse.addProperty("arg_error", "missing parser grammar");
} else if (startRule.strip().length() == 0) {
jsonResponse.addProperty("arg_error", "missing start rule");
} else if (input.length() == 0) {
jsonResponse.addProperty("arg_error", "missing input");
} else {
try {
jsonResponse = interp(grammar, lexGrammar, input, startRule);
} catch (ParseCancellationException pce) {
jsonResponse.addProperty("exception_trace", "parser timeout (" + GrammarProcessor.MAX_PARSE_TIME_MS + "ms)");
} catch (Throwable e) {
e.printStackTrace(System.err);
}
}
} catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
jsonResponse.addProperty("exception_trace", sw.toString());
jsonResponse.addProperty("exception", e.getMessage());
}
LOGGER.info("RESULT:\n" + jsonResponse);
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter w = response.getWriter();
w.write(new Gson().toJson(jsonResponse));
w.flush();
}
}
58 changes: 58 additions & 0 deletions src/org/antlr/v4/server/ShareServlet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.antlr.v4.server;

import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.antlr.v4.server.persistence.PersistenceLayer;
import org.antlr.v4.server.persistence.CloudStoragePersistenceLayer;
import org.antlr.v4.server.unique.DummyUniqueKeyGenerator;
import org.antlr.v4.server.unique.UniqueKeyGenerator;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

import static org.antlr.v4.server.ANTLRHttpServer.persistenceLayer;

public class ShareServlet extends DefaultServlet {
static final ch.qos.logback.classic.Logger LOGGER =
(ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ANTLRHttpServer.class);

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
final JsonObject jsonResponse = new JsonObject();
try {
response.setContentType("text/plain;charset=utf-8");
response.setContentType("text/html;");
response.addHeader("Access-Control-Allow-Origin", "*");

JsonObject jsonObj = JsonParser.parseReader(request.getReader()).getAsJsonObject();
UniqueKeyGenerator keyGen = new DummyUniqueKeyGenerator();
Optional<String> uniqueKey = keyGen.generateKey();
persistenceLayer.persist(new Gson().toJson(jsonObj).getBytes(StandardCharsets.UTF_8),
uniqueKey.orElseThrow());

jsonResponse.addProperty("uuid", uniqueKey.orElseThrow());
}
catch (Exception e) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
jsonResponse.addProperty("exception_trace", sw.toString());
jsonResponse.addProperty("exception", e.getMessage());

}
LOGGER.info("RESULT:\n" + jsonResponse);
response.setStatus(HttpServletResponse.SC_OK);
PrintWriter w = response.getWriter();
w.write(new Gson().toJson(jsonResponse));
w.flush();
}
}
Loading