Skip to content
Merged
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
4 changes: 2 additions & 2 deletions aws-cognito/http-client-authtoken/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-json-core</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
</dependency>

<!-- test dependencies -->
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-json-node</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
<scope>test</scope>
</dependency>

Expand Down
4 changes: 2 additions & 2 deletions http-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsonb</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
<optional>true</optional>
</dependency>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-json-node</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
<scope>test</scope>
</dependency>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,13 @@ public static void writeJsonbType(UType type, Append writer) {
writeType(type.paramRaw(), writer);
writer.append(".map()");
break;
case "java.util.stream.Stream":
writeType(type.paramRaw(), writer);
writer.append(".streamAsLines()");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would also check if content type is json stream, since json streaming isn't the first thing that comes to mind

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah actually that might not be quite so easy. This is in the generated constructor and not per method/endpoint with a produces mime type. Hmm.

So currently it's more like, using JsonB + response type is a Stream -> "streaming json content".

break;
default: {
if (type.mainType().contains("java.util")) {
throw new UnsupportedOperationException("Only java.util Map, Set and List are supported JsonB Controller Collection Types");
throw new UnsupportedOperationException("Only java.util Map, Set, List and Stream are supported JsonB Controller Collection Types");
}
writeType(type, writer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

public enum MediaType {
APPLICATION_JSON("application/json"),
APPLICATION_STREAM_JSON("application/stream+json"),
TEXT_PLAIN("text/plain"),
TEXT_HTML("text/html"),
HTML_UTF8("text/html;charset=UTF8"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,15 +258,14 @@ void writeHandler(boolean requestScoped) {
writer.append(indent).append("res.send(content);").eol();

} else {
writeContextReturn(indent);
final var uType = UType.parse(method.returnType());
writeContextReturn(indent, streamingResponse(uType));
if (responseMode == ResponseMode.InputStream) {
final var uType = UType.parse(method.returnType());
writer.append(indent).append("result.transferTo(res.outputStream());", uType.shortName()).eol();
} else if (responseMode == ResponseMode.Json) {
if (returnTypeString()) {
writer.append(indent).append("res.send(result); // send raw JSON").eol();
} else {
final var uType = UType.parse(method.returnType());
writer.append(indent).append("%sJsonType.toJson(result, JsonOutput.of(res));", uType.shortName()).eol();
}
} else {
Expand All @@ -280,6 +279,10 @@ void writeHandler(boolean requestScoped) {
writer.append(" }").eol().eol();
}

private static boolean streamingResponse(UType uType) {
return uType.mainType().equals("java.util.stream.Stream");
}

enum ResponseMode {
Void,
Json,
Expand Down Expand Up @@ -381,25 +384,35 @@ private boolean usesQueryParams() {
}

private void writeContextReturn(String indent) {
writeContextReturn(indent, false);
}

private void writeContextReturn(String indent, boolean streaming) {
final var producesOp = Optional.ofNullable(method.produces());
if (producesOp.isEmpty() && !useJsonB && !useJstachio) {
return;
}
final var produces =
producesOp
.map(MediaType::parse)
.orElse(useJstachio ? MediaType.HTML_UTF8 : MediaType.APPLICATION_JSON);
final var produces = producesOp
.map(MediaType::parse)
.orElse(defaultMediaType(streaming));
final var contentTypeString = "res.headers().contentType(MediaTypes.";
writer.append(indent);
switch (produces) {
case HTML_UTF8 -> writer.append("res.headers().contentType(HTML_UTF8);").eol();
case APPLICATION_JSON -> writer.append(contentTypeString).append("APPLICATION_JSON);").eol();
case APPLICATION_STREAM_JSON -> writer.append(contentTypeString).append("APPLICATION_STREAM_JSON);").eol();
case TEXT_HTML -> writer.append(contentTypeString).append("TEXT_HTML);").eol();
case TEXT_PLAIN -> writer.append(contentTypeString).append("TEXT_PLAIN);").eol();
case UNKNOWN -> writer.append(contentTypeString + "create(\"%s\"));", producesOp.orElse("UNKNOWN")).eol();
}
}

private MediaType defaultMediaType(boolean streaming) {
return useJstachio
? MediaType.HTML_UTF8
: streaming ? MediaType.APPLICATION_STREAM_JSON : MediaType.APPLICATION_JSON;
}

private String lookupStatusCode(int statusCode) {
return statusMap.getOrDefault(statusCode, String.valueOf(statusCode));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ private void write(boolean requestScoped) {
writer.append(");").eol();
writer.append(" var cacheContent = contentCache.content(key);").eol();
writer.append(" if (cacheContent != null) {").eol();
writeContextReturn(responseMode, "cacheContent");
writeContextReturn(responseMode, "cacheContent", "");
writer.append(" return;").eol();
writer.append(" }").eol();
}
Expand Down Expand Up @@ -258,18 +258,15 @@ private void write(boolean requestScoped) {
if (withContentCache) {
writer.append(indent).append("contentCache.contentPut(key, content);").eol();
}
writer.append(indent);
writeContextReturn(responseMode, "content");
writeContextReturn(responseMode, "content", indent);
}
case Jstachio -> {
var renderer = ProcessingContext.jstacheRenderer(method.returnType());
writer.append(indent).append("var content = %s(result);", renderer).eol();
writer.append(indent);
writeContextReturn(responseMode, "content");
writeContextReturn(responseMode, "content", indent);
}
default -> {
writer.append(indent);
writeContextReturn(responseMode, "result");
writeContextReturn(responseMode, "result", indent);
}
}
if (includeNoContent) {
Expand All @@ -278,7 +275,8 @@ private void write(boolean requestScoped) {
}
}

private void writeContextReturn(ResponseMode responseMode, String resultVariable) {
private void writeContextReturn(ResponseMode responseMode, String resultVariable, String indent) {
writer.append(indent);
final UType type = UType.parse(method.returnType());
if ("java.util.concurrent.CompletableFuture".equals(type.mainType())) {
logError(method.element(), "CompletableFuture is not a supported return type.");
Expand All @@ -293,30 +291,42 @@ private void writeContextReturn(ResponseMode responseMode, String resultVariable
}
switch (responseMode) {
case Void -> {}
case Json -> writeJsonReturn(produces);
case Json -> writeJsonReturn(produces, indent);
case Text -> writer.append("ctx.text(%s);", resultVariable);
case Templating -> writer.append("ctx.html(%s);", resultVariable);
default -> writer.append("ctx.contentType(\"%s\").write(%s);", produces, resultVariable);
}
writer.eol();
}

private void writeJsonReturn(String produces) {
private void writeJsonReturn(String produces, String indent) {
var uType = UType.parse(method.returnType());
boolean streaming = useJsonB && streamingContent(uType);
if (produces == null) {
produces = MediaType.APPLICATION_JSON.getValue();
produces = streaming
? MediaType.APPLICATION_STREAM_JSON.getValue()
: MediaType.APPLICATION_JSON.getValue();
}
var uType = UType.parse(method.returnType());
if ("java.lang.String".equals(method.returnType().toString())) {
writer.append("ctx.contentType(\"%s\").write(result); // raw json", produces);
return;
}
if (useJsonB) {
writer.append("ctx.jsonb(%sJsonType, result);", uType.shortName());
if (streaming) {
writer.append("ctx.contentType(\"%s\");", produces).eol();
writer.append(indent).append("%sJsonType.toJson(result, io.avaje.jex.core.json.JsonbOutput.of(ctx));", uType.shortName());
} else {
writer.append("ctx.jsonb(%sJsonType, result);", uType.shortName());
}
} else {
writer.append("ctx.json(result);");
}
}

private static boolean streamingContent(UType uType) {
return uType.mainType().equals("java.util.stream.Stream");
}

private static boolean isExceptionOrFilterChain(MethodParam param) {
return isAssignable2Interface(param.utype().mainType(), "java.lang.Exception")
|| "HttpFilter.FilterChain".equals(param.shortType());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ public String bodyAsClass(UType type) {

public static String writeJsonbType(UType type) {
var writer = new StringBuilder();

switch (type.mainType()) {
case "java.util.List":
writeType(type.paramRaw(), writer);
Expand All @@ -63,10 +62,14 @@ public static String writeJsonbType(UType type) {
writeType(type.paramRaw(), writer);
writer.append(".map()");
break;
case "java.util.stream.Stream":
writeType(type.paramRaw(), writer);
writer.append(".stream()");
break;
default: {
if (type.mainType().contains("java.util")) {
throw new UnsupportedOperationException(
"Only java.util Map, Set and List are supported JsonB Controller Collection Types");
"Only java.util Map, Set, List and Stream are supported JsonB Controller Collection Types");
}
writeType(type, writer);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/test-javalin-jsonb/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,13 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsonb</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
</dependency>

<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsonb-generator</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
<scope>provided</scope>
</dependency>

Expand Down
4 changes: 2 additions & 2 deletions tests/test-jex/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
<dependency>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsonb</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
</dependency>

<!-- java annotation processors -->
Expand Down Expand Up @@ -140,7 +140,7 @@
<path>
<groupId>io.avaje</groupId>
<artifactId>avaje-jsonb-generator</artifactId>
<version>3.5</version>
<version>3.6-RC2</version>
</path>
<path>
<groupId>io.avaje</groupId>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.example.web;

import java.math.BigInteger;
import java.util.stream.Stream;

import io.avaje.http.api.Controller;
import io.avaje.http.api.Default;
Expand All @@ -16,6 +17,11 @@
@Path("/")
public class HelloController {

@Get("stream")
Stream<HelloDto> stream() {
return Stream.of(new HelloDto(1,"a"), new HelloDto(2, "b"));
}

@Get
HelloDto getHello() {
HelloDto dto = new HelloDto();
Expand Down
8 changes: 8 additions & 0 deletions tests/test-jex/src/main/java/org/example/web/HelloDto.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,12 @@ public class HelloDto {
@NotNull
public String name;
public ServerType serverType;

public HelloDto() {
}

public HelloDto(int id, String name) {
this.id = id;
this.name = name;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

@Controller
public class BarController implements BarInterface {
Expand All @@ -21,6 +22,11 @@ public List<Bar> findByCode(String code) {
return new ArrayList<>();
}

@Override
public Stream<Bar> findByCodeStream(String code) {
return Stream.of();
}

@Override
public String barMessage() {
return "Hello";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponse;

import java.util.List;
import java.util.stream.Stream;

@Path("/bars")
public interface BarInterface {
Expand All @@ -19,6 +20,9 @@ public interface BarInterface {
@Get("/find/:code")
List<Bar> findByCode(String code);

@Get("/find/:code/stream")
Stream<Bar> findByCodeStream(String code);

@Produces(MediaType.TEXT_PLAIN)
@Get
String barMessage();
Expand Down
Loading