Skip to content

Commit 42fde6d

Browse files
committed
Get constant value
1 parent f4a58a6 commit 42fde6d

File tree

2 files changed

+144
-133
lines changed

2 files changed

+144
-133
lines changed

src/main/java/org/openrewrite/java/migrate/net/URLConstructorsToURI.java

Lines changed: 68 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,24 @@
1515
*/
1616
package org.openrewrite.java.migrate.net;
1717

18+
import fj.data.Option;
19+
import org.jspecify.annotations.Nullable;
1820
import org.openrewrite.ExecutionContext;
19-
import org.openrewrite.ScanningRecipe;
21+
import org.openrewrite.Recipe;
2022
import org.openrewrite.TreeVisitor;
21-
import org.openrewrite.java.*;
23+
import org.openrewrite.analysis.constantfold.ConstantFold;
24+
import org.openrewrite.analysis.util.CursorUtil;
25+
import org.openrewrite.java.JavaParser;
26+
import org.openrewrite.java.JavaTemplate;
27+
import org.openrewrite.java.JavaVisitor;
28+
import org.openrewrite.java.MethodMatcher;
2229
import org.openrewrite.java.tree.Expression;
2330
import org.openrewrite.java.tree.J;
2431
import org.openrewrite.java.tree.JavaType;
25-
import org.openrewrite.java.tree.Statement;
2632

2733
import java.net.URI;
28-
import java.util.HashSet;
29-
import java.util.List;
30-
import java.util.Set;
3134

32-
public class URLConstructorsToURI extends ScanningRecipe<Set<String>> {
35+
public class URLConstructorsToURI extends Recipe {
3336
@Override
3437
public String getDisplayName() {
3538
return "Convert `new URL(String)` to `URI.create(String).toURL()`";
@@ -41,88 +44,25 @@ public String getDescription() {
4144
}
4245

4346
@Override
44-
public Set<String> getInitialValue(ExecutionContext ctx) {
45-
return new HashSet<>();
46-
}
47-
48-
@Override
49-
public TreeVisitor<?, ExecutionContext> getScanner(Set<String> wrapperMethodClasses) {
50-
return new JavaIsoVisitor<ExecutionContext>() {
51-
private final MethodMatcher methodMatcherSingleArg = new MethodMatcher("java.net.URL <constructor>(java.lang.String)");
52-
53-
@Override
54-
public J.NewClass visitNewClass(J.NewClass nc, ExecutionContext ctx) {
55-
if (methodMatcherSingleArg.matches(nc)) {
56-
Expression arg = nc.getArguments().get(0);
57-
if (!(arg instanceof J.Literal && arg.getType().toString().equals("String"))) {
58-
J.ClassDeclaration cd = getCursor().firstEnclosing(J.ClassDeclaration.class);
59-
if (cd != null) {
60-
wrapperMethodClasses.add(cd.getType().getFullyQualifiedName());
61-
}
62-
}
63-
}
64-
return super.visitNewClass(nc, ctx);
65-
}
66-
};
67-
}
68-
69-
@Override
70-
public TreeVisitor<?, ExecutionContext> getVisitor(Set<String> wrapperMethodClasses) {
47+
public TreeVisitor<?, ExecutionContext> getVisitor() {
7148
return new JavaVisitor<ExecutionContext>() {
7249
private final MethodMatcher methodMatcherSingleArg = new MethodMatcher("java.net.URL <constructor>(java.lang.String)");
7350
private final MethodMatcher methodMatcherThreeArg = new MethodMatcher("java.net.URL <constructor>(java.lang.String, java.lang.String, java.lang.String)");
7451
private final MethodMatcher methodMatcherFourArg = new MethodMatcher("java.net.URL <constructor>(java.lang.String, java.lang.String, int, java.lang.String)");
75-
JavaType.Method methodType;
76-
77-
78-
@Override
79-
public J visitClassDeclaration(J.ClassDeclaration cd, ExecutionContext ctx) {
80-
boolean wrapperMethodExists = cd.getBody()
81-
.getStatements()
82-
.stream()
83-
.filter(J.MethodDeclaration.class::isInstance)
84-
.map(J.MethodDeclaration.class::cast)
85-
.anyMatch(md -> md.getSimpleName().equals("transformNonLiteralURIToValidURL"));
86-
87-
if (!wrapperMethodExists && wrapperMethodClasses.contains(cd.getType().getFullyQualifiedName())) {
88-
JavaTemplate convertUriMethod = JavaTemplate.builder(
89-
"public URL transformNonLiteralURIToValidURL(String spec) {\n" +
90-
" try {\n" +
91-
" return URI.create(spec).toURL();\n" +
92-
" } catch (Exception e) {\n" +
93-
" return new URL(spec);\n" +
94-
" }\n" +
95-
"}")
96-
.contextSensitive()
97-
.imports("java.net.URI", "java.net.URL")
98-
.javaParser(JavaParser.fromJavaVersion())
99-
.build();
100-
maybeAddImport("java.net.URI");
101-
102-
cd = convertUriMethod.apply(updateCursor(cd), cd.getBody().getCoordinates().lastStatement());
103-
104-
List<Statement> statements = cd.getBody().getStatements();
105-
J.MethodDeclaration md = (J.MethodDeclaration) statements.get(statements.size() - 1);
106-
methodType = md.getMethodType();
107-
}
108-
return super.visitClassDeclaration(cd, ctx);
109-
}
11052

11153
@Override
11254
public J visitNewClass(J.NewClass nc, ExecutionContext ctx) {
113-
J.MethodDeclaration enclosingMethod = getCursor().firstEnclosing(J.MethodDeclaration.class);
114-
if (enclosingMethod != null && enclosingMethod.getSimpleName().equals("transformNonLiteralURIToValidURL")) {
115-
return super.visitNewClass(nc, ctx);
116-
}
117-
11855
if (methodMatcherSingleArg.matches(nc)) {
11956
Expression arg = nc.getArguments().get(0);
12057

121-
if (arg instanceof J.Literal && arg.getType().toString().equals("String")) {
122-
// If the argument is a string literal, only convert the constructor if the argument is a valid input
58+
if (arg instanceof J.Literal) {
59+
// Check if the literal is of type String
60+
if (!arg.getType().toString().equals("String")) {
61+
return nc;
62+
}
12363

64+
// Check if value is null
12465
String literalValue = ((J.Literal) arg).getValueSource();
125-
12666
if (literalValue == null) {
12767
return nc;
12868
}
@@ -133,39 +73,47 @@ public J visitNewClass(J.NewClass nc, ExecutionContext ctx) {
13373

13474

13575
// Check that this string is a valid input for URI.create().toURL()
136-
try {
137-
//noinspection ResultOfMethodCallIgnored
138-
URI.create(literalValue).toURL();
139-
} catch (Exception e) {
76+
if (isNotValidPath(literalValue)) {
77+
return nc;
78+
}
79+
80+
} else if (arg instanceof J.Identifier) {
81+
// Check if type is String
82+
JavaType type = arg.getType();
83+
if (type == null || !type.toString().equals("java.lang.String")) {
84+
return nc;
85+
}
86+
87+
88+
// Check if constant value is valid
89+
String constantValue = null;
90+
Option<String> constant = CursorUtil.findCursorForTree(getCursor(), arg)
91+
.bind(c -> ConstantFold.findConstantLiteralValue(c, String.class));
92+
93+
if (constant.isSome()) {
94+
constantValue = constant.some();
95+
}
96+
97+
if (isNotValidPath(constantValue)) {
14098
return nc;
14199
}
142100

143-
JavaTemplate template = JavaTemplate.builder("URI.create(#{any(String)}).toURL()")
144-
.imports("java.net.URI")
145-
.contextSensitive()
146-
.javaParser(JavaParser.fromJavaVersion())
147-
.build();
148-
149-
J result = template.apply(getCursor(),
150-
nc.getCoordinates().replace(),
151-
nc.getArguments().get(0));
152-
maybeAddImport("java.net.URI");
153-
return result;
154101
} else {
155-
// If the argument is not a string literal, replace the constructor with the wrapper method
156-
JavaTemplate template = JavaTemplate.builder("transformNonLiteralURIToValidURL(#{any(String)})")
157-
.imports("java.net.URI")
158-
.contextSensitive()
159-
.javaParser(JavaParser.fromJavaVersion())
160-
.build();
161-
J.MethodInvocation result = template.apply(updateCursor(nc), nc.getCoordinates().replace(), nc.getArguments().get(0));
162-
result = result.withMethodType(methodType);
163-
J.Identifier name = result.getName();
164-
name = name.withType(methodType);
165-
result = result.withName(name);
166-
maybeAddImport("java.net.URI");
167-
return result;
102+
return nc;
168103
}
104+
105+
JavaTemplate template = JavaTemplate.builder("URI.create(#{any(String)}).toURL()")
106+
.imports("java.net.URI")
107+
.contextSensitive()
108+
.javaParser(JavaParser.fromJavaVersion())
109+
.build();
110+
111+
J result = template.apply(getCursor(),
112+
nc.getCoordinates().replace(),
113+
nc.getArguments().get(0));
114+
maybeAddImport("java.net.URI");
115+
116+
return result;
169117
} else if (methodMatcherThreeArg.matches(nc)) {
170118
JavaTemplate template = JavaTemplate.builder("new URI(#{any(String)}, null, #{any(String)}, -1, #{any(String)}, null, null).toURL()")
171119
.imports("java.net.URI", "java.net.URL")
@@ -198,4 +146,19 @@ public J visitNewClass(J.NewClass nc, ExecutionContext ctx) {
198146
}
199147
};
200148
}
149+
150+
private static boolean isNotValidPath(@Nullable String path) {
151+
if (path == null) {
152+
return true;
153+
}
154+
155+
try {
156+
//noinspection ResultOfMethodCallIgnored
157+
URI.create(path).toURL();
158+
} catch (Exception e) {
159+
return true;
160+
}
161+
162+
return false;
163+
}
201164
}

src/test/java/org/openrewrite/java/migrate/net/URLConstructorsToURITest.java

Lines changed: 76 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -53,27 +53,18 @@ void urlConstructor(String spec) throws Exception {
5353
5454
class Test {
5555
void urlConstructor(String spec) throws Exception {
56-
URL url1 = transformNonLiteralURIToValidURL(spec);
56+
URL url1 = new URL(spec);
5757
URL url2 = new URI(spec, null, "localhost", -1, "file", null, null).toURL();
5858
URL url3 = new URI(spec, null, "localhost", 8080, "file", null, null).toURL();
5959
}
60-
61-
public URL transformNonLiteralURIToValidURL(String spec) {
62-
try {
63-
return URI.create(spec).toURL();
64-
} catch (Exception e) {
65-
return new URL(spec);
66-
}
67-
}
6860
}
6961
"""
7062
)
7163
);
7264
}
7365

7466
@Test
75-
@DocumentExample
76-
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/191")
67+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/620")
7768
void urlCheckAbsolutePath() {
7869
rewriteRun(
7970
//language=java
@@ -82,7 +73,7 @@ void urlCheckAbsolutePath() {
8273
import java.net.URL;
8374
8475
class Test {
85-
void urlConstructor(String spec) throws Exception {
76+
void urlConstructor() {
8677
URL url1 = new URL("https://test.com");
8778
}
8879
}
@@ -92,7 +83,7 @@ void urlConstructor(String spec) throws Exception {
9283
import java.net.URL;
9384
9485
class Test {
95-
void urlConstructor(String spec) throws Exception {
86+
void urlConstructor() {
9687
URL url1 = URI.create("https://test.com").toURL();
9788
}
9889
}
@@ -102,8 +93,61 @@ void urlConstructor(String spec) throws Exception {
10293
}
10394

10495
@Test
105-
@DocumentExample
106-
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/191")
96+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/620")
97+
void urlCheckConstantAbsolutePath() {
98+
rewriteRun(
99+
//language=java
100+
java(
101+
"""
102+
import java.net.URL;
103+
104+
class Test {
105+
private String goodURL = "https://test.com";
106+
private String badURL = "not/valid/url";
107+
void urlConstructor() {
108+
URL url1 = new URL(goodURL);
109+
}
110+
}
111+
""",
112+
"""
113+
import java.net.URI;
114+
import java.net.URL;
115+
116+
class Test {
117+
private String goodURL = "https://test.com";
118+
private String badURL = "not/valid/url";
119+
void urlConstructor() {
120+
URL url1 = URI.create(goodURL).toURL();
121+
}
122+
}
123+
"""
124+
)
125+
);
126+
}
127+
128+
@Test
129+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/620")
130+
void urlCheckConstantRelativePath() {
131+
rewriteRun(
132+
//language=java
133+
java(
134+
"""
135+
import java.net.URL;
136+
137+
class Test {
138+
private String goodURL = "https://test.com";
139+
private String badURL = "not/valid/url";
140+
void urlConstructor() {
141+
URL url1 = new URL(badURL);
142+
}
143+
}
144+
"""
145+
)
146+
);
147+
}
148+
149+
@Test
150+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/620")
107151
void urlCheckRelativePath() {
108152
rewriteRun(
109153
spec -> spec.expectedCyclesThatMakeChanges(0),
@@ -113,7 +157,7 @@ void urlCheckRelativePath() {
113157
import java.net.URL;
114158
115159
class Test {
116-
void urlConstructor(String spec) throws Exception {
160+
void urlConstructor() {
117161
URL url1 = new URL("TEST-INF/test/testCase.wsdl");
118162
}
119163
}
@@ -123,8 +167,7 @@ void urlConstructor(String spec) throws Exception {
123167
}
124168

125169
@Test
126-
@DocumentExample
127-
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/191")
170+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/620")
128171
void urlCheckNullPath() {
129172
rewriteRun(
130173
//language=java
@@ -133,26 +176,31 @@ void urlCheckNullPath() {
133176
import java.net.URL;
134177
135178
class Test {
136-
void urlConstructor(String spec) throws Exception {
179+
void urlConstructor() {
137180
URL url1 = new URL(null);
138181
}
139182
}
140-
""",
183+
"""
184+
)
185+
);
186+
}
187+
188+
@Test
189+
@Issue("https://github.com/openrewrite/rewrite-migrate-java/issues/620")
190+
void urlCheckMethodInvocationParameter() {
191+
rewriteRun(
192+
//language=java
193+
java(
141194
"""
142-
import java.net.URI;
143195
import java.net.URL;
144196
145197
class Test {
146198
void urlConstructor(String spec) throws Exception {
147-
URL url1 = transformNonLiteralURIToValidURL(null);
199+
URL url1 = new URL(getString());
148200
}
149201
150-
public URL transformNonLiteralURIToValidURL(String spec) {
151-
try {
152-
return URI.create(spec).toURL();
153-
} catch (Exception e) {
154-
return new URL(spec);
155-
}
202+
String getString() {
203+
return "myURL";
156204
}
157205
}
158206
"""

0 commit comments

Comments
 (0)