Skip to content

Commit ff5f6f4

Browse files
committed
mvc: Add BindParam annotation for custom parsing/mapping
- supports BindParam "sub class" annotation - ref #3472
1 parent 6737126 commit ff5f6f4

File tree

7 files changed

+48
-4
lines changed

7 files changed

+48
-4
lines changed

jooby/src/main/java/io/jooby/annotation/BindParam.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* @since 3.2.5
1818
*/
1919
@Retention(RetentionPolicy.RUNTIME)
20-
@Target(ElementType.PARAMETER)
20+
@Target({ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
2121
public @interface BindParam {
2222
/**
2323
* Class containing the mapping function.

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

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66
package io.jooby.internal.apt;
77

88
import java.util.*;
9-
import java.util.function.Function;
109
import java.util.function.Predicate;
1110
import java.util.stream.Collectors;
1211
import java.util.stream.Stream;
1312

1413
import javax.lang.model.element.AnnotationMirror;
14+
import javax.lang.model.element.Element;
1515
import javax.lang.model.element.VariableElement;
1616

1717
public class MvcParameter {
@@ -132,6 +132,17 @@ private Map<String, AnnotationMirror> annotationMap(VariableElement parameter) {
132132
return Stream.of(parameter.getAnnotationMirrors(), parameter.asType().getAnnotationMirrors())
133133
.filter(Objects::nonNull)
134134
.flatMap(List::stream)
135-
.collect(Collectors.toMap(it -> it.getAnnotationType().toString(), Function.identity()));
135+
.flatMap(
136+
it ->
137+
Stream.concat(
138+
Stream.of(it),
139+
annotationFromAnnotationType(it.getAnnotationType().asElement()).stream()))
140+
.filter(Objects::nonNull)
141+
.map(it -> Map.entry(it.getAnnotationType().toString(), it))
142+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1));
143+
}
144+
145+
private List<? extends AnnotationMirror> annotationFromAnnotationType(Element element) {
146+
return Optional.ofNullable(element.getAnnotationMirrors()).orElse(Collections.emptyList());
136147
}
137148
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ public String toSourceCode(
161161
.orElseThrow(
162162
() ->
163163
new IllegalArgumentException(
164-
"Method not found: " + converter + "." + methodErrorName));
164+
"Method not found: " + converter + ".[unnamed]" + methodErrorName));
165165
if (!mapping.getModifiers().contains(Modifier.PUBLIC)) {
166166
throw new IllegalArgumentException("Method is not public: " + converter + "." + mapping);
167167
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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.i3472;
7+
8+
import io.jooby.Context;
9+
10+
public class BeanMapping {
11+
public static BindBean map(Context ctx) {
12+
return new BindBean("extends:" + ctx.query("value").value());
13+
}
14+
}

modules/jooby-apt/src/test/java/tests/i3472/C3472.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ public BindBean bindStatic(@BindParam(BindBean.class) BindBean bean) {
2626
return bean;
2727
}
2828

29+
@GET("/3472/extends")
30+
public BindBean bindExtends(@SubAnnotation BindBean bean) {
31+
return bean;
32+
}
33+
2934
public BindBean convert(Context ctx) {
3035
return new BindBean(ctx.query("value").value());
3136
}

modules/jooby-apt/src/test/java/tests/i3472/Issue3472.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public void shouldBindWithCustomCode() throws Exception {
3030

3131
assertEquals(
3232
new BindBean("static:" + value), router.get("/3472/static", ctx).value());
33+
34+
assertEquals(
35+
new BindBean("extends:" + value), router.get("/3472/extends", ctx).value());
3336
});
3437
}
3538
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
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.i3472;
7+
8+
import io.jooby.annotation.BindParam;
9+
10+
@BindParam(BeanMapping.class)
11+
public @interface SubAnnotation {}

0 commit comments

Comments
 (0)