From 7bd8c8288cb7e8c774f6a5287e0bfd5426284443 Mon Sep 17 00:00:00 2001 From: bhavanapidapa Date: Mon, 2 Dec 2024 14:39:22 -0600 Subject: [PATCH] Generic Recipe to exception replacement based on method signature --- ...tExceptionToAlreadyConnectedException.java | 2 + .../MethodExceptionReplacerRecipe.java | 78 +++++++++++ .../META-INF/rewrite/java-version-11.yml | 19 ++- ...xceptionToTypeNotPresentExceptionTest.java | 2 +- ...eptionToAlreadyConnectedExceptionTest.java | 126 ++++++++++++++++++ 5 files changed, 225 insertions(+), 2 deletions(-) create mode 100644 src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.java create mode 100644 src/main/java/org/openrewrite/java/migrate/MethodExceptionReplacerRecipe.java create mode 100644 src/test/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedExceptionTest.java diff --git a/src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.java b/src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.java new file mode 100644 index 000000000..bc95792fe --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.java @@ -0,0 +1,2 @@ +package org.openrewrite.java.migrate;public class IllegalArgumentExceptionToAlreadyConnectedException { +} diff --git a/src/main/java/org/openrewrite/java/migrate/MethodExceptionReplacerRecipe.java b/src/main/java/org/openrewrite/java/migrate/MethodExceptionReplacerRecipe.java new file mode 100644 index 000000000..c374427ba --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/MethodExceptionReplacerRecipe.java @@ -0,0 +1,78 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate; + +import org.openrewrite.*; +import org.openrewrite.internal.ListUtils; +import org.openrewrite.java.ChangeType; +import org.openrewrite.java.JavaIsoVisitor; +import org.openrewrite.java.search.FindMethods; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.TypeUtils; + +import java.util.Map; + +public class MethodExceptionReplacerRecipe extends Recipe { + private final Map> methodToExceptionMapping; + + public MethodExceptionReplacerRecipe(Map> methodToExceptionMapping) { + this.methodToExceptionMapping = methodToExceptionMapping; + } + + @Override + public String getDisplayName() { + return "Generic Recipe to Exception Replacement based on method signatures"; + } + + @Override + public String getDescription() { + return "This recipe replaces specified exceptions with other exceptions based on method signatures."; + } + + @Override + public TreeVisitor getVisitor() { + return new JavaIsoVisitor() { + + @Override + public J.Try visitTry(J.Try tryStatement, ExecutionContext ctx) { + J.Try try_ = super.visitTry(tryStatement, ctx); + + for (Map.Entry> entry : methodToExceptionMapping.entrySet()) { + String methodPattern = entry.getKey(); + Map exceptionMapping = entry.getValue(); + + if (FindMethods.find(try_, methodPattern).isEmpty()) { + continue; + } + + for (Map.Entry exceptionEntry : exceptionMapping.entrySet()) { + String oldException = exceptionEntry.getKey(); + String newException = exceptionEntry.getValue(); + try_ = try_.withCatches(ListUtils.map(try_.getCatches(), catch_ -> { + if (TypeUtils.isOfClassType(catch_.getParameter().getType(), oldException)) { + return (J.Try.Catch) new ChangeType(oldException, newException, true) + .getVisitor().visit(catch_, ctx); + } + return catch_; + })); + } + } + + return try_; + } + }; + } +} diff --git a/src/main/resources/META-INF/rewrite/java-version-11.yml b/src/main/resources/META-INF/rewrite/java-version-11.yml index 2ce31ac4a..e85aab456 100644 --- a/src/main/resources/META-INF/rewrite/java-version-11.yml +++ b/src/main/resources/META-INF/rewrite/java-version-11.yml @@ -74,6 +74,7 @@ recipeList: - org.openrewrite.java.migrate.ReplaceComSunAWTUtilitiesMethods - org.openrewrite.java.migrate.ReplaceLocalizedStreamMethods - org.openrewrite.java.migrate.ArrayStoreExceptionToTypeNotPresentException + - org.openrewrite.java.migrate.MethodExceptionReplacerRecipe --- type: specs.openrewrite.org/v1beta/recipe @@ -290,4 +291,20 @@ recipeList: - org.openrewrite.java.ChangeMethodName: methodPattern: java.nio.file.Path get(..) newMethodName: of - +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.openrewrite.java.migrate.MethodExceptionReplacerRecipe +displayName: Replace `javax.security.auth.Policy` with `java.security.Policy` +description: The `javax.security.auth.Policy` class is not available from Java SE 11 onwards. +tags: + - java11 +recipeList: + - org.openrewrite.java.migrate.MethodExceptionReplacerRecipe: + methodToExceptionMapping: + "java.nio.channels.DatagramChannel send(java.nio.ByteBuffer, java.net.SocketAddress)": + "java.lang.IllegalArgumentException": "java.nio.channels.AlreadyConnectedException" + - org.openrewrite.java.migrate.MethodExceptionReplacerRecipe: + methodToExceptionMapping: + "java.lang.Class getAnnotation(java.lang.Class)": + "java.lang.ArrayStoreException": "java.lang.TypeNotPresentException" +--- diff --git a/src/test/java/org/openrewrite/java/migrate/ArrayStoreExceptionToTypeNotPresentExceptionTest.java b/src/test/java/org/openrewrite/java/migrate/ArrayStoreExceptionToTypeNotPresentExceptionTest.java index 4843e8981..e403f3634 100644 --- a/src/test/java/org/openrewrite/java/migrate/ArrayStoreExceptionToTypeNotPresentExceptionTest.java +++ b/src/test/java/org/openrewrite/java/migrate/ArrayStoreExceptionToTypeNotPresentExceptionTest.java @@ -26,7 +26,7 @@ class ArrayStoreExceptionToTypeNotPresentExceptionTest implements RewriteTest { @Override public void defaults(RecipeSpec spec) { - spec.recipe(new ArrayStoreExceptionToTypeNotPresentException()); + spec.recipeFromResources("org.openrewrite.java.migrate.MethodExceptionReplacerRecipe"); } @DocumentExample diff --git a/src/test/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedExceptionTest.java b/src/test/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedExceptionTest.java new file mode 100644 index 000000000..d5c631219 --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedExceptionTest.java @@ -0,0 +1,126 @@ +/* + * Copyright 2024 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * https://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.openrewrite.java.migrate; + +import org.junit.jupiter.api.Test; +import org.openrewrite.DocumentExample; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +class IllegalArgumentExceptionToAlreadyConnectedExceptionTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec.recipeFromResources("org.openrewrite.java.migrate.MethodExceptionReplacerRecipe"); + } + + @DocumentExample + @Test + void replaceCaughtException() { + rewriteRun( + //language=java + java( + """ + import java.nio.ByteBuffer; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + public class Test { + public void sendData() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } catch (IllegalArgumentException e) { + System.out.println("Caught Exception"); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("DatagramChannel already connected to a different address"); + } + } + } + """, + """ + import java.nio.ByteBuffer; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + public class Test { + public void sendData() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } catch (AlreadyConnectedException e) { + System.out.println("Caught Exception"); + } catch (AlreadyConnectedException e) { + throw new AlreadyConnectedException("DatagramChannel already connected to a different address"); + } + } + } + """ + ) + ); + } + + @Test + void retainOtherCaughtExceptions() { + rewriteRun( + //language=java + java( + """ + import java.io.IOException;import java.nio.ByteBuffer; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + public class Test { + public void sendData() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } catch (IOException e) { + System.out.println("Caught Exception"); + } + } + } + """ + ) + ); + } + + @Test + void retainIllegalArgumentExceptionWithoutChannelSendAnnotation() { + rewriteRun( + //language=java + java( + """ + import java.nio.ByteBuffer; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + public class Test { + public void sendData() { + try { + DatagramChannel channel = DatagramChannel.open(); + } catch (IllegalArgumentException e) { + System.out.println("Caught Exception"); + } + } + } + """ + ) + ); + } +}