generated from lengors/maven-java-template
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add
NullabilityAnnotator
and deprecate CheckerableAnnotator
and…
… related classes
- Loading branch information
Showing
11 changed files
with
499 additions
and
61 deletions.
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
105
src/main/java/io/github/lengors/js2pets/annotators/AnnotationUtils.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
package io.github.lengors.js2pets.annotators; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
import java.util.stream.Stream; | ||
|
||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.checkerframework.checker.nullness.qual.Nullable; | ||
import org.jsonschema2pojo.GenerationConfig; | ||
|
||
/** | ||
* Annotation utilities. | ||
* | ||
* @author lengors | ||
*/ | ||
public final class AnnotationUtils { | ||
/** | ||
* Checkerframework nullable annotation. | ||
*/ | ||
public static final List<Class<? extends Annotation>> CHECKERFRAMEWORK_NULLABLE_ANNOTATION = List.of(Nullable.class); | ||
|
||
/** | ||
* Checkerframework nullability annotations. | ||
*/ | ||
public static final Set<String> CHECKERFRAMEWORK_NULLABILITY_ANNOTATIONS = Stream | ||
.of(NonNull.class, Nullable.class) | ||
.map(Class::getName) | ||
.collect(Collectors.toUnmodifiableSet()); | ||
|
||
/** | ||
* Non-nullable annotations. | ||
*/ | ||
public static final List<Class<? extends Annotation>> NON_NULLABLE_ANNOTATIONS = List.of( | ||
jakarta.validation.constraints.NotNull.class, | ||
javax.validation.constraints.NotNull.class, | ||
jakarta.annotation.Nonnull.class, | ||
javax.annotation.Nonnull.class, | ||
NonNull.class); | ||
|
||
/** | ||
* Nullable annotations. | ||
*/ | ||
public static final List<Class<? extends Annotation>> NULLABLE_ANNOTATIONS = List.of( | ||
jakarta.annotation.Nullable.class, | ||
javax.annotation.Nullable.class, | ||
Nullable.class); | ||
|
||
private AnnotationUtils() { | ||
throw new UnsupportedOperationException(); | ||
} | ||
|
||
/** | ||
* Gets the non-nullable annotations based on generation configuration. | ||
* | ||
* @param generationConfig The generation configuration. | ||
* @return The non-nullable annotation classes. | ||
*/ | ||
public static List<Class<? extends Annotation>> getNonNullableAnnotations(final GenerationConfig generationConfig) { | ||
final var annotations = new ArrayList<Class<? extends Annotation>>(); | ||
if (generationConfig.isIncludeJsr303Annotations()) { | ||
if (generationConfig.isUseJakartaValidation()) { | ||
annotations.add(jakarta.validation.constraints.NotNull.class); | ||
} else { | ||
annotations.add(javax.validation.constraints.NotNull.class); | ||
} | ||
} | ||
|
||
if (generationConfig.isIncludeJsr305Annotations()) { | ||
if (generationConfig.isUseJakartaValidation()) { | ||
annotations.add(jakarta.annotation.Nonnull.class); | ||
} else { | ||
annotations.add(javax.annotation.Nonnull.class); | ||
} | ||
} | ||
|
||
annotations.add(NonNull.class); | ||
|
||
return Collections.unmodifiableList(annotations); | ||
} | ||
|
||
/** | ||
* Gets the nullable annotations based on generation configuration. | ||
* | ||
* @param generationConfig The generation configuration. | ||
* @return The nullable annotation classes. | ||
*/ | ||
public static List<Class<? extends Annotation>> getNullableAnnotations(final GenerationConfig generationConfig) { | ||
final var annotations = new ArrayList<Class<? extends Annotation>>(); | ||
if (generationConfig.isIncludeJsr305Annotations()) { | ||
if (generationConfig.isUseJakartaValidation()) { | ||
annotations.add(jakarta.annotation.Nullable.class); | ||
} else { | ||
annotations.add(javax.annotation.Nullable.class); | ||
} | ||
} | ||
|
||
annotations.add(Nullable.class); | ||
|
||
return Collections.unmodifiableList(annotations); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
106 changes: 106 additions & 0 deletions
106
src/main/java/io/github/lengors/js2pets/annotators/NullabilityAnnotator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
package io.github.lengors.js2pets.annotators; | ||
|
||
import java.util.Collections; | ||
import java.util.stream.Collectors; | ||
|
||
import org.apache.commons.lang3.StringUtils; | ||
import org.jsonschema2pojo.AbstractAnnotator; | ||
import org.jsonschema2pojo.GenerationConfig; | ||
|
||
import com.sun.codemodel.JDefinedClass; | ||
import com.sun.codemodel.JFieldVar; | ||
import com.sun.codemodel.JType; | ||
|
||
import io.github.lengors.js2pets.codemodel.CodeModelUtils; | ||
|
||
/** | ||
* An annotator that makes the generated classes emitted with proper nullable and non-nullable annotations. | ||
* | ||
* @author lengors | ||
*/ | ||
public class NullabilityAnnotator extends AbstractAnnotator implements EnhancedAnnotator { | ||
/** | ||
* Getter method prefix. | ||
*/ | ||
private static final String GETTER_PREFIX = "get"; | ||
|
||
/** | ||
* Instantiates annotator with generation configuration. | ||
* | ||
* @param generationConfig The injected generation configuration. | ||
*/ | ||
public NullabilityAnnotator(final GenerationConfig generationConfig) { | ||
super(generationConfig); | ||
} | ||
|
||
/** | ||
* Annotator callback that annotates equals methods' parameter with proper nullable types as well as any properties, | ||
* return types and parameters for constructors and setters for the respective fields. | ||
* | ||
* @param type The generated class to apply the annotation to. | ||
*/ | ||
@Override | ||
public void type(final JType type) { | ||
EnhancedAnnotator.super.type(type); | ||
|
||
if (!(type instanceof JDefinedClass clazz)) { | ||
return; | ||
} | ||
|
||
final var nullableAnnotations = AnnotationUtils.getNullableAnnotations(getGenerationConfig()); | ||
final var nonNullableAnnotations = AnnotationUtils.getNonNullableAnnotations(getGenerationConfig()); | ||
|
||
final var classStructure = CodeModelUtils.listClassStructure(clazz); | ||
final var invokables = CodeModelUtils.listInvokables(classStructure); | ||
|
||
final var fieldsByNullabilityType = clazz | ||
.fields() | ||
.values() | ||
.stream() | ||
.collect(Collectors.groupingBy(field -> AnnotationUtils.NON_NULLABLE_ANNOTATIONS | ||
.stream() | ||
.anyMatch(annotation -> CodeModelUtils.containsAnnotation(field, annotation)) | ||
? NullabilityType.NON_NULLABLE | ||
: NullabilityType.NULLABLE)); | ||
|
||
for (final var nullabilityType : NullabilityType.values()) { | ||
final var annotations = switch (nullabilityType) { | ||
case NullabilityType.NON_NULLABLE -> nonNullableAnnotations; | ||
case NullabilityType.NULLABLE -> nullableAnnotations; | ||
}; | ||
final var fields = fieldsByNullabilityType.getOrDefault(nullabilityType, Collections.emptyList()); | ||
final var fieldNames = fields | ||
.stream() | ||
.map(field -> { | ||
CodeModelUtils.safeAnnotate(field, annotations); | ||
return field; | ||
}) | ||
.map(JFieldVar::name) | ||
.collect(Collectors.toUnmodifiableSet()); | ||
|
||
CodeModelUtils.annotateInvokablesParameters(invokables.stream(), fieldNames, annotations); | ||
|
||
final var capitalizedFieldNames = fieldNames | ||
.stream() | ||
.map(StringUtils::capitalize) | ||
.collect(Collectors.toUnmodifiableSet()); | ||
invokables | ||
.stream() | ||
.filter(method -> { | ||
if (!method.params().isEmpty()) { | ||
return false; | ||
} | ||
|
||
final var methodName = method.name(); | ||
if (!methodName.startsWith(GETTER_PREFIX)) { | ||
return false; | ||
} | ||
|
||
return capitalizedFieldNames.contains(StringUtils.capitalize(methodName.replaceFirst(GETTER_PREFIX, ""))); | ||
}) | ||
.forEach(method -> CodeModelUtils.safeAnnotate(method, annotations)); | ||
} | ||
|
||
CodeModelUtils.annotateEqualsMethod(clazz); | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/main/java/io/github/lengors/js2pets/annotators/NullabilityType.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package io.github.lengors.js2pets.annotators; | ||
|
||
/** | ||
* Types of nullability. | ||
* | ||
* @author lengors | ||
*/ | ||
public enum NullabilityType { | ||
/** | ||
* Nullable type. | ||
*/ | ||
NULLABLE, | ||
|
||
/** | ||
* Nullable type. | ||
*/ | ||
NON_NULLABLE; | ||
} |
Oops, something went wrong.