diff --git a/astra-core/src/main/java/org/alfasoftware/astra/core/refactoring/operations/annotations/AnnotationChangeRefactor.java b/astra-core/src/main/java/org/alfasoftware/astra/core/refactoring/operations/annotations/AnnotationChangeRefactor.java index 4c0e899..25eb80f 100644 --- a/astra-core/src/main/java/org/alfasoftware/astra/core/refactoring/operations/annotations/AnnotationChangeRefactor.java +++ b/astra-core/src/main/java/org/alfasoftware/astra/core/refactoring/operations/annotations/AnnotationChangeRefactor.java @@ -1,7 +1,6 @@ package org.alfasoftware.astra.core.refactoring.operations.annotations; import java.io.IOException; -import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Optional; @@ -32,6 +31,8 @@ *
  * com.google.inject.Inject -> javax.inject.Inject.
  * 
+ * By default the import for an annotation will be swapped over.
+ * If this is not required use {@link Builder#forceQualifiedName()}.
  */
 public class AnnotationChangeRefactor implements ASTOperation {
 
@@ -47,8 +48,11 @@ public class AnnotationChangeRefactor implements ASTOperation {
   private final Map memberNameUpdates;
   private final Map memberNamesToUpdateWithNewValues;
   private final Optional transform;
+  private final boolean forceQualifiedName;
 
-  public AnnotationChangeRefactor(AnnotationMatcher fromType, String toType, Map membersAndValuesToAdd, Map memberAndTypesToAdd, Set namesForMembersToRemove, Map memberNameUpdates, Map memberNamesToUpdateWithNewValues, Optional transform) {
+  public AnnotationChangeRefactor(AnnotationMatcher fromType, String toType, Map membersAndValuesToAdd,
+      Map memberAndTypesToAdd, Set namesForMembersToRemove, Map memberNameUpdates,
+      Map memberNamesToUpdateWithNewValues, Optional transform, boolean forceQualifiedName) {
     this.fromType = fromType;
     this.toType = toType;
     this.membersAndValuesToAdd = membersAndValuesToAdd;
@@ -57,6 +61,7 @@ public AnnotationChangeRefactor(AnnotationMatcher fromType, String toType, Map memberNameUpdates = Map.of();
     private Optional transform = Optional.empty();
     private Map memberNamesToUpdateWithNewValues = Map.of();
+    private boolean forceQualifiedName;
 
     private Builder() {
       super();
@@ -132,6 +138,17 @@ public Builder withTransform(Transform transform) {
       return this;
     }
 
+    /**
+     * Forces use of the qualified name for the annotation.
+     * This is helpful if not all instances of an annotation are going to be replaced.
+     *
+     * @return this for method chaining
+     */
+    public Builder forceQualifiedName() {
+      this.forceQualifiedName = true;
+      return this;
+    }
+
     public AnnotationChangeRefactor build() {
       return new AnnotationChangeRefactor(fromType,
               toType,
@@ -140,8 +157,10 @@ public AnnotationChangeRefactor build() {
               namesForMembersToRemove,
               memberNameUpdates,
               memberNamesToUpdateWithNewValues,
-              transform);
+              transform,
+              forceQualifiedName);
     }
+
   }
 
 
@@ -162,7 +181,7 @@ public void run(CompilationUnit compilationUnit, ASTNode node, ASTRewrite rewrit
             + "to [" + toType + "] "
             + "in [" + AstraUtils.getNameForCompilationUnit(compilationUnit) + "]");
 
-        if (! AstraUtils.getSimpleName(toType).equals(AstraUtils.getSimpleName(annotation.getTypeName().getFullyQualifiedName()))) {
+        if (!forceQualifiedName && !annotation.getTypeName().isQualifiedName()) {
           AstraUtils.updateImport(compilationUnit, fromType.getFullyQualifiedName(), toType, rewriter);
         }
 
@@ -193,7 +212,7 @@ private void rewriteAnnotation(CompilationUnit compilationUnit, Annotation annot
 
   private Annotation changeAnnotationName(ASTRewrite rewriter, Annotation annotation) {
     Name name;
-    if (annotation.getTypeName().isQualifiedName()) {
+    if (forceQualifiedName || annotation.getTypeName().isQualifiedName()) {
       name = annotation.getAST().newName(toType);
     } else {
       name = annotation.getAST().newSimpleName(AstraUtils.getSimpleName(toType));
diff --git a/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameExample.java b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameExample.java
new file mode 100644
index 0000000..6460ee7
--- /dev/null
+++ b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameExample.java
@@ -0,0 +1,15 @@
+package org.alfasoftware.astra.core.refactoring.annotations;
+
+import org.alfasoftware.astra.exampleTypes.AnnotationA;
+
+@AnnotationA("")
+public class AnnotationChangeSameSimpleNameExample {
+
+    @AnnotationA(value="A")
+    protected long someField;
+
+    @AnnotationA("BAR")
+    public char getBar(){
+        return 'a';
+    }
+}
diff --git a/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameExampleAfter.java b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameExampleAfter.java
new file mode 100644
index 0000000..06ba75e
--- /dev/null
+++ b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameExampleAfter.java
@@ -0,0 +1,15 @@
+package org.alfasoftware.astra.core.refactoring.annotations;
+
+import org.alfasoftware.astra.moreexampletypes.AnnotationA;
+
+@AnnotationA("")
+public class AnnotationChangeSameSimpleNameExampleAfter {
+
+    @AnnotationA(value="A")
+    protected long someField;
+
+    @AnnotationA("BAR")
+    public char getBar(){
+        return 'a';
+    }
+}
diff --git a/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameWithRemainderExample.java b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameWithRemainderExample.java
new file mode 100644
index 0000000..e45632c
--- /dev/null
+++ b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameWithRemainderExample.java
@@ -0,0 +1,18 @@
+package org.alfasoftware.astra.core.refactoring.annotations;
+
+import org.alfasoftware.astra.exampleTypes.AnnotationA;
+
+@AnnotationA("")
+public class AnnotationChangeSameSimpleNameWithRemainderExample {
+
+    /**
+     * This annotation should not change
+     */
+    @AnnotationA(value="A")
+    protected long someField;
+
+    @AnnotationA("BAR")
+    public char getBar(){
+        return 'a';
+    }
+}
diff --git a/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameWithRemainderExampleAfter.java b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameWithRemainderExampleAfter.java
new file mode 100644
index 0000000..9e4b582
--- /dev/null
+++ b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/AnnotationChangeSameSimpleNameWithRemainderExampleAfter.java
@@ -0,0 +1,18 @@
+package org.alfasoftware.astra.core.refactoring.annotations;
+
+import org.alfasoftware.astra.exampleTypes.AnnotationA;
+
+@org.alfasoftware.astra.moreexampletypes.AnnotationA("")
+public class AnnotationChangeSameSimpleNameWithRemainderExampleAfter {
+
+    /**
+     * This annotation should not change
+     */
+    @AnnotationA(value="A")
+    protected long someField;
+
+    @org.alfasoftware.astra.moreexampletypes.AnnotationA("BAR")
+    public char getBar(){
+        return 'a';
+    }
+}
diff --git a/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/TestAnnotationsRefactor.java b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/TestAnnotationsRefactor.java
index e17ad22..3d37d1f 100644
--- a/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/TestAnnotationsRefactor.java
+++ b/astra-core/src/test/java/org/alfasoftware/astra/core/refactoring/annotations/TestAnnotationsRefactor.java
@@ -1,5 +1,7 @@
 package org.alfasoftware.astra.core.refactoring.annotations;
 
+import static org.alfasoftware.astra.core.utils.AstraUtils.addImport;
+
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.Map;
@@ -22,8 +24,6 @@
 import org.eclipse.jdt.core.dom.TypeDeclaration;
 import org.junit.Test;
 
-import static org.alfasoftware.astra.core.utils.AstraUtils.addImport;
-
 public class TestAnnotationsRefactor extends AbstractRefactorTest {
 
   @Test
@@ -91,6 +91,60 @@ public void testAnnotationChange() {
       )));
   }
 
+  @Test
+  public void testSameSimpleNameAnnotationChange() {
+    assertRefactor(
+      AnnotationChangeSameSimpleNameExample.class,
+      new HashSet<>(Arrays.asList(
+        AnnotationChangeRefactor.builder()
+          .from(AnnotationMatcher.builder()
+            .withFullyQualifiedName(AnnotationA.class.getName())
+            .withValue("")
+            .build())
+          .to(org.alfasoftware.astra.moreexampletypes.AnnotationA.class.getTypeName()).build(),
+        AnnotationChangeRefactor.builder()
+          .from(AnnotationMatcher.builder()
+            .withFullyQualifiedName(AnnotationA.class.getName())
+            .withValue("A")
+            .build())
+          .to(org.alfasoftware.astra.moreexampletypes.AnnotationA.class.getTypeName()).build(),
+        AnnotationChangeRefactor.builder()
+          .from(AnnotationMatcher.builder()
+            .withFullyQualifiedName(AnnotationA.class.getName())
+            .withValue("BAR")
+            .build())
+          .to(org.alfasoftware.astra.moreexampletypes.AnnotationA.class.getTypeName()).build()
+      )));
+  }
+
+  /**
+   * Example where we are not swapping over all instances of an annotation with the same simple name
+   * therefore we force the new annotation to be fully qualified.
+   */
+  @Test
+  public void testSameSimpleNameAnnotationChangeWithRemainder() {
+    assertRefactor(
+      AnnotationChangeSameSimpleNameWithRemainderExample.class,
+      new HashSet<>(Arrays.asList(
+        AnnotationChangeRefactor.builder()
+          .from(AnnotationMatcher.builder()
+            .withFullyQualifiedName(AnnotationA.class.getName())
+            .withValue("")
+            .build())
+          .to(org.alfasoftware.astra.moreexampletypes.AnnotationA.class.getTypeName())
+          .forceQualifiedName()
+          .build(),
+        AnnotationChangeRefactor.builder()
+          .from(AnnotationMatcher.builder()
+            .withFullyQualifiedName(AnnotationA.class.getName())
+            .withValue("BAR")
+            .build())
+          .to(org.alfasoftware.astra.moreexampletypes.AnnotationA.class.getTypeName())
+          .forceQualifiedName()
+          .build()
+      )));
+  }
+
   @Test
   public void testRemoveAnnotation() {
     assertRefactor(
diff --git a/astra-core/src/test/java/org/alfasoftware/astra/moreexampletypes/AnnotationA.java b/astra-core/src/test/java/org/alfasoftware/astra/moreexampletypes/AnnotationA.java
new file mode 100644
index 0000000..a485e26
--- /dev/null
+++ b/astra-core/src/test/java/org/alfasoftware/astra/moreexampletypes/AnnotationA.java
@@ -0,0 +1,9 @@
+package org.alfasoftware.astra.moreexampletypes;
+
+public @interface AnnotationA {
+
+  String value() default "";
+
+  String othervalue() default "";
+}
+