Skip to content

Commit

Permalink
Generic Recipe to exception replacement based on method signature
Browse files Browse the repository at this point in the history
  • Loading branch information
bhavanapidapa committed Dec 2, 2024
1 parent 59d56a6 commit 7bd8c82
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package org.openrewrite.java.migrate;public class IllegalArgumentExceptionToAlreadyConnectedException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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<String, Map<String, String>> methodToExceptionMapping;

public MethodExceptionReplacerRecipe(Map<String, Map<String, String>> 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<?, ExecutionContext> getVisitor() {
return new JavaIsoVisitor<ExecutionContext>() {

@Override
public J.Try visitTry(J.Try tryStatement, ExecutionContext ctx) {
J.Try try_ = super.visitTry(tryStatement, ctx);

for (Map.Entry<String, Map<String, String>> entry : methodToExceptionMapping.entrySet()) {
String methodPattern = entry.getKey();
Map<String, String> exceptionMapping = entry.getValue();

if (FindMethods.find(try_, methodPattern).isEmpty()) {
continue;
}

for (Map.Entry<String, String> 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_;
}
};
}
}
19 changes: 18 additions & 1 deletion src/main/resources/META-INF/rewrite/java-version-11.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
---
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright 2024 the original author or authors.
* <p>
* 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
* <p>
* https://www.apache.org/licenses/LICENSE-2.0
* <p>
* 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");
}
}
}
"""
)
);
}
}

0 comments on commit 7bd8c82

Please sign in to comment.