Skip to content

Commit 5a850fc

Browse files
committed
mvc: default value on @QueryParam/@CookieParam/@HeaderParam annotation
- fix #3761
1 parent df40329 commit 5a850fc

File tree

4 files changed

+87
-4
lines changed

4 files changed

+87
-4
lines changed

modules/jooby-apt/src/main/java/io/jooby/internal/apt/ParameterGenerator.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ protected String builtinType(
326326
boolean kt, AnnotationMirror annotation, TypeDefinition type, String name, boolean nullable) {
327327
if (BUILT_IN.stream().anyMatch(type::is)) {
328328
var paramSource = source(annotation);
329+
var defaultValue = defaultValue(annotation);
329330
// look at named parameter
330331
if (type.isPrimitive()) {
331332
// like: .intValue
@@ -334,15 +335,27 @@ protected String builtinType(
334335
method,
335336
"(",
336337
CodeBlock.string(name),
337-
paramSource,
338+
paramSource.isEmpty() ? defaultValue : paramSource,
338339
").",
339340
CodeBlock.type(kt, type.getName()).toLowerCase(),
340341
"Value()");
341342
} else if (type.is(String.class)) {
342343
var stringValue = nullable ? "valueOrNull" : "value";
343-
// StringL: .value
344+
if (paramSource.isEmpty() && !defaultValue.isEmpty()) {
345+
// use non-null version bc there is a default value.
346+
stringValue = "value";
347+
}
348+
// String: .value
344349
return CodeBlock.of(
345-
"ctx.", method, "(", CodeBlock.string(name), paramSource, ").", stringValue, "()");
350+
"ctx.",
351+
method,
352+
"(",
353+
CodeBlock.string(name),
354+
// Param Source doesn't support default value
355+
paramSource.isEmpty() ? defaultValue : paramSource,
356+
").",
357+
stringValue,
358+
"()");
346359
} else {
347360
var toValue = nullable ? "toNullable" : "to";
348361
// Any other type: .to(UUID.class)
@@ -412,6 +425,14 @@ protected String source(AnnotationMirror annotation) {
412425
return "";
413426
}
414427

428+
protected String defaultValue(AnnotationMirror annotation) {
429+
if (annotation.getAnnotationType().toString().startsWith("io.jooby.annotation")) {
430+
var sources = findAnnotationValue(annotation, AnnotationSupport.VALUE);
431+
return sources.isEmpty() ? "" : CodeBlock.of(", ", CodeBlock.string(sources.getFirst()));
432+
}
433+
return "";
434+
}
435+
415436
protected final String method;
416437
private final Set<String> annotations;
417438
private Set<String> typeRestrictions = Set.of(); // empty set means no restrictions by default

modules/jooby-apt/src/test/java/tests/ModuleCompilerTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public void routesWithMimeTypes() throws Exception {
123123
public void routesWithParamLookup() throws Exception {
124124
new ProcessorRunner(new RouteWithParamLookup())
125125
.withRouter(
126-
app -> {
126+
(app, source) -> {
127127
MockRouter router = new MockRouter(app);
128128

129129
Throwable t =
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3761;
7+
8+
import io.jooby.annotation.GET;
9+
import io.jooby.annotation.Path;
10+
import io.jooby.annotation.QueryParam;
11+
12+
@Path("/3761")
13+
public class C3761 {
14+
15+
@GET("/number")
16+
public int number(@QueryParam("5") int num) {
17+
return num;
18+
}
19+
20+
@GET("/unset")
21+
public String unset(@QueryParam String unset) {
22+
return unset;
23+
}
24+
25+
@GET("/emptySet")
26+
public String emptySet(@QueryParam("") String emptySet) {
27+
return emptySet;
28+
}
29+
30+
@GET("/stringVal")
31+
public String string(@QueryParam("Hello") String stringVal) {
32+
return stringVal;
33+
}
34+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package tests.i3761;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
import org.junit.jupiter.api.Test;
11+
12+
import io.jooby.apt.ProcessorRunner;
13+
14+
public class Issue3761 {
15+
@Test
16+
public void shouldGenerateDefaultValues() throws Exception {
17+
new ProcessorRunner(new C3761())
18+
.withSourceCode(
19+
(source) -> {
20+
assertTrue(source.contains("return c.number(ctx.query(\"num\", \"5\").intValue());"));
21+
assertTrue(source.contains("return c.unset(ctx.query(\"unset\").valueOrNull());"));
22+
assertTrue(
23+
source.contains("return c.emptySet(ctx.query(\"emptySet\", \"\").value());"));
24+
assertTrue(
25+
source.contains("return c.string(ctx.query(\"stringVal\", \"Hello\").value());"));
26+
});
27+
}
28+
}

0 commit comments

Comments
 (0)