From f43c8cef4f944b6cc1c925d8737514ea99d2db3a Mon Sep 17 00:00:00 2001 From: BhavanaPidapa <61456973+BhavanaPidapa@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:43:18 -0600 Subject: [PATCH] Recipe `IllegalArgumentExceptionToAlreadyConnectedException` (#615) * Generic Recipe to exception replacement based on method signature * Delete src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.java * Apply suggestions from code review Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> * Updating the recipe name * Dedicate Recipe as mentioned in comments. * Updated few changes in yml file * Restore ArrayStoreExceptionToTypeNotPresentExceptionTest * Split the tests to catch and rethrow the exception * Add now required import --------- Co-authored-by: bhavanapidapa Co-authored-by: Tim te Beek Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- ...tExceptionToAlreadyConnectedException.java | 66 +++++++ .../META-INF/rewrite/java-version-11.yml | 2 +- ...eptionToAlreadyConnectedExceptionTest.java | 166 ++++++++++++++++++ 3 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.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..a430e3723 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedException.java @@ -0,0 +1,66 @@ +/* + * 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.ExecutionContext; +import org.openrewrite.Preconditions; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +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.search.UsesMethod; +import org.openrewrite.java.tree.J; +import org.openrewrite.java.tree.TypeUtils; + +public class IllegalArgumentExceptionToAlreadyConnectedException extends Recipe { + + private static final String ILLEGAL_ARGUMENT_EXCEPTION = "java.lang.IllegalArgumentException"; + private static final String ALREADY_CONNECTED_EXCEPTION = "java.nio.channels.AlreadyConnectedException"; + + @Override + public String getDisplayName() { + return "Replace `IllegalArgumentException` with `AlreadyConnectedException` in `DatagramChannel.send()` method"; + } + + @Override + public String getDescription() { + return "Replace `IllegalArgumentException` with `AlreadyConnectedException` for DatagramChannel.send() to ensure compatibility with Java 11+."; + } + + @Override + public TreeVisitor getVisitor() { + String datagramChannelSendMethodPattern = "java.nio.channels.DatagramChannel send(java.nio.ByteBuffer, java.net.SocketAddress)"; + return Preconditions.check(new UsesMethod<>(datagramChannelSendMethodPattern), new JavaIsoVisitor() { + @Override + public J.Try visitTry(J.Try tryStatement, ExecutionContext ctx) { + J.Try try_ = super.visitTry(tryStatement, ctx); + if (FindMethods.find(try_, datagramChannelSendMethodPattern).isEmpty()) { + return try_; + } + return try_.withCatches(ListUtils.map(try_.getCatches(), catch_ -> { + if (TypeUtils.isOfClassType(catch_.getParameter().getType(), ILLEGAL_ARGUMENT_EXCEPTION)) { + maybeAddImport(ALREADY_CONNECTED_EXCEPTION); + return (J.Try.Catch) new ChangeType(ILLEGAL_ARGUMENT_EXCEPTION, ALREADY_CONNECTED_EXCEPTION, true) + .getVisitor().visit(catch_, ctx); + } + return catch_; + })); + } + }); + } +} 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..999637af8 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.IllegalArgumentExceptionToAlreadyConnectedException --- type: specs.openrewrite.org/v1beta/recipe @@ -290,4 +291,3 @@ recipeList: - org.openrewrite.java.ChangeMethodName: methodPattern: java.nio.file.Path get(..) newMethodName: of - 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..1fd0d0214 --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/IllegalArgumentExceptionToAlreadyConnectedExceptionTest.java @@ -0,0 +1,166 @@ +/* + * 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.recipe(new IllegalArgumentExceptionToAlreadyConnectedException()); + } + + @DocumentExample + @Test + void catchException() { + rewriteRun( + //language=java + java( + """ + import java.nio.ByteBuffer; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + class Test { + void sendDataCatch() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } catch (IllegalArgumentException e) { + System.out.println("Caught Exception"); + } + } + } + """, + """ + import java.nio.ByteBuffer; + import java.nio.channels.AlreadyConnectedException; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + class Test { + void sendDataCatch() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } catch (AlreadyConnectedException e) { + System.out.println("Caught Exception"); + } + } + } + """ + ) + ); + } + + @Test + void rethrowException() { + rewriteRun( + //language=java + java( + """ + import java.nio.ByteBuffer; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + class Test { + void sendDataRethrow() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException("DatagramChannel already connected to a different address"); + } + } + } + """, + """ + import java.nio.ByteBuffer; + import java.nio.channels.AlreadyConnectedException; + import java.net.SocketAddress; + import java.nio.channels.DatagramChannel; + + class Test { + void sendDataRethrow() { + try { + DatagramChannel channel = DatagramChannel.open(); + channel.send(ByteBuffer.allocate(1024), new java.net.InetSocketAddress("localhost", 8080)); + } 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; + + class Test { + 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 retainIllegalArgumentExceptionWithoutChannelSend() { + 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"); + } + } + } + """ + ) + ); + } +}