Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CDI recipe #340

Merged
merged 38 commits into from
Jan 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
ac34dd2
partial cdi recipe
AnuRam123 Nov 7, 2023
6c5e0cd
completed CDI recipe
AnuRam123 Nov 7, 2023
48061f9
add back ticks for code
AnuRam123 Nov 7, 2023
e1072c8
remove public class from test classes
AnuRam123 Nov 7, 2023
730d337
updated tests with isNullable and BeanDiscovery method
AnuRam123 Nov 8, 2023
954f8b6
updated recipes based on my comments
cjobinabo Nov 9, 2023
b624d7c
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Nov 15, 2023
92bbacf
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Nov 16, 2023
7ba16f4
minor refactor
cjobinabo Nov 16, 2023
cbfe7e7
convert isNullable to false and simplify logic
cjobinabo Nov 16, 2023
19bce8b
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Nov 20, 2023
1a5524b
Test RemoveBeanIsNullable separately and simplify implementation
timtebeek Nov 20, 2023
359f7b2
Restore jakarta-ee-10.yml
timtebeek Nov 20, 2023
e185033
Merge branch 'openrewrite:main' into jakarta_ee10_CDI
ranuradh Nov 20, 2023
fdd6b2c
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Nov 27, 2023
87ef9a2
Apply missing license
timtebeek Nov 27, 2023
7ac0ae1
Restore missing type
timtebeek Nov 27, 2023
3b93dfd
remove annotation and clean up code
AnuRam123 Nov 28, 2023
48914e8
fixes the diff failure.
cjobinabo Nov 28, 2023
4448fe4
reverting to not use templete in getEvent
AnuRam123 Nov 28, 2023
bce6039
fixed test
cjobinabo Nov 28, 2023
4cccdbf
remove template comment
AnuRam123 Nov 28, 2023
ddd40a4
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Dec 11, 2023
fbc45b9
Merge branch 'main' into jakarta_ee10_CDI
ranuradh Jan 9, 2024
9e26317
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Jan 17, 2024
41e54de
Merge branch 'main' into jakarta_ee10_CDI
cjobinabo Jan 19, 2024
e8f44e7
should resolve tests
cjobinabo Jan 19, 2024
360b481
Add no args constructors to reduce test log output
timtebeek Jan 19, 2024
2938411
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Jan 22, 2024
1da61b2
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Jan 28, 2024
701fb68
Minor polish
timtebeek Jan 30, 2024
69b6659
Add individual unit tests to flush out issues
timtebeek Jan 30, 2024
64fb591
Add individual unit tests to flush out issues
timtebeek Jan 30, 2024
f3f82f9
Remove DeprecatedCDIAPIsRemoved40Test as it duplicates others
timtebeek Jan 30, 2024
83b6afa
Drop `FacesManagedBeansRemoved` that had moved to `jakarta-faces-4.yml`
timtebeek Jan 30, 2024
701e46b
Further minimize tests
timtebeek Jan 30, 2024
a466098
Only keep one copy of classpath resource jar
timtebeek Jan 30, 2024
65f1728
Merge branch 'main' into jakarta_ee10_CDI
timtebeek Jan 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/*
* Copyright 2023 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.jakarta;

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Option;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.lang.NonNull;
import org.openrewrite.java.JavaTemplate;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.tree.J;

@Value
@EqualsAndHashCode(callSuper = true)
public class UpdateAddAnnotatedType extends Recipe {

@Option(displayName = "Method Pattern", description = "A method pattern for matching required method definition.", example = "jakarta.enterprise.inject.spi.BeforeBeanDiscovery addAnnotatedType(jakarta.enterprise.inject.spi.AnnotatedType)")
@NonNull String methodPattern;
String TEMPLATE_STRING_JAKARTA = "jakarta.enterprise.inject.spi.AnnotatedType";
String TEMPLATE_STRING_JAVAX = "javax.enterprise.inject.spi.AnnotatedType";

@Override
public String getDisplayName() {
return "Replace `addAnnotatedType(AnnotatedType)` with `addAnnotatedType(AnnotatedType,String)`";
}

@Override
public String getDescription() {
return "BeforeBeanDiscovery.addAnnotatedType(AnnotatedType) is Deprecated in CDI 1.1. It is Replaced by BeforeBeanDiscovery.addAnnotatedType(AnnotatedType, String).";
timtebeek marked this conversation as resolved.
Show resolved Hide resolved
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
MethodMatcher METHOD_INPUT_PATTERN = new MethodMatcher(methodPattern, false);
String templateBuilderString = null;
if (methodPattern.contains("jakarta.enterprise.inject.spi.")) {
templateBuilderString = TEMPLATE_STRING_JAKARTA;
} else if (methodPattern.contains("javax.enterprise.inject.spi.")) {
templateBuilderString = TEMPLATE_STRING_JAVAX;
}
String finalTemplateBuilderString = templateBuilderString;
return new JavaVisitor<ExecutionContext>() {
@Override
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
if (METHOD_INPUT_PATTERN.matches(method)) {
String tempString = "#{any(" + finalTemplateBuilderString + ")},null\"";
//"#{any(jakarta.enterprise.inject.spi.AnnotatedType)},null"
timtebeek marked this conversation as resolved.
Show resolved Hide resolved
return JavaTemplate.builder(tempString).build().apply(updateCursor(method), method.getCoordinates().replaceArguments(), method.getArguments().get(0));
}
return super.visitMethodInvocation(method, ctx);
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2023 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.jakarta;

import lombok.EqualsAndHashCode;
import lombok.Value;
import org.jetbrains.annotations.NotNull;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Option;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.internal.lang.NonNull;
import org.openrewrite.internal.lang.Nullable;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;

@Value
@EqualsAndHashCode(callSuper = false)
public class UpdateBeanManagerMethod extends Recipe {
@Option(displayName = "Method Pattern",
description = "A `BeanManager.fireEvent()` or `BeanManager.createInjectionTarget()` matching required",
example = "jakarta.enterprise.inject.spi.BeanManager fireEvent()")
@NonNull String methodPattern;

@Override
public @NotNull String getDisplayName() {
ranuradh marked this conversation as resolved.
Show resolved Hide resolved
return "Update fireEvent() and createInjectionTarget() calls";
}

@Override
public @NotNull String getDescription() {
return " Updates `BeanManager.fireEvent()` or `BeanManager.createInjectionTarget()`";
}

@Override
public @NotNull TreeVisitor<?, ExecutionContext> getVisitor() {
return new MethodInvocationVisitor(methodPattern);
}

private static class MethodInvocationVisitor extends JavaVisitor<ExecutionContext> {
private final MethodMatcher METHOD_PATTERN;

private MethodInvocationVisitor(String methodPattern) {
METHOD_PATTERN = new MethodMatcher(methodPattern, false);
}

@Nullable
@Override
public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ec) {
String newMethodName = "";
if (METHOD_PATTERN.matches(method)) {
if (method.getSimpleName().equals("fireEvent")){
newMethodName = "getEvent()." + "fire";
}
else if (method.getSimpleName().equals("createInjectionTarget")){
newMethodName = "getInjectionTargetFactory()." + "createInjectionTarget";
}
// newMethodName = newMethodName + method.getSimpleName();
JavaType.Method type = method.getMethodType();
if (type != null) {
type = type.withName(newMethodName);
}
method = method.withName(method.getName().withSimpleName(newMethodName)).withMethodType(type);
}
return method;
}
}
}
17 changes: 17 additions & 0 deletions src/main/resources/META-INF/rewrite/jakarta-ee-10.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ recipeList:
- org.openrewrite.java.migrate.jakarta.RemovedUIComponentConstant
- org.openrewrite.java.migrate.jakarta.WsWsocServerContainerDeprecation
- org.openrewrite.java.migrate.jakarta.ServletCookieBehaviorChangeRFC6265
- org.openrewrite.java.migrate.jakarta.DeprecatedCDIAPIsRemoved40
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.java.migrate.jakarta.ServletCookieBehaviorChangeRFC6265
Expand Down Expand Up @@ -253,3 +254,19 @@ recipeList:
oldFullyQualifiedTypeName: javax.faces.el.ReferenceSyntaxException
newFullyQualifiedTypeName: jakarta.el.ELException
ignoreDefinition: true
---
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.java.migrate.jakarta.DeprecatedCDIAPIsRemoved40
displayName: Remove deprecated API's not supported in CDI4.0
description: >
Deprecated APIs have been removed in CDI 4.0. This recipe removes and updates the corresponding deprecated methods.
recipeList:
- org.openrewrite.java.migrate.jakarta.RemoveMethods:
methodPattern: jakarta.enterprise.inject.spi.Bean isNullable()
- org.openrewrite.java.migrate.jakarta.UpdateAddAnnotatedType:
methodPattern: jakarta.enterprise.inject.spi.BeforeBeanDiscovery addAnnotatedType(jakarta.enterprise.inject.spi.AnnotatedType)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UpdateAddAnnotatedType is only used once, yet the implementation seems to switch between two types of method patterns. Should it be used once more? Or can we simplify the implementation to only support a single case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timtebeek I added the javax case as well .Should be there in the final commit.

- org.openrewrite.java.migrate.jakarta.UpdateBeanManagerMethod:
methodPattern: "jakarta.enterprise.inject.spi.BeanManager fireEvent(..)"
- org.openrewrite.java.migrate.jakarta.UpdateBeanManagerMethod:
methodPattern: "jakarta.enterprise.inject.spi.BeanManager createInjectionTarget(..)"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than one big test to verify three different Java recipes, as well as some yaml configuration, I'd prefer to see a unit test class per Java recipe; That helps make it clear what each recipe contributes, and allows one to jump from the implementation directly to the associated tests rather than having to deduce that from usage in yaml files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@timtebeek will do that from the next recipe. This one just would up like that

timtebeek marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
* Copyright 2023 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.jakarta;

import org.junit.jupiter.api.Test;
import org.openrewrite.InMemoryExecutionContext;
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 DeprecatedCDIAPIsRemoved40Test implements RewriteTest {
timtebeek marked this conversation as resolved.
Show resolved Hide resolved
@Override
public void defaults(RecipeSpec spec) {
spec
.parser(JavaParser.fromJavaVersion()
.classpathFromResources(new InMemoryExecutionContext(), "jakarta.enterprise.cdi-api-3.0.0-M4","jakarta.enterprise.cdi-api-4.0.1"))
.recipe(Environment.builder()
.scanRuntimeClasspath("org.openrewrite.java.migrate.jakarta").build()
.activateRecipes("org.openrewrite.java.migrate.jakarta.DeprecatedCDIAPIsRemoved40"));
}

@Test
void updateCDI() {
rewriteRun(
//language=java
java("""
package sample.cdi;

import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.New;
import jakarta.enterprise.inject.spi.AnnotatedType;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.Extension;
import java.util.Set;

public class JakartaCdiMethods implements Extension {

public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) {
ranuradh marked this conversation as resolved.
Show resolved Hide resolved
System.out.println("SPI registered extention beforeBeanDiscovery has been fired");
AnnotatedType<String> producerType = beanManager.createAnnotatedType(String.class);

beforeBeanDiscovery.addAnnotatedType(producerType); // Flag this one
beforeBeanDiscovery.addAnnotatedType(producerType, "my unique id"); // Not this one
beforeBeanDiscovery.addAnnotatedType(String.class, "my other unique id"); // Not this one

beanManager.createInjectionTarget(producerType);

beanManager.fireEvent(beforeBeanDiscovery);

Set<Bean<?>> myBeans = beanManager.getBeans("my precious beans");
Bean myFavoriteBean = myBeans.stream().findFirst().get();
myFavoriteBean.isNullable();
timtebeek marked this conversation as resolved.
Show resolved Hide resolved
}
}
""", """
package sample.cdi;

import jakarta.enterprise.event.Observes;
import jakarta.enterprise.inject.New;
import jakarta.enterprise.inject.spi.AnnotatedType;
import jakarta.enterprise.inject.spi.Bean;
import jakarta.enterprise.inject.spi.BeanManager;
import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
import jakarta.enterprise.inject.spi.Extension;
import java.util.Set;

public class JakartaCdiMethods implements Extension {

public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager) {
System.out.println("SPI registered extention beforeBeanDiscovery has been fired");
AnnotatedType<String> producerType = beanManager.createAnnotatedType(String.class);

beforeBeanDiscovery.addAnnotatedType(producerType, null); // Flag this one
beforeBeanDiscovery.addAnnotatedType(producerType, "my unique id"); // Not this one
beforeBeanDiscovery.addAnnotatedType(String.class, "my other unique id"); // Not this one

beanManager.getInjectionTargetFactory().createInjectionTarget(producerType);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getInjectionTargetFactory needs to take in the annotatedType which was previous passed to createInjectionTarget
Screenshot 2023-11-07 at 1 07 27 PM

createInjectionTarget would take in null. Here are some examples I've seen of this code being used https://www.tabnine.com/code/java/methods/javax.enterprise.inject.spi.BeanManager/getInjectionTargetFactory

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldnt get this to work as well since if the arguments are right I was using the simpleName change and that worked..now we need to add different arguments to the methods as well. I updated the test

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I'll look into both updates


beanManager.getEvent().fire(beforeBeanDiscovery);

Set<Bean<?>> myBeans = beanManager.getBeans("my precious beans");
Bean myFavoriteBean = myBeans.stream().findFirst().get();
}
}
"""));
}
}
Binary file not shown.
Binary file not shown.
Loading