Skip to content

Commit 522c320

Browse files
nmck257Nick McKinneytimtebeek
authored
Refactored ConvertToSecurityDslVisitor to assemble target method type… (#465)
* Refactored ConvertToSecurityDslVisitor to assemble target method types "manually" instead of searching for them on some existing type's available methods, to fix a bug where ApplyToWithLambdaDsl did not work for projects parsed with an older version of Spring Security (aka the expected case for apps using the recipe to upgrade) * Rename methods from find to create now that we don't look up --------- Co-authored-by: Nick McKinney <[email protected]> Co-authored-by: Tim te Beek <[email protected]>
1 parent 8478040 commit 522c320

File tree

1 file changed

+29
-28
lines changed

1 file changed

+29
-28
lines changed

src/main/java/org/openrewrite/java/spring/boot2/ConvertToSecurityDslVisitor.java

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ public class ConvertToSecurityDslVisitor<P> extends JavaIsoVisitor<P> {
3939

4040
public static final String FQN_CUSTOMIZER = "org.springframework.security.config.Customizer";
4141

42+
private static final JavaType.FullyQualified CUSTOMIZER_SHALLOW_TYPE =
43+
(JavaType.ShallowClass) JavaType.buildType(FQN_CUSTOMIZER);
44+
4245
private final String securityFqn;
4346

4447
private final Collection<String> convertableMethods;
@@ -79,7 +82,7 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation initialMethod
7982
J.MethodInvocation method = super.visitMethodInvocation(initialMethod, executionContext);
8083
if (isApplicableMethod(method)) {
8184
J.MethodInvocation m = method;
82-
method = findDesiredReplacement(method)
85+
method = createDesiredReplacement(method)
8386
.map(newMethodType -> {
8487
List<J.MethodInvocation> chain = computeAndMarkChain();
8588
boolean keepArg = keepArg(m.getSimpleName());
@@ -89,9 +92,9 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation initialMethod
8992
.withName(m.getName().withSimpleName(newMethodType.getName()))
9093
.withArguments(ListUtils.concat(
9194
keepArg ? m.getArguments().get(0) : null,
92-
Collections.singletonList(chain.isEmpty()
93-
? createDefaultsCall(newMethodType.getParameterTypes().get(keepArg ? 1 : 0))
94-
: createLambdaParam(paramName, newMethodType.getParameterTypes().get(keepArg ? 1 : 0), chain))
95+
Collections.singletonList(chain.isEmpty() ?
96+
createDefaultsCall() :
97+
createLambdaParam(paramName, newMethodType.getParameterTypes().get(keepArg ? 1 : 0), chain))
9598
)
9699
);
97100
})
@@ -171,37 +174,38 @@ private boolean hasHandleableArg(J.MethodInvocation m) {
171174
&& !TypeUtils.isAssignableTo(FQN_CUSTOMIZER, m.getMethodType().getParameterTypes().get(0));
172175
}
173176

174-
private Optional<JavaType.Method> findDesiredReplacement(J.MethodInvocation m) {
177+
private Optional<JavaType.Method> createDesiredReplacement(J.MethodInvocation m) {
175178
JavaType.Method methodType = m.getMethodType();
176179
if (methodType == null) {
177180
return Optional.empty();
178181
}
179-
JavaType.FullyQualified httpSecurityType = methodType.getDeclaringType();
182+
JavaType.Parameterized customizerArgType = new JavaType.Parameterized(null,
183+
CUSTOMIZER_SHALLOW_TYPE, Collections.singletonList(methodType.getReturnType()));
180184
boolean keepArg = keepArg(m.getSimpleName());
181-
int expectedParamCount = keepArg ? 2 : 1;
182-
int customizerParamIndex = keepArg ? 1 : 0;
183-
return httpSecurityType.getMethods().stream()
184-
.filter(availableMethod -> availableMethod.getName().equals(methodRenames.getOrDefault(m.getSimpleName(), m.getSimpleName())) &&
185-
availableMethod.getParameterTypes().size() == expectedParamCount &&
186-
availableMethod.getParameterTypes().get(customizerParamIndex) instanceof JavaType.FullyQualified &&
187-
FQN_CUSTOMIZER.equals(((JavaType.FullyQualified) availableMethod.getParameterTypes().get(customizerParamIndex)).getFullyQualifiedName()))
188-
.findFirst();
185+
List<String> paramNames = keepArg ? ListUtils.concat(methodType.getParameterNames(), "arg1")
186+
: Collections.singletonList("arg0");
187+
List<JavaType> paramTypes = keepArg ? ListUtils.concat(methodType.getParameterTypes(), customizerArgType)
188+
: Collections.singletonList(customizerArgType);
189+
return Optional.of(methodType.withReturnType(methodType.getDeclaringType())
190+
.withName(methodRenames.getOrDefault(methodType.getName(), methodType.getName()))
191+
.withParameterNames(paramNames)
192+
.withParameterTypes(paramTypes)
193+
);
189194
}
190195

191196
private boolean keepArg(String methodName) {
192197
return argReplacements.containsKey(methodName) && argReplacements.get(methodName) == null;
193198
}
194199

195-
private Optional<JavaType.Method> findDesiredReplacementForArg(J.MethodInvocation m) {
200+
private Optional<JavaType.Method> createDesiredReplacementForArg(J.MethodInvocation m) {
196201
JavaType.Method methodType = m.getMethodType();
197202
if (methodType == null || !hasHandleableArg(m) || !(methodType.getReturnType() instanceof JavaType.Class)) {
198203
return Optional.empty();
199204
}
200-
JavaType.Class returnType = (JavaType.Class) methodType.getReturnType();
201-
return returnType.getMethods().stream()
202-
.filter(availableMethod -> availableMethod.getName().equals(argReplacements.get(m.getSimpleName())) &&
203-
availableMethod.getParameterTypes().size() == 1)
204-
.findFirst();
205+
return Optional.of(
206+
methodType.withName(argReplacements.get(m.getSimpleName()))
207+
.withDeclaringType((JavaType.FullyQualified) methodType.getReturnType())
208+
);
205209
}
206210

207211
// this method is unused in this repo, but, useful in Spring Tool Suite integration
@@ -232,7 +236,7 @@ private List<J.MethodInvocation> computeAndMarkChain() {
232236
List<J.MethodInvocation> chain = new ArrayList<>();
233237
Cursor cursor = getCursor();
234238
J.MethodInvocation initialMethodInvocation = cursor.getValue();
235-
findDesiredReplacementForArg(initialMethodInvocation).ifPresent(methodType ->
239+
createDesiredReplacementForArg(initialMethodInvocation).ifPresent(methodType ->
236240
chain.add(initialMethodInvocation.withMethodType(methodType)
237241
.withName(initialMethodInvocation.getName().withSimpleName(methodType.getName()))));
238242
cursor = cursor.getParent(2);
@@ -272,13 +276,10 @@ private boolean isDisableMethod(J.MethodInvocation method) {
272276
return new MethodMatcher("org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer disable()", true).matches(method);
273277
}
274278

275-
private J.MethodInvocation createDefaultsCall(JavaType type) {
276-
JavaType.FullyQualified fullyQualified = TypeUtils.asFullyQualified(type);
277-
assert fullyQualified != null;
278-
JavaType.Method methodType = fullyQualified.getMethods().stream().filter(m -> "withDefaults".equals(m.getName()) && m.getParameterTypes().isEmpty() && m.getFlags().contains(Flag.Static)).findFirst().orElse(null);
279-
if (methodType == null) {
280-
throw new IllegalStateException();
281-
}
279+
private J.MethodInvocation createDefaultsCall() {
280+
JavaType.Method methodType = new JavaType.Method(null, 9, CUSTOMIZER_SHALLOW_TYPE, "withDefaults",
281+
new JavaType.GenericTypeVariable(null, "T", JavaType.GenericTypeVariable.Variance.INVARIANT, null),
282+
null, null, null, null);
282283
maybeAddImport(methodType.getDeclaringType().getFullyQualifiedName(), methodType.getName());
283284
return new J.MethodInvocation(Tree.randomId(), Space.EMPTY, Markers.EMPTY, null, null,
284285
new J.Identifier(Tree.randomId(), Space.EMPTY, Markers.EMPTY, emptyList(), "withDefaults", null, null),

0 commit comments

Comments
 (0)