diff --git a/src/main/java/org/openrewrite/java/apache/httpclient4/MigrateDefaultHttpClient.java b/src/main/java/org/openrewrite/java/apache/httpclient4/MigrateDefaultHttpClient.java new file mode 100644 index 00000000..e33c940a --- /dev/null +++ b/src/main/java/org/openrewrite/java/apache/httpclient4/MigrateDefaultHttpClient.java @@ -0,0 +1,62 @@ +/* + * Copyright 2023 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.apache.httpclient4; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Preconditions; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.*; +import org.openrewrite.java.search.UsesType; +import org.openrewrite.java.tree.J; + +public class MigrateDefaultHttpClient extends Recipe { + @Override + public String getDisplayName() { + return "Migrates deprecated `DefaultHttpClient`"; + } + + @Override + public String getDescription() { + return "Since DefaultHttpClient is deprecated, we need to change it to the CloseableHttpClient. " + + "It only covers the default scenario with no custom HttpParams or ConnectionManager."; + } + + @Override + public TreeVisitor getVisitor() { + return Preconditions.check(new UsesType<>("org.apache.http.impl.client.DefaultHttpClient", false), new JavaVisitor() { + final MethodMatcher noArgsMatcher = new MethodMatcher("org.apache.http.impl.client.DefaultHttpClient ()"); + final JavaTemplate noArgsTemplate = JavaTemplate.builder("HttpClients.createDefault()") + .javaParser(JavaParser.fromJavaVersion().classpath("httpclient")) + .imports("org.apache.http.impl.client.HttpClients") + .build(); + + @Override + public J visitNewClass(J.NewClass newClass, ExecutionContext executionContext) { + if (noArgsMatcher.matches(newClass.getConstructorType())) { + maybeAddImport("org.apache.http.impl.client.HttpClients"); + doAfterVisit(new ChangeType( + "org.apache.http.impl.client.DefaultHttpClient", + "org.apache.http.impl.client.CloseableHttpClient", true + ).getVisitor()); + return noArgsTemplate.apply(getCursor(), newClass.getCoordinates().replace()); + } + return super.visitNewClass(newClass, executionContext); + } + }); + } + +} diff --git a/src/main/java/org/openrewrite/java/apache/httpclient4/package-info.java b/src/main/java/org/openrewrite/java/apache/httpclient4/package-info.java new file mode 100644 index 00000000..63b0bf7e --- /dev/null +++ b/src/main/java/org/openrewrite/java/apache/httpclient4/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2023 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. + */ +@NonNullApi @NonNullFields +package org.openrewrite.java.apache.httpclient4; + +import org.openrewrite.internal.lang.NonNullApi; +import org.openrewrite.internal.lang.NonNullFields; diff --git a/src/main/resources/META-INF/rewrite/apache-httpclient-4-5.yml b/src/main/resources/META-INF/rewrite/apache-httpclient-4-5.yml new file mode 100644 index 00000000..2bf4319d --- /dev/null +++ b/src/main/resources/META-INF/rewrite/apache-httpclient-4-5.yml @@ -0,0 +1,52 @@ +# +# Copyright 2023 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. +# + +######################################################################################################################## +# Apache HttpClient 4.5.x +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.openrewrite.java.apache.httpclient4.UpgradeApacheHttpClient_4_5 +displayName: Migrates to ApacheHttpClient 4.5.x +description: > + Migrate applications to the latest Apache HttpClient 4.5.x release. This recipe modifies + application's build files, make changes to deprecated/preferred APIs, and migrates configuration settings that have + changes between versions. +tags: + - apache + - httpclient +recipeList: + - org.openrewrite.java.dependencies.UpgradeDependencyVersion: + groupId: org.apache.httpcomponents + artifactId: httpclient + newVersion: 4.5.x + - org.openrewrite.java.apache.httpclient4.MappingDeprecatedClasses +--- +type: specs.openrewrite.org/v1beta/recipe +name: org.openrewrite.java.apache.httpclient4.MappingDeprecatedClasses +displayName: Maps deprecated classes from Apache HttpClient 4.5.x to suggested replacements +description: Uses new classes/methods instead of the deprecated ones +recipeList: + - org.openrewrite.java.ReplaceConstantWithAnotherConstant: + existingFullyQualifiedConstantName: org.apache.http.client.params.CookiePolicy.RFC_2109 + fullyQualifiedConstantName: org.apache.http.client.config.CookieSpecs.STANDARD + - org.openrewrite.java.ReplaceConstantWithAnotherConstant: + existingFullyQualifiedConstantName: org.apache.http.client.params.CookiePolicy.RFC_2965 + fullyQualifiedConstantName: org.apache.http.client.config.CookieSpecs.STANDARD_STRICT + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: org.apache.http.client.params.CookiePolicy + newFullyQualifiedTypeName: org.apache.http.client.config.CookieSpecs + - org.openrewrite.java.apache.httpclient4.MigrateDefaultHttpClient + diff --git a/src/main/resources/META-INF/rewrite/apache-httpclient-5.yml b/src/main/resources/META-INF/rewrite/apache-httpclient-5.yml index ba4190c9..ae4b74ca 100644 --- a/src/main/resources/META-INF/rewrite/apache-httpclient-5.yml +++ b/src/main/resources/META-INF/rewrite/apache-httpclient-5.yml @@ -28,19 +28,18 @@ tags: - apache - httpclient recipeList: + - org.openrewrite.java.apache.httpclient4.UpgradeApacheHttpClient_4_5 - org.openrewrite.java.dependencies.ChangeDependency: oldGroupId: org.apache.httpcomponents oldArtifactId: httpclient newGroupId: org.apache.httpcomponents.client5 newArtifactId: httpclient5 newVersion: 5.1.x - overrideManagedVersion: true - org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_ClassMapping - org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_DeprecatedMethods - org.openrewrite.java.apache.httpclient5.UseTimeout - org.openrewrite.java.apache.httpclient5.UseTimeValue - org.openrewrite.java.apache.httpclient5.StatusLine - --- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5_ClassMapping @@ -132,9 +131,11 @@ recipeList: - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.auth newPackageName: org.apache.hc.client5.http.auth + - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.cookie newPackageName: org.apache.hc.client5.http.cookie + - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.cookie newPackageName: org.apache.hc.client5.http.cookie @@ -142,9 +143,21 @@ recipeList: - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.annotation newPackageName: org.apache.hc.core5.annotation + - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.client.config newPackageName: org.apache.hc.client5.http.config + # Fixing deprecated constants + - org.openrewrite.java.ReplaceConstantWithAnotherConstant: + existingFullyQualifiedConstantName: org.apache.hc.client5.http.config.CookieSpecs.IGNORE_COOKIES + fullyQualifiedConstantName: org.apache.hc.client5.http.cookie.StandardCookieSpec.IGNORE + - org.openrewrite.java.ReplaceConstantWithAnotherConstant: + existingFullyQualifiedConstantName: org.apache.hc.client5.http.config.CookieSpecs.STANDARD + fullyQualifiedConstantName: org.apache.hc.client5.http.cookie.StandardCookieSpec.RELAXED + - org.openrewrite.java.ReplaceConstantWithAnotherConstant: + existingFullyQualifiedConstantName: org.apache.hc.client5.http.config.CookieSpecs.STANDARD_STRICT + fullyQualifiedConstantName: org.apache.hc.client5.http.cookie.StandardCookieSpec.STRICT + - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.annotation newPackageName: org.apache.hc.core5.annotation @@ -183,9 +196,11 @@ recipeList: - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.io newPackageName: org.apache.hc.core5.http.io + - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.message newPackageName: org.apache.hc.core5.http.message + - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.pool newPackageName: org.apache.hc.core5.pool @@ -255,6 +270,7 @@ recipeList: - org.openrewrite.java.ChangePackage: oldPackageName: org.apache.http.config newPackageName: org.apache.hc.core5.http.config + # Fixing specific mappings - org.openrewrite.java.ChangeType: oldFullyQualifiedTypeName: org.apache.hc.core5.http.config.SocketConfig newFullyQualifiedTypeName: org.apache.hc.core5.http.io.SocketConfig diff --git a/src/main/resources/META-INF/rewrite/classpath/httpclient-4.5.14.jar b/src/main/resources/META-INF/rewrite/classpath/httpclient-4.5.14.jar new file mode 100644 index 00000000..2bb7c073 Binary files /dev/null and b/src/main/resources/META-INF/rewrite/classpath/httpclient-4.5.14.jar differ diff --git a/src/main/resources/META-INF/rewrite/classpath/httpcore-4.4.16.jar b/src/main/resources/META-INF/rewrite/classpath/httpcore-4.4.16.jar new file mode 100644 index 00000000..f0bdebeb Binary files /dev/null and b/src/main/resources/META-INF/rewrite/classpath/httpcore-4.4.16.jar differ diff --git a/src/test/java/org/openrewrite/java/apache/httpclient4/CookieConstantsTest.java b/src/test/java/org/openrewrite/java/apache/httpclient4/CookieConstantsTest.java new file mode 100644 index 00000000..0f7675f3 --- /dev/null +++ b/src/test/java/org/openrewrite/java/apache/httpclient4/CookieConstantsTest.java @@ -0,0 +1,73 @@ +/* + * Copyright 2023 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.apache.httpclient4; + +import org.junit.jupiter.api.Test; +import org.openrewrite.config.Environment; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +public class CookieConstantsTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec + .parser(JavaParser.fromJavaVersion().classpath("httpclient", "httpcore")) + .recipe(Environment.builder() + .scanRuntimeClasspath("org.openrewrite") + .build() + .activateRecipes("org.openrewrite.java.apache.httpclient4.UpgradeApacheHttpClient_4_5") + ); + } + + @Test + void testCookieConstantsMapping() { + rewriteRun( + //language=java + java( + """ + import org.apache.http.client.params.CookiePolicy; + + class A { + void method() { + String c1 = CookiePolicy.BROWSER_COMPATIBILITY; + String c2 = CookiePolicy.NETSCAPE; + String c3 = CookiePolicy.RFC_2109; + String c4 = CookiePolicy.RFC_2965; + String c5 = CookiePolicy.BEST_MATCH; + String c6 = CookiePolicy.IGNORE_COOKIES; + } + } + """, """ + import org.apache.http.client.config.CookieSpecs; + + class A { + void method() { + String c1 = CookieSpecs.BROWSER_COMPATIBILITY; + String c2 = CookieSpecs.NETSCAPE; + String c3 = CookieSpecs.STANDARD; + String c4 = CookieSpecs.STANDARD_STRICT; + String c5 = CookieSpecs.BEST_MATCH; + String c6 = CookieSpecs.IGNORE_COOKIES; + } + } + """ + ) + ); + } +} diff --git a/src/test/java/org/openrewrite/java/apache/httpclient4/MigrateDefaultHttpClientTest.java b/src/test/java/org/openrewrite/java/apache/httpclient4/MigrateDefaultHttpClientTest.java new file mode 100644 index 00000000..ca2cbad9 --- /dev/null +++ b/src/test/java/org/openrewrite/java/apache/httpclient4/MigrateDefaultHttpClientTest.java @@ -0,0 +1,72 @@ +/* + * Copyright 2023 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.apache.httpclient4; + +import org.junit.jupiter.api.Test; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +public class MigrateDefaultHttpClientTest implements RewriteTest { + + @Override + public void defaults(RecipeSpec spec) { + spec + .parser(JavaParser.fromJavaVersion().classpath("httpclient", "httpcore")) + .recipe(new MigrateDefaultHttpClient()); + } + + @Test + void noArgsDefaultHttpClient() { + rewriteRun( + //language=java + java( + """ + import org.apache.http.HttpResponse; + import org.apache.http.client.methods.HttpPost; + import org.apache.http.impl.client.DefaultHttpClient; + + import java.io.IOException; + + class A { + void method() throws IOException { + DefaultHttpClient httpClient = new DefaultHttpClient(); + HttpPost httpPost = new HttpPost("https://moderne.io"); + HttpResponse httpResponse = httpClient.execute(httpPost); + } + } + """, """ + import org.apache.http.HttpResponse; + import org.apache.http.client.methods.HttpPost; + import org.apache.http.impl.client.CloseableHttpClient; + import org.apache.http.impl.client.HttpClients; + + import java.io.IOException; + + class A { + void method() throws IOException { + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost("https://moderne.io"); + HttpResponse httpResponse = httpClient.execute(httpPost); + } + } + """ + ) + ); + } +} diff --git a/src/test/java/org/openrewrite/java/apache/httpclient5/CookieConstantsTest.java b/src/test/java/org/openrewrite/java/apache/httpclient5/CookieConstantsTest.java new file mode 100644 index 00000000..de216514 --- /dev/null +++ b/src/test/java/org/openrewrite/java/apache/httpclient5/CookieConstantsTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2023 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.apache.httpclient5; + +import org.junit.jupiter.api.Test; +import org.openrewrite.config.Environment; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +public class CookieConstantsTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec + .parser(JavaParser.fromJavaVersion().classpath("httpclient", "httpcore", "httpclient5", "httpcore5")) + .recipe(Environment.builder() + .scanRuntimeClasspath("org.openrewrite") + .build() + .activateRecipes("org.openrewrite.java.apache.httpclient5.UpgradeApacheHttpClient_5") + ); + } + + @Test + void testCookieConstantsMapping() { + rewriteRun( + //language=java + java( + """ + import org.apache.http.client.config.CookieSpecs; + + class A { + void method() { + String c1 = CookieSpecs.IGNORE_COOKIES; + String c2 = CookieSpecs.STANDARD; + String c3 = CookieSpecs.STANDARD_STRICT; + } + } + """, """ + import org.apache.hc.client5.http.cookie.StandardCookieSpec; + + class A { + void method() { + String c1 = StandardCookieSpec.IGNORE; + String c2 = StandardCookieSpec.RELAXED; + String c3 = StandardCookieSpec.STRICT; + } + } + """ + ) + ); + } +}