Skip to content

Commit

Permalink
jooby-apt: Value annotation attribute must be always generated fix #3539
Browse files Browse the repository at this point in the history
  • Loading branch information
jknack committed Sep 23, 2024
1 parent af15d20 commit fa783eb
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import javax.lang.model.element.*;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.Elements;
import javax.lang.model.util.SimpleAnnotationValueVisitor14;
import javax.lang.model.util.Types;

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

private final List<String> skip;
private final Types types;
private final Elements elements;
private final boolean hasBeanValidation;

public RouteAttributesGenerator(MvcContext context, boolean hasBeanValidation) {
var environment = context.getProcessingEnvironment();
this.elements = environment.getElementUtils();
this.types = environment.getTypeUtils();
this.skip = Options.stringListOpt(environment, SKIP_ATTRIBUTE_ANNOTATIONS);
this.hasBeanValidation = hasBeanValidation;
Expand Down Expand Up @@ -165,22 +168,33 @@ private Map<String, Object> annotationMap(List<? extends AnnotationMirror> annot
String prefix = elem.getSimpleName().toString();
// Set all values and then override with present values (fix for JDK 11+)
result.putAll(toMap(annotation.getElementValues(), prefix));
// toMap(elements.getElementValuesWithDefaults(annotation),
// prefix).forEach(result::putIfAbsent);

// Defaults value only pick "value"
toMap(elements.getElementValuesWithDefaults(annotation), prefix, "value"::equals)
.forEach(result::putIfAbsent);
}
return result;
}

private Map<String, Object> toMap(
Map<? extends ExecutableElement, ? extends AnnotationValue> values, String prefix) {
return toMap(values, prefix, name -> true);
}

private Map<String, Object> toMap(
Map<? extends ExecutableElement, ? extends AnnotationValue> values,
String prefix,
Predicate<String> filter) {
Map<String, Object> result = new LinkedHashMap<>();
for (var attribute : values.entrySet()) {
var value = annotationValue(attribute.getValue());
if (value != null && !value.toString().isEmpty()) {
var method = attribute.getKey().getSimpleName().toString();
var name = method.equals("value") ? prefix : prefix + "." + method;
// Found value is override on JDK 11 with default annotation value, we trust that spe
result.putIfAbsent(name, value);
if (filter.test(method)) {
var name = method.equals("value") ? prefix : prefix + "." + method;
// Found value is override on JDK 11 with default annotation value, we trust that spe
result.putIfAbsent(name, value);
}
}
}
return result;
Expand Down
14 changes: 14 additions & 0 deletions modules/jooby-apt/src/test/java/tests/i3539/C3539.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package tests.i3539;

import io.jooby.annotation.GET;

public class C3539 {
@GET("/3539")
@Secured3525
public void secured() {}
}
35 changes: 35 additions & 0 deletions modules/jooby-apt/src/test/java/tests/i3539/Issue3539.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package tests.i3539;

import static org.junit.jupiter.api.Assertions.*;

import java.util.Map;

import org.junit.jupiter.api.Test;

import io.jooby.apt.ProcessorRunner;

public class Issue3539 {

@Test
public void shouldGenerateAnnotationWithDefaultValue() throws Exception {
new ProcessorRunner(new C3539())
.withRouter(
app -> {
var routes = app.getRoutes();
assertNotNull(routes);
assertFalse(routes.isEmpty());
var route = app.getRoutes().get(0);
assertNotNull(route);
Map<String, Object> attributes = route.getAttributes();
assertNotNull(attributes);
assertFalse(attributes.isEmpty());
var secured = attributes.get(Secured3525.class.getSimpleName());
assertSame(secured, Boolean.TRUE);
});
}
}
17 changes: 17 additions & 0 deletions modules/jooby-apt/src/test/java/tests/i3539/Secured3525.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package tests.i3539;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secured3525 {
boolean value() default true;
}

0 comments on commit fa783eb

Please sign in to comment.