package com.example.statemachinedemo; import org.eclipse.jdt.core.dom.*; import java.util.List; public class StateMachineConfigureMethodFinder { /** * Parses source code and returns the MethodDeclaration for * `public void configure(StateMachineTransitionConfigurer transitions) throws Exception` * in a class extending StateMachineConfigurerAdapter. * * @param source Java source code string * @return MethodDeclaration of configure or null if not found */ public static MethodDeclaration findConfigureMethod(String source) { ASTParser parser = ASTParser.newParser(AST.JLS17); parser.setSource(source.toCharArray()); parser.setKind(ASTParser.K_COMPILATION_UNIT); parser.setResolveBindings(false); CompilationUnit cu = (CompilationUnit) parser.createAST(null); ConfigureMethodVisitor visitor = new ConfigureMethodVisitor(); cu.accept(visitor); return visitor.getConfigureMethod(); } private static class ConfigureMethodVisitor extends ASTVisitor { private MethodDeclaration configureMethod = null; @Override public boolean visit(TypeDeclaration node) { // Check if class extends StateMachineConfigurerAdapter if (!node.isInterface() && extendsStateMachineConfigurerAdapter(node)) { // Look for configure method inside this class for (MethodDeclaration method : node.getMethods()) { if (isConfigureMethod(method)) { configureMethod = method; return false; // Found, stop visiting further } } } return true; } private boolean extendsStateMachineConfigurerAdapter(TypeDeclaration node) { Type superclass = node.getSuperclassType(); if (superclass == null) return false; // Superclass can be parameterized type if (superclass.isParameterizedType()) { ParameterizedType pt = (ParameterizedType) superclass; String superName = pt.getType().toString(); return superName.equals("StateMachineConfigurerAdapter"); } else { return superclass.toString().equals("StateMachineConfigurerAdapter"); } } private boolean isConfigureMethod(MethodDeclaration method) { if (!method.getName().getIdentifier().equals("configure")) return false; // Must be public void if (!Modifier.isPublic(method.getModifiers())) return false; if (!(method.getReturnType2() != null && method.getReturnType2().isPrimitiveType())) return false; if (!"void".equals(method.getReturnType2().toString())) return false; // Exactly one parameter of type StateMachineTransitionConfigurer List params = method.parameters(); if (params.size() != 1) return false; SingleVariableDeclaration param = (SingleVariableDeclaration) params.get(0); Type paramType = param.getType(); String paramTypeStr = paramType.toString(); // Since generic params, just check starts with StateMachineTransitionConfigurer if (!paramTypeStr.startsWith("StateMachineTransitionConfigurer")) return false; // Check throws Exception using thrownExceptionTypes() @SuppressWarnings("unchecked") List thrownExceptions = method.thrownExceptionTypes(); boolean throwsExceptionFound = false; for (Type excType : thrownExceptions) { if (excType.toString().equals("Exception")) { throwsExceptionFound = true; break; } } if (!throwsExceptionFound) return false; return true; } public MethodDeclaration getConfigureMethod() { return configureMethod; } } }