Skip to content

Upgrade dependencies and refactor server implementation #372

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

Open
wants to merge 6 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
58 changes: 29 additions & 29 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,40 +15,40 @@ jobs:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v2
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2

# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
- name: Checkout repository
uses: actions/checkout@v3
with:
# We must fetch at least the immediate parents so that if this is
# a pull request then we can checkout the head.
fetch-depth: 2

# If this run was triggered by a pull request event, then checkout
# the head of the pull request instead of the merge commit.
- run: git checkout HEAD^2
if: ${{ github.event_name == 'pull_request' }}

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
# Override language selection by uncommenting this and choosing your languages
# with:
# languages: go, javascript, csharp, python, cpp, java

# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v1
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3

# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ℹ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl

# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language

#- run: |
# make bootstrap
# make release
#- run: |
# make bootstrap
# make release

- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ apply plugin: 'signing'

compileJava.options.encoding = "UTF-8"
compileTestJava.options.encoding = "UTF-8"
sourceCompatibility = 11
targetCompatibility = 11
sourceCompatibility = 21
targetCompatibility = 21
22 changes: 9 additions & 13 deletions core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'com.intershop.gradle.javacc' version '4.0.1'
id 'com.github.johnrengelman.shadow' version '8.1.1'
id 'com.intershop.gradle.javacc' version '5.0.1'
id 'java'
id 'com.jfrog.artifactory'
id 'maven-publish'
Expand All @@ -15,10 +15,10 @@ repositories {
}

dependencies {
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.4.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.3'

testImplementation 'junit:junit:4.13.2'
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.13.2'
testImplementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.18.3'
}

ext {
Expand All @@ -27,7 +27,7 @@ ext {
}

group 'com.schibsted.spt.data'
version "0.1.14"
version "0.1.15"
project.description "A JSON query and transformation language"

check {
Expand Down Expand Up @@ -62,7 +62,7 @@ javacc {
// Sonatype Maven central publishing

task sourceJar(type: Jar) {
classifier "sources"
archiveClassifier = "sources"
from sourceSets.main.allJava
}

Expand All @@ -81,7 +81,7 @@ javadoc {
}

task javadocJar(type: Jar, dependsOn: javadoc) {
classifier "javadoc"
archiveClassifier = "javadoc"
from javadoc.destinationDir
}

Expand Down Expand Up @@ -131,12 +131,8 @@ publishing {

from components.java

artifact(sourceJar) {
classifier = 'sources'
}
artifact(javadocJar) {
classifier = 'javadoc'
}
artifact(sourceJar)
artifact(javadocJar)
}
}
repositories {
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
7 changes: 4 additions & 3 deletions playground/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}

apply plugin: 'java'
Expand All @@ -12,8 +12,9 @@ repositories {

dependencies {
implementation project(':core')
implementation 'org.eclipse.jetty:jetty-server:9.4.45.v20220203'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.2'
implementation 'org.eclipse.jetty:jetty-server:12.0.18'
implementation 'jakarta.servlet:jakarta.servlet-api:5.0.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.18.3'
}

group 'com.schibsted.spt.data'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,83 +1,143 @@

package no.priv.garshol.jslt.playground;

import java.io.IOException;
import java.io.PrintStream;
import java.io.InputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.schibsted.spt.data.jslt.Expression;
import com.schibsted.spt.data.jslt.Parser;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.component.AbstractLifeCycle;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.schibsted.spt.data.jslt.Parser;
import com.schibsted.spt.data.jslt.Expression;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;

public class PlaygroundServer {
private static ObjectMapper mapper = new ObjectMapper();
private static String INDEX_HTML = "lambda.html";

public static class JsltHandler extends AbstractHandler {
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) {
if (!target.equals("/jslt"))
return;

if (request.getMethod().equals("GET")) {
try (InputStream stream = Parser.class.getClassLoader().getResourceAsStream(INDEX_HTML)) {
byte[] buf = new byte[16384];
int bytes;
while ((bytes = stream.read(buf)) != -1) {
response.getOutputStream().write(buf, 0, bytes);
}

response.setStatus(HttpServletResponse.SC_OK);
response.addHeader("Content-type", "text/html");
} catch (IOException e) {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
private static final ObjectMapper mapper = new ObjectMapper();

public static class JsltHandler extends AbstractLifeCycle implements Handler {
private Server server;

@Override
public boolean handle(Request request, Response response, Callback callback) throws Exception {
String target = request.getHttpURI().getPath();

if (!target.equals("/jslt")) {
return false;
}

String method = request.getMethod();

if (method.equals("GET")) {
// Set headers before writing content
response.setStatus(HttpStatus.OK_200);
response.getHeaders().add("Content-Type", "text/html");

String INDEX_HTML = "lambda.html";
try (InputStream stream = Parser.class.getClassLoader().getResourceAsStream(INDEX_HTML)) {
if (stream == null) {
response.setStatus(HttpStatus.NOT_FOUND_404);
callback.succeeded();
return true;
}

// Read the entire file into memory first
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buf = new byte[4096];
int bytesRead;
while ((bytesRead = stream.read(buf)) != -1) {
baos.write(buf, 0, bytesRead);
}

// Write the content all at once
byte[] content = baos.toByteArray();
response.write(true, ByteBuffer.wrap(content), callback);
} catch (IOException e) {
response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR_500);
callback.succeeded();
return true;
}

return true;
}

if (method.equals("POST")) {
try {
// Use the Request.asInputStream() utility method to get an InputStream of the request
try (InputStream inputStream = Request.asInputStream(request)) {
// Read the request body into memory
ByteArrayOutputStream requestContent = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
requestContent.write(buffer, 0, bytesRead);
}
String requestBody = requestContent.toString(StandardCharsets.UTF_8);

JsonNode body = mapper.readTree(requestBody);
JsonNode input = mapper.readTree(body.get("json").asText());
String jslt = body.get("jslt").asText();

Expression template = Parser.compileString(jslt);
JsonNode output = template.apply(input);

// Set status before writing the response
response.setStatus(HttpStatus.OK_200);
response.getHeaders().add("Content-Type", "application/json");

// Write the response in one go
byte[] responseBytes = mapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(output);
response.write(true, ByteBuffer.wrap(responseBytes), callback);
}
} catch (Exception e) {
response.setStatus(HttpStatus.BAD_REQUEST_400);
response.getHeaders().add("Content-Type", "text/plain");

byte[] errorBytes = e.toString().getBytes();
response.write(true, ByteBuffer.wrap(errorBytes), callback);
}

return true;
}

return false;
}

baseRequest.setHandled(true);
return;
}

if (request.getMethod().equals("POST")) {
try {
JsonNode body = mapper.readTree(request.getReader());
JsonNode input = mapper.readTree(body.get("json").asText());
String jslt = body.get("jslt").asText();

Expression template = Parser.compileString(jslt);
JsonNode output = template.apply(input);
response.setStatus(HttpServletResponse.SC_OK);

response.getOutputStream().write(mapper.writerWithDefaultPrettyPrinter().writeValueAsBytes(output));
@Override
public Server getServer() {
return server;
}

} catch (Exception e) {
try (PrintStream ps = new PrintStream(response.getOutputStream())) {
e.printStackTrace(ps);
} catch (IOException e2) {
}
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
@Override
public void setServer(Server server) {
this.server = server;
}

baseRequest.setHandled(true);
}
@Override
public void destroy() {
// Implementation for Destroyable interface
// Clean up any resources if needed
}
}
}

public static void main(String[] argv) throws Exception {
Server server = new Server(Integer.parseInt(argv[0]));
HandlerList handlers = new HandlerList();
handlers.addHandler(new JsltHandler());
server.setHandler(handlers);
public static void main(String[] argv) throws Exception {
Server server = new Server(Integer.parseInt(argv[0]));

server.start();
server.join();
}
// Create a context handler for the /jslt path
ContextHandler context = new ContextHandler();
context.setContextPath("/");
context.setHandler(new JsltHandler());

}
server.setHandler(context);

server.start();
server.join();
}
}
Loading