Files

2.4 KiB

Advanced String and Variable Resolution Strategy

1. The Problem

Annotations often use non-literal values for metadata:

  • Constants: @PostMapping(ApiConstants.SUBMIT_PATH)
  • Concatenation: @RequestMapping(BASE + "/orders")
  • Inherited Variables: Use of fields defined in base classes.

Simple StringLiteral extraction fails in these cases. We need a recursive Expression Evaluator.

2. Evaluation Logic

Constant Resolution

If an expression is a SimpleName or QualifiedName:

  1. Use CodebaseContext.getTypeDeclaration() to find the class where the variable is defined.
  2. Search for the VariableDeclarationFragment.
  3. If it has an initializer that is a literal or another evaluatable expression, resolve it.

Concatenation (Infix Expressions)

If an expression is an InfixExpression with the + operator:

  1. Recursively resolve the left operand.
  2. Recursively resolve the right operand.
  3. Concatenate the results if both are strings.

Spring Expression Language (SpEL) in Annotations

For values like @Value("#{systemProperties['path.base'] + '/api'}"):

  1. Identify the SpEL string.
  2. Use a "Lite" SpEL parser to extract keys.
  3. Match against the profiles map in CodebaseMetadata.

3. Implementation: ValueResolver

We will introduce a central ValueResolver utility.

public class ValueResolver {
    public String resolveString(Expression expr, CodebaseContext context) {
        if (expr instanceof StringLiteral sl) return sl.getLiteralValue();
        if (expr instanceof InfixExpression ie) return resolveInfix(ie, context);
        if (expr instanceof Name name) return resolveVariable(name, context);
        // ... fallback to toString() or empty
    }
}

4. Challenges

  • Circular Dependencies: A + B, where B = A + C. We need a "visited" set to prevent infinite recursion.
  • Runtime-only values: Some values cannot be resolved statically (e.g., values from a DB). In these cases, we should return the placeholder or a "Runtime Value" marker.
  • Method Calls: getPath() + "/orders". Resolving method return values is complex; initially, we will only support simple getters returning literals.

5. Integration

  1. Update AstUtils or create ValueResolver.
  2. Refactor SpringMvcEnricher, RabbitMqEnricher, and JmsEnricher to use the resolver for all path/queue/destination fields.
  3. Update integration_test_state_machine with complex path examples.