diff --git a/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaSetsNewConcurrentHashSet.java b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaSetsNewConcurrentHashSet.java new file mode 100644 index 0000000000..d0c9238687 --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/guava/NoGuavaSetsNewConcurrentHashSet.java @@ -0,0 +1,65 @@ +/* + * Copyright 2021 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.guava; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.MethodMatcher; +import org.openrewrite.java.search.UsesMethod; +import org.openrewrite.java.tree.J; + +public class NoGuavaSetsNewConcurrentHashSet extends Recipe { + private static final MethodMatcher NEW_HASH_SET = new MethodMatcher("com.google.common.collect.Sets newConcurrentHashSet()"); + + @Override + public String getDisplayName() { + return "Construct a set from a `new ConcurrentHashMap<>()` instead of Guava"; + } + + @Override + public String getDescription() { + return "Prefer the Java standard library over third-party usage of Guava in simple cases like this."; + } + + @Override + protected TreeVisitor getApplicableTest() { + return new UsesMethod<>(NEW_HASH_SET); + } + + @Override + protected TreeVisitor getVisitor() { + return new JavaVisitor() { + private final JavaTemplate newConcurrentHashSet = template("Collections.newSetFromMap(new ConcurrentHashMap<>())") + .imports("java.util.Collections") + .imports("java.util.concurrent.ConcurrentHashMap") + .build(); + + @Override + public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext executionContext) { + if (NEW_HASH_SET.matches(method)) { + maybeRemoveImport("com.google.common.collect.Sets"); + maybeAddImport("java.util.Collections"); + maybeAddImport("java.util.concurrent.ConcurrentHashMap"); + return method.withTemplate(newConcurrentHashSet, method.getCoordinates().replace()); + } + return super.visitMethodInvocation(method, executionContext); + } + }; + } +} diff --git a/src/test/kotlin/org/openrewrite/java/migrate/guava/NoGuavaSetsNewConcurrentHashSetTest.kt b/src/test/kotlin/org/openrewrite/java/migrate/guava/NoGuavaSetsNewConcurrentHashSetTest.kt new file mode 100644 index 0000000000..930c60997b --- /dev/null +++ b/src/test/kotlin/org/openrewrite/java/migrate/guava/NoGuavaSetsNewConcurrentHashSetTest.kt @@ -0,0 +1,54 @@ +/* + * Copyright 2021 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.guava + +import org.junit.jupiter.api.Test +import org.openrewrite.Recipe +import org.openrewrite.java.JavaParser +import org.openrewrite.java.JavaRecipeTest + +class NoGuavaSetsNewConcurrentHashSetTest: JavaRecipeTest { + override val parser: JavaParser + get() = JavaParser.fromJavaVersion() + .logCompilationWarningsAndErrors(true) + .classpath("guava") + .build() + + override val recipe: Recipe + get() = NoGuavaSetsNewConcurrentHashSet() + + @Test + fun replaceWithNewConcurrentHashSet() = assertChanged( + before = """ + import com.google.common.collect.*; + + import java.util.Set; + + class Test { + Set cardinalsWorldSeries = Sets.newConcurrentHashSet(); + } + """, + after = """ + import java.util.Collections; + import java.util.Set; + import java.util.concurrent.ConcurrentHashMap; + + class Test { + Set cardinalsWorldSeries = Collections.newSetFromMap(new ConcurrentHashMap<>()); + } + """ + ) +}