diff --git a/src/main/java/org/openrewrite/java/migrate/jakarta/UpdateGetRealPath.java b/src/main/java/org/openrewrite/java/migrate/jakarta/UpdateGetRealPath.java new file mode 100644 index 0000000000..e321ba209c --- /dev/null +++ b/src/main/java/org/openrewrite/java/migrate/jakarta/UpdateGetRealPath.java @@ -0,0 +1,59 @@ +/* + * 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.migrate.jakarta; + +import org.openrewrite.ExecutionContext; +import org.openrewrite.Recipe; +import org.openrewrite.TreeVisitor; +import org.openrewrite.java.JavaParser; +import org.openrewrite.java.JavaTemplate; +import org.openrewrite.java.JavaVisitor; +import org.openrewrite.java.MethodMatcher; +import org.openrewrite.java.tree.J; + +public class UpdateGetRealPath extends Recipe { + @Override + public String getDisplayName() { + return "Updates `getRealPath()` to call `getContext()` followed by `getRealPath()`"; + } + + @Override + public String getDescription() { + return "Updates `getRealPath()` for `jakarta.servlet.ServletRequest` and `jakarta.servlet.ServletRequestWrapper` to use `ServletContext.getRealPath(String)`."; + } + + @Override + public TreeVisitor getVisitor() { + return new JavaVisitor() { + private final MethodMatcher METHOD_PATTERN = new MethodMatcher("jakarta.servlet.ServletRequest* getRealPath(String)", false); + + @Override + public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, ExecutionContext ec) { + if (METHOD_PATTERN.matches(method)) { + return JavaTemplate.builder("#{any()}.getServletContext().getRealPath(#{any(String)})") + .javaParser(JavaParser.fromJavaVersion().classpathFromResources(ec, "jakarta.servlet-api-6.0.0")) + .build() + .apply(updateCursor(method), + method.getCoordinates().replace(), + method.getSelect(), + method.getArguments().get(0)); + } + return method; + } + }; + } +} diff --git a/src/main/resources/META-INF/rewrite/jakarta-ee-10.yml b/src/main/resources/META-INF/rewrite/jakarta-ee-10.yml index e30dfd4f01..d75f7fe778 100644 --- a/src/main/resources/META-INF/rewrite/jakarta-ee-10.yml +++ b/src/main/resources/META-INF/rewrite/jakarta-ee-10.yml @@ -27,6 +27,7 @@ recipeList: - org.openrewrite.java.migrate.jakarta.RemovedSOAPElementFactory - org.openrewrite.java.migrate.jakarta.WsWsocServerContainerDeprecation - org.openrewrite.java.migrate.jakarta.ServletCookieBehaviorChangeRFC6265 + - org.openrewrite.java.migrate.jakarta.RemovalsServletJakarta10 - org.openrewrite.java.migrate.jakarta.DeprecatedCDIAPIsRemoved40 - org.openrewrite.java.migrate.BeanDiscovery - org.openrewrite.java.migrate.jakarta.BeanValidationMessages @@ -53,7 +54,6 @@ recipeList: methodPattern: jakarta.servlet.SessionCookieConfig getComment() - org.openrewrite.java.migrate.RemoveMethodInvocation: methodPattern: jakarta.servlet.SessionCookieConfig setComment(String) - --- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.migrate.jakarta.WsWsocServerContainerDeprecation @@ -63,11 +63,9 @@ recipeList: - org.openrewrite.java.ChangeMethodName: methodPattern: com.ibm.websphere.wsoc.WsWsocServerContainer doUpgrade(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, com.ibm.websphere.wsoc.ServerEndpointConfig, java.util.Map) newMethodName: upgradeHttpToWebSocket - ignoreDefinition: true - org.openrewrite.java.ChangeType: oldFullyQualifiedTypeName: com.ibm.websphere.wsoc.WsWsocServerContainer newFullyQualifiedTypeName: jakarta.websocket.server.ServerContainer - ignoreDefinition: true --- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.migrate.jakarta.RemovedIsParmetersProvidedMethod @@ -79,7 +77,6 @@ recipeList: - org.openrewrite.java.ChangeMethodName: methodPattern: jakarta.el.MethodExpression isParmetersProvided() newMethodName: isParametersProvided - ignoreDefinition: true --- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.migrate.jakarta.RemovedSOAPElementFactory @@ -91,15 +88,12 @@ recipeList: - org.openrewrite.java.ChangeMethodName: methodPattern: jakarta.xml.soap.SOAPElementFactory create(String,..) newMethodName: createElement - ignoreDefinition: true - org.openrewrite.java.ChangeMethodName: methodPattern: jakarta.xml.soap.SOAPElementFactory create(jakarta.xml.soap.Name) newMethodName: createElement - ignoreDefinition: true - org.openrewrite.java.ChangeType: oldFullyQualifiedTypeName: jakarta.xml.soap.SOAPElementFactory newFullyQualifiedTypeName: jakarta.xml.soap.SOAPFactory - ignoreDefinition: true --- type: specs.openrewrite.org/v1beta/recipe name: org.openrewrite.java.migrate.jakarta.JavaxBeansXmlToJakartaBeansXml @@ -127,6 +121,86 @@ recipeList: newValue: https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_4_0.xsd --- type: specs.openrewrite.org/v1beta/recipe +name: org.openrewrite.java.migrate.jakarta.RemovalsServletJakarta10 +displayName: Replace deprecated Jakarta Servlet methods and classes +description: > + This recipe replaces the classes and methods deprecated in Jakarta Servlet 6.0 +recipeList: + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.http.HttpServletRequest + newFullyQualifiedTypeName: jakarta.servlet.http.HttpServletRequest + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.http.HttpServletRequestWrapper + newFullyQualifiedTypeName: jakarta.servlet.http.HttpServletRequestWrapper + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.http.HttpServletResponse + newFullyQualifiedTypeName: jakarta.servlet.http.HttpServletResponse + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.http.HttpServletResponseWrapper + newFullyQualifiedTypeName: jakarta.servlet.http.HttpServletResponseWrapper + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.http.HttpSession + newFullyQualifiedTypeName: jakarta.servlet.http.HttpSession + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.ServletContext + newFullyQualifiedTypeName: jakarta.servlet.ServletContext + - org.openrewrite.java.ChangeType: + oldFullyQualifiedTypeName: javax.servlet.UnavailableException + newFullyQualifiedTypeName: jakarta.servlet.UnavailableException + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpServletRequest isRequestedSessionIdFromUrl() + newMethodName: isRequestedSessionIdFromURL + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpServletRequestWrapper isRequestedSessionIdFromUrl() + newMethodName: isRequestedSessionIdFromURL + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpServletResponse encodeUrl(String) + newMethodName: encodeURL + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpServletResponseWrapper encodeUrl(String) + newMethodName: encodeURL + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpServletResponse encodeRedirectUrl(String) + newMethodName: encodeRedirectURL + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpServletResponseWrapper encodeRedirectUrl(String)" + newMethodName: encodeRedirectURL + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpSession getValue(String) + newMethodName: getAttribute + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpSession getValueNames() + newMethodName: getAttributeNames + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpSession putValue(String, Object) + newMethodName: setAttribute + - org.openrewrite.java.ChangeMethodName: + methodPattern: jakarta.servlet.http.HttpSession removeValue(String) + newMethodName: removeAttribute + - org.openrewrite.java.DeleteMethodArgument: + methodPattern: jakarta.servlet.http.HttpServletResponse setStatus(int, String) + argumentIndex: 1 + - org.openrewrite.java.DeleteMethodArgument: + methodPattern: jakarta.servlet.http.HttpServletResponseWrapper setStatus(int, String) + argumentIndex: 1 + - org.openrewrite.java.ReorderMethodArguments: + methodPattern: jakarta.servlet.ServletContext log(Exception, String) + newParameterNames: [ ex, str ] + oldParameterNames: [ str, ex ] + matchOverrides: true + - org.openrewrite.java.migrate.jakarta.UpdateGetRealPath + - org.openrewrite.java.DeleteMethodArgument: + methodPattern: jakarta.servlet.UnavailableException (jakarta.servlet.Servlet, String) + argumentIndex: 0 + - org.openrewrite.java.DeleteMethodArgument: + methodPattern: jakarta.servlet.UnavailableException (int, jakarta.servlet.Servlet, String) + argumentIndex: 1 + - org.openrewrite.java.ReorderMethodArguments: + methodPattern: jakarta.servlet.UnavailableException (int, String) + oldParameterNames: [ in, str ] + newParameterNames: [ str, in ] + matchOverrides: true +--- name: org.openrewrite.java.migrate.jakarta.DeprecatedCDIAPIsRemoved40 displayName: Remove deprecated API's not supported in CDI4.0 description: > diff --git a/src/test/java/org/openrewrite/java/migrate/jakarta/RemovalsServletJakarta10Test.java b/src/test/java/org/openrewrite/java/migrate/jakarta/RemovalsServletJakarta10Test.java new file mode 100644 index 0000000000..3224397a72 --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/jakarta/RemovalsServletJakarta10Test.java @@ -0,0 +1,190 @@ +/* + * 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.migrate.jakarta; + +import org.junit.jupiter.api.Test; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +class RemovalsServletJakarta10Test implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec.parser(JavaParser.fromJavaVersion() + .classpathFromResources(new InMemoryExecutionContext(), + "javax.servlet-api-4.0.0", + "jakarta.servlet-api-5.0.0", + "jakarta.servlet-api-6.0.0")) + .recipeFromResource("/META-INF/rewrite/jakarta-ee-10.yml", "org.openrewrite.java.migrate.jakarta.RemovalsServletJakarta10"); + } + + @Test + void servletReplacements() { + rewriteRun( + //language=java + java( + """ + import java.io.IOException; + + import jakarta.servlet.ServletContext; + import jakarta.servlet.ServletException; + import jakarta.servlet.SingleThreadModel; + import jakarta.servlet.UnavailableException; + import jakarta.servlet.http.HttpServlet; + import jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletRequestWrapper; + import jakarta.servlet.http.HttpServletResponse; + import jakarta.servlet.http.HttpServletResponseWrapper; + import jakarta.servlet.http.HttpSession; + import jakarta.servlet.http.HttpSessionContext; + import jakarta.servlet.http.HttpUtils; + + class TestJakarta extends HttpServlet implements SingleThreadModel { + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + req.isRequestedSessionIdFromUrl(); + + res.encodeUrl(""); + res.encodeRedirectUrl(""); + + res.setStatus(0, ""); + + res.setStatus(0); + + HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(req); + reqWrapper.isRequestedSessionIdFromUrl(); + + HttpServletResponseWrapper resWrapper = new HttpServletResponseWrapper(res); + + resWrapper.encodeUrl(""); + resWrapper.encodeRedirectUrl(""); + + resWrapper.setStatus(0, ""); + + HttpSession httpSession = req.getSession(); + httpSession.getSessionContext(); + httpSession.getValue(""); + httpSession.getValueNames(); + httpSession.putValue("", null); + httpSession.removeValue(""); + + ServletContext servletContext = getServletContext(); + + servletContext.getServlet(""); + servletContext.getServlets(); + servletContext.getServletNames(); + + servletContext.log(null, ""); + } + } + """, + """ + import java.io.IOException; + + import jakarta.servlet.ServletContext; + import jakarta.servlet.ServletException; + import jakarta.servlet.SingleThreadModel; + import jakarta.servlet.UnavailableException; + import jakarta.servlet.http.HttpServlet; + import jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletRequestWrapper; + import jakarta.servlet.http.HttpServletResponse; + import jakarta.servlet.http.HttpServletResponseWrapper; + import jakarta.servlet.http.HttpSession; + import jakarta.servlet.http.HttpSessionContext; + import jakarta.servlet.http.HttpUtils; + + class TestJakarta extends HttpServlet implements SingleThreadModel { + protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { + req.isRequestedSessionIdFromURL(); + + res.encodeURL(""); + res.encodeRedirectURL(""); + + res.setStatus(0); + + res.setStatus(0); + + HttpServletRequestWrapper reqWrapper = new HttpServletRequestWrapper(req); + reqWrapper.isRequestedSessionIdFromURL(); + + HttpServletResponseWrapper resWrapper = new HttpServletResponseWrapper(res); + + resWrapper.encodeURL(""); + resWrapper.encodeRedirectURL(""); + + resWrapper.setStatus(0); + + HttpSession httpSession = req.getSession(); + httpSession.getSessionContext(); + httpSession.getAttribute(""); + httpSession.getAttributeNames(); + httpSession.setAttribute("", null); + httpSession.removeAttribute(""); + + ServletContext servletContext = getServletContext(); + + servletContext.getServlet(""); + servletContext.getServlets(); + servletContext.getServletNames(); + + servletContext.log("", null); + } + } + """ + ) + ); + } + + @Test + void unavailableException() { + rewriteRun( + //language=java + java( + """ + import jakarta.servlet.UnavailableException; + import jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletResponse; + + class Test { + void doGet(HttpServletRequest req, HttpServletResponse res) throws Exception { + jakarta.servlet.Servlet servlet ; + UnavailableException unavailableEx1 = new UnavailableException(0, null, "x"); + UnavailableException unavailableEx2 = new UnavailableException(0, servlet, "x"); + UnavailableException unavailableEx3 = new UnavailableException(servlet, "x"); + } + } + """, + """ + import jakarta.servlet.UnavailableException; + import jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletResponse; + + class Test { + void doGet(HttpServletRequest req, HttpServletResponse res) throws Exception { + jakarta.servlet.Servlet servlet ; + UnavailableException unavailableEx1 = new UnavailableException("x", 0); + UnavailableException unavailableEx2 = new UnavailableException("x", 0); + UnavailableException unavailableEx3 = new UnavailableException( "x"); + } + } + """ + ) + ); + } +} diff --git a/src/test/java/org/openrewrite/java/migrate/jakarta/UpdateGetRealPathTest.java b/src/test/java/org/openrewrite/java/migrate/jakarta/UpdateGetRealPathTest.java new file mode 100644 index 0000000000..ae8e7533ee --- /dev/null +++ b/src/test/java/org/openrewrite/java/migrate/jakarta/UpdateGetRealPathTest.java @@ -0,0 +1,63 @@ +/* + * 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.jakarta; + +import org.junit.jupiter.api.Test; +import org.openrewrite.InMemoryExecutionContext; +import org.openrewrite.java.JavaParser; +import org.openrewrite.test.RecipeSpec; +import org.openrewrite.test.RewriteTest; + +import static org.openrewrite.java.Assertions.java; + +class UpdateGetRealPathTest implements RewriteTest { + @Override + public void defaults(RecipeSpec spec) { + spec.parser(JavaParser.fromJavaVersion() + .classpathFromResources(new InMemoryExecutionContext(), + "jakarta.servlet-api-5.0.0")) + .recipe(new UpdateGetRealPath()); + } + + @Test + void servletReplacements() { + rewriteRun( + //language=java + java( + """ + import jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletRequestWrapper; + class Foo { + void bar(HttpServletRequest request, HttpServletRequestWrapper wrapper) throws Exception { + request.getRealPath(""); + wrapper.getRealPath(""); + } + } + """, + """ + import jakarta.servlet.http.HttpServletRequest; + import jakarta.servlet.http.HttpServletRequestWrapper; + class Foo { + void bar(HttpServletRequest request, HttpServletRequestWrapper wrapper) throws Exception { + request.getServletContext().getRealPath(""); + wrapper.getServletContext().getRealPath(""); + } + } + """ + ) + ); + } +} \ No newline at end of file diff --git a/src/test/resources/META-INF/rewrite/classpath/jakarta.servlet-api-5.0.0.jar b/src/test/resources/META-INF/rewrite/classpath/jakarta.servlet-api-5.0.0.jar new file mode 100644 index 0000000000..88b788a0bf Binary files /dev/null and b/src/test/resources/META-INF/rewrite/classpath/jakarta.servlet-api-5.0.0.jar differ diff --git a/src/test/resources/META-INF/rewrite/classpath/javax.servlet-api-4.0.0.jar b/src/test/resources/META-INF/rewrite/classpath/javax.servlet-api-4.0.0.jar new file mode 100644 index 0000000000..9c9f4b7f6a Binary files /dev/null and b/src/test/resources/META-INF/rewrite/classpath/javax.servlet-api-4.0.0.jar differ