Skip to content

Commit fa783eb

Browse files
committed
jooby-apt: Value annotation attribute must be always generated fix #3539
1 parent af15d20 commit fa783eb

File tree

4 files changed

+85
-5
lines changed

4 files changed

+85
-5
lines changed

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

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import javax.lang.model.element.*;
1717
import javax.lang.model.type.TypeMirror;
18+
import javax.lang.model.util.Elements;
1819
import javax.lang.model.util.SimpleAnnotationValueVisitor14;
1920
import javax.lang.model.util.Types;
2021

@@ -46,10 +47,12 @@ private record EnumValue(String type, String value) {}
4647

4748
private final List<String> skip;
4849
private final Types types;
50+
private final Elements elements;
4951
private final boolean hasBeanValidation;
5052

5153
public RouteAttributesGenerator(MvcContext context, boolean hasBeanValidation) {
5254
var environment = context.getProcessingEnvironment();
55+
this.elements = environment.getElementUtils();
5356
this.types = environment.getTypeUtils();
5457
this.skip = Options.stringListOpt(environment, SKIP_ATTRIBUTE_ANNOTATIONS);
5558
this.hasBeanValidation = hasBeanValidation;
@@ -165,22 +168,33 @@ private Map<String, Object> annotationMap(List<? extends AnnotationMirror> annot
165168
String prefix = elem.getSimpleName().toString();
166169
// Set all values and then override with present values (fix for JDK 11+)
167170
result.putAll(toMap(annotation.getElementValues(), prefix));
168-
// toMap(elements.getElementValuesWithDefaults(annotation),
169-
// prefix).forEach(result::putIfAbsent);
171+
172+
// Defaults value only pick "value"
173+
toMap(elements.getElementValuesWithDefaults(annotation), prefix, "value"::equals)
174+
.forEach(result::putIfAbsent);
170175
}
171176
return result;
172177
}
173178

174179
private Map<String, Object> toMap(
175180
Map<? extends ExecutableElement, ? extends AnnotationValue> values, String prefix) {
181+
return toMap(values, prefix, name -> true);
182+
}
183+
184+
private Map<String, Object> toMap(
185+
Map<? extends ExecutableElement, ? extends AnnotationValue> values,
186+
String prefix,
187+
Predicate<String> filter) {
176188
Map<String, Object> result = new LinkedHashMap<>();
177189
for (var attribute : values.entrySet()) {
178190
var value = annotationValue(attribute.getValue());
179191
if (value != null && !value.toString().isEmpty()) {
180192
var method = attribute.getKey().getSimpleName().toString();
181-
var name = method.equals("value") ? prefix : prefix + "." + method;
182-
// Found value is override on JDK 11 with default annotation value, we trust that spe
183-
result.putIfAbsent(name, value);
193+
if (filter.test(method)) {
194+
var name = method.equals("value") ? prefix : prefix + "." + method;
195+
// Found value is override on JDK 11 with default annotation value, we trust that spe
196+
result.putIfAbsent(name, value);
197+
}
184198
}
185199
}
186200
return result;
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.i3539;
7+
8+
import io.jooby.annotation.GET;
9+
10+
public class C3539 {
11+
@GET("/3539")
12+
@Secured3525
13+
public void secured() {}
14+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
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.i3539;
7+
8+
import static org.junit.jupiter.api.Assertions.*;
9+
10+
import java.util.Map;
11+
12+
import org.junit.jupiter.api.Test;
13+
14+
import io.jooby.apt.ProcessorRunner;
15+
16+
public class Issue3539 {
17+
18+
@Test
19+
public void shouldGenerateAnnotationWithDefaultValue() throws Exception {
20+
new ProcessorRunner(new C3539())
21+
.withRouter(
22+
app -> {
23+
var routes = app.getRoutes();
24+
assertNotNull(routes);
25+
assertFalse(routes.isEmpty());
26+
var route = app.getRoutes().get(0);
27+
assertNotNull(route);
28+
Map<String, Object> attributes = route.getAttributes();
29+
assertNotNull(attributes);
30+
assertFalse(attributes.isEmpty());
31+
var secured = attributes.get(Secured3525.class.getSimpleName());
32+
assertSame(secured, Boolean.TRUE);
33+
});
34+
}
35+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
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.i3539;
7+
8+
import java.lang.annotation.ElementType;
9+
import java.lang.annotation.Retention;
10+
import java.lang.annotation.RetentionPolicy;
11+
import java.lang.annotation.Target;
12+
13+
@Target({ElementType.METHOD})
14+
@Retention(RetentionPolicy.RUNTIME)
15+
public @interface Secured3525 {
16+
boolean value() default true;
17+
}

0 commit comments

Comments
 (0)