Skip to content

Commit

Permalink
Guard against NPE on arguments in TypeAnnotationParameter
Browse files Browse the repository at this point in the history
  • Loading branch information
timtebeek committed Feb 5, 2025
1 parent 21556e9 commit d2bc02a
Showing 1 changed file with 16 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
package org.openrewrite.hibernate;

import org.jspecify.annotations.Nullable;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Recipe;
import org.openrewrite.Tree;
import org.openrewrite.TreeVisitor;
import org.openrewrite.*;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.java.AnnotationMatcher;
import org.openrewrite.java.JavaIsoVisitor;
import org.openrewrite.java.JavaParser;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.search.UsesType;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JLeftPadded;
import org.openrewrite.java.tree.JavaType;
Expand All @@ -40,7 +38,8 @@

public class TypeAnnotationParameter extends Recipe {

private static final AnnotationMatcher FQN_TYPE_ANNOTATION = new AnnotationMatcher("@org.hibernate.annotations.Type");
private static final String ORG_HIBERNATE_ANNOTATIONS_TYPE = "org.hibernate.annotations.Type";
private static final AnnotationMatcher FQN_TYPE_ANNOTATION = new AnnotationMatcher("@" + ORG_HIBERNATE_ANNOTATIONS_TYPE);

@Override
public String getDisplayName() {
Expand All @@ -65,7 +64,7 @@ public String getDescription() {

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<ExecutionContext>() {
JavaIsoVisitor<ExecutionContext> visitor = new JavaIsoVisitor<ExecutionContext>() {
@Override
public J.@Nullable Annotation visitAnnotation(J.Annotation annotation, ExecutionContext ctx) {
J.Annotation a = super.visitAnnotation(annotation, ctx);
Expand All @@ -74,19 +73,19 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
}

// Remove entire annotation if type is one of the removed types
if (a.getArguments().stream().anyMatch(arg -> {
if (a.getArguments() != null && a.getArguments().stream().anyMatch(arg -> {
if (arg instanceof J.Assignment) {
J.Assignment assignment = (J.Assignment) arg;
if (assignment.getVariable() instanceof J.Identifier &&
"type".equals(((J.Identifier) assignment.getVariable()).getSimpleName()) &&
assignment.getAssignment() instanceof J.Literal) {
"type".equals(((J.Identifier) assignment.getVariable()).getSimpleName()) &&
assignment.getAssignment() instanceof J.Literal) {
String fqTypeName = (String) ((J.Literal) assignment.getAssignment()).getValue();
return REMOVED_FQNS.contains(fqTypeName);
}
}
return false;
})) {
maybeRemoveImport("org.hibernate.annotations.Type");
maybeRemoveImport(ORG_HIBERNATE_ANNOTATIONS_TYPE);
return null;
}

Expand All @@ -96,7 +95,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
if (temporalType.get() != null) {
maybeAddImport("jakarta.persistence.Temporal");
maybeAddImport("jakarta.persistence.TemporalType");
maybeRemoveImport("org.hibernate.annotations.Type");
maybeRemoveImport(ORG_HIBERNATE_ANNOTATIONS_TYPE);
return JavaTemplate.builder("@Temporal(TemporalType." + temporalType.get().toUpperCase() + ")")
.doBeforeParseTemplate(System.out::println)
.javaParser(JavaParser.fromJavaVersion().classpathFromResources(ctx, "jakarta.persistence-api"))
Expand All @@ -116,8 +115,8 @@ private AtomicReference<String> getTemporalTypeArgument(J.Annotation a) {
public J.Assignment visitAssignment(J.Assignment assignment, AtomicReference<String> ref) {
J.Assignment as = super.visitAssignment(assignment, ref);
if (J.Literal.isLiteralValue(as.getAssignment(), "date") ||
J.Literal.isLiteralValue(as.getAssignment(), "time") ||
J.Literal.isLiteralValue(as.getAssignment(), "timestamp")) {
J.Literal.isLiteralValue(as.getAssignment(), "time") ||
J.Literal.isLiteralValue(as.getAssignment(), "timestamp")) {
//noinspection DataFlowIssue
ref.set((String) ((J.Literal) as.getAssignment()).getValue());
}
Expand All @@ -128,14 +127,14 @@ public J.Assignment visitAssignment(J.Assignment assignment, AtomicReference<Str
}

private J.Annotation replaceArgumentWithClass(J.Annotation a) {
final boolean isOnlyParameter = a.getArguments().size() == 1;
final boolean isOnlyParameter = a.getArguments() != null && a.getArguments().size() == 1;
// Replace type parameter with value parameter
return a.withArguments(ListUtils.map(a.getArguments(), arg -> {
if (arg instanceof J.Assignment) {
J.Assignment assignment = (J.Assignment) arg;
if (assignment.getVariable() instanceof J.Identifier &&
"type".equals(((J.Identifier) assignment.getVariable()).getSimpleName()) &&
assignment.getAssignment() instanceof J.Literal) {
"type".equals(((J.Identifier) assignment.getVariable()).getSimpleName()) &&
assignment.getAssignment() instanceof J.Literal) {
String fqTypeName = (String) ((J.Literal) assignment.getAssignment()).getValue();
J.Identifier identifier = new J.Identifier(
Tree.randomId(),
Expand Down Expand Up @@ -164,6 +163,7 @@ private J.Annotation replaceArgumentWithClass(J.Annotation a) {
}));
}
};
return Preconditions.check(new UsesType<>(ORG_HIBERNATE_ANNOTATIONS_TYPE, false), visitor);
}

private static String getSimpleName(String fqName) {
Expand Down

0 comments on commit d2bc02a

Please sign in to comment.