davsclaus opened a new pull request, #26349: URL: https://github.com/apache/camel/pull/26349
Fixes [CAMEL-24692](https://issues.apache.org/jira/browse/CAMEL-24692). ## Problem `AbstractCamelCatalog` substitutes `{{key}}` with `~^key^~` before handing the text to the Simple and Groovy parsers, so a property placeholder can be parsed without a running `CamelContext`. That works when the placeholder sits inside quotes or free text, but `~^key^~` is an *unquoted literal*, and `SimplePredicateParser.binaryOperator()` only accepts a quoted literal, a `${...}` function, or a numeric/boolean/null value as the right hand side. So these valid predicates were rejected: ``` ${body} >= {{hot.threshold}} -> Binary operator >= does not support token ^ at location 12 ${header.level} == {{level}} -> Binary operator == does not support token ^ at location 20 {{hot.threshold}} -> Unexpected token ~ at location 0 ``` They are valid at runtime: `ExpressionReifier.createPredicate()` calls `parseString(definition.getExpression())`, which resolves the property placeholders, **before** `language.createPredicate(exp)`. The Simple parser never sees `{{ }}`. This produced false positives in the `camel:validate` Maven goal (`ValidateMojo`) and in the Camel TUI save-time validation. ## Fix Replace a placeholder that is **not already inside a quoted literal** with `'~key~'`, which parses as a quoted literal in every operand position. A placeholder already inside quotes keeps the existing `~^key^~` form, so `${body} contains '{{danger}}'` is unaffected. Both dummies are exactly the same length as the `{{key}}` they replace, so the position reported in a parser error still points at the same location in the original text and no index remapping is needed. A second, independent bug is fixed at the same time: the regex was greedy, so several placeholders in one expression collapsed into a single match, both when substituting and when restoring them in the error message: ``` input: ${body} == {{a}} && ${header.x} == {{b}} before: ${body} == ~^a}} && ${header.x} == {{b^~ after: ${body} == '~a~' && ${header.x} == '~b~' ``` The two near-duplicate copies of this logic in `doValidateSimple` and `doValidateGroovy` are now a shared pair of helpers. ## Groovy `doValidateGroovy` carried the same substitution and failed the same way, verified against the real parser: ``` request.body >= {{hot.threshold}} -> MultipleCompilationErrorsException {{hot.threshold}} -> MultipleCompilationErrorsException request.body == '{{name}}' -> OK ``` ## Testing Four new tests in `CamelCatalogTest` covering bare operands (including `in` / `range` / `regex`, which need a `Literal` and so rule out a numeric dummy), whole-predicate placeholders, multiple and mixed quoted/unquoted placeholders plus error-message restoration, expression-position placeholders, and the Groovy equivalents. The pre-existing `testPredicatePlaceholder`, which pins the quoted case and the `'{{danger}}'` error reversal, still passes. The candidate substitutions were checked against the real `SimpleLanguage` parser before settling on this one, including `'foo{{name}}bar'` (placeholder mid-quote), `"{{name}}"`, `${header.{{headerName}}}`, and ternaries. > Note: `CamelCatalogTest` has 4 unrelated failures on my machine (`testComponentAliases`, `testSuggestComponentNames`, `testSuggestComponentNamesDedupesAlternativeSchemes`, `devConsolesOpenApiSpec`). I reproduced all four on a clean tree at the same base commit, so they pre-date this change and look like a stale local `.m2`. --- _Claude Code on behalf of davsclaus_ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
