davsclaus opened a new pull request, #27251:
URL: https://github.com/apache/camel/pull/27251

   Fixes [CAMEL-25254](https://issues.apache.org/jira/browse/CAMEL-25254).
   
   The source editor showed a route in another DSL (Space) only for a 
**running** integration, read-only, one route at a time; `camel transform 
route` converted files without running them, but only **to** XML or YAML. Now a 
route file converts between all three DSLs, without running it:
   
   - **Source editor**: F12 file actions → _Convert to YAML / XML / Java…_ on a 
route file writes a new file next to it (`orders.camel.xml` → 
`orders.camel.yaml`, or the route builder class `Orders.java`), which opens. 
The original stays; an existing file is not overwritten. What did not carry 
over is said at the top of the new file, as a comment of its DSL.
   - **CLI**: `camel transform route --format=java orders.camel.yaml`, one 
class per file, notes as comments at its top.
   
   
![convert](https://raw.githubusercontent.com/apache/camel/fix/CAMEL-25254/docs/user-manual/modules/ROOT/images/jbang/camel-tui-source-convert.png)
   
   ### How (`RouteDslConverter`, camel-jbang-core)
   - **Read without running**, into a `DefaultCamelContext` that is never 
started: Java with the Java DSL parser (as `TransformJavaRoutes`), XML with 
`ModelParser` (every root: `camel`, `beans`, `routes`, `rests`, route 
configurations, templates), YAML with the YAML DSL loader — **its `beans:` 
taken out first and read as plain `BeanFactoryDefinition`s with SnakeYAML's 
safe constructor**, because the YAML DSL creates the beans while loading 
(`BeansDeserializer` → `BeanModelHelper.newInstance`), which would run project 
code. This follows the security model's rule for tooling that reads route 
sources.
   - **Write** with `DefaultDumpRoutesStrategy` (routes, rests, route 
configurations, templates, beans, data formats); Java output wrapped in a 
`RouteBuilder` class with the imports it uses.
   - **Verify**: the converted file is read back the same way and both models 
are written as XML and compared. A file that would not load is **refused** (a 
gap of the target DSL's writer); a difference is **noted** with the first 
differing line. So nothing is lost without a word.
   - **Refused with the reason**: a Java route the parser cannot read (lambda 
processor, field) at its line; a predicate built in Java 
(`header("x").isEqualTo(..)`), which YAML/XML cannot express (the dump writes 
`expressionDefinition`, which does not load); YAML `semantic:` declarations 
(outside the route model, as the MCP transform tool also refuses); route 
configurations to Java (a `RouteConfigurationBuilder`); a beans-only file to 
Java.
   - **Noted**: comments; beans to Java (declare them in code, 
`@BindToRegistry`); Java statements that configure the context rather than the 
routes.
   
   ### Fidelity
   A scratch run (not committed) over the route files of the repo, each 
converted to the other two DSLs and read back:
   
   | | clean | converted, difference noted | refused: converted file would not 
load |
   |---|---|---|---|
   | Java → XML | 230 | 0 | 0 |
   | Java → YAML | 224 | 2 | 4 |
   | XML → YAML | 128 | 10 | 8 |
   | XML → Java | 125 | 16 | 0 |
   | YAML → XML | 47 | 0 | 1 |
   | YAML → Java | 30 | 13 | 5 |
   
   (Of 458 Java files, 228 are refused as source: test code with processors and 
fields, refused rather than converted with gaps. Of 96 YAML files, 39 are YAML 
writer test expectations with `customId`, which the YAML DSL itself does not 
load.)
   
   The notes and refusals point at **gaps of the model writers**, which this PR 
does not fix (to be filed separately): the YAML writer writes `verbs` for rests 
and `templateParameter` for route templates, which the YAML DSL does not load 
(`camel transform route` to YAML has the same problem today), nested bean 
property maps, `interceptFrom`, and the nesting of steps after an expression 
EIP; the Java writer leaves out a route's `errorHandler`, `intercept*`, 
`batchConfig` options and the id of `from`, and writes a stream resequencer 
`timeout="2000"` as `2s0ms`.
   
   ### Not changed
   The `camel_transform_route` tool of `camel mcp` keeps its own implementation 
(it compiles Java sources to read them, and has its own semantic-declaration 
handling and tests); moving it onto this converter is a follow-up to discuss.
   
   ### Docs
   `camel-jbang-transforming.adoc` (Transforming to Java), the source editor 
page (convert a whole file), TUI help, and the regenerated command 
docs/metadata for `--format=java`.
   
   ### Testing
   - `RouteDslConverterTest` (camel-jbang-core): XML → YAML, XML → a Java class 
that reads back clean, YAML beans converted without creating them (a class that 
does not exist), Java → YAML, refusals (lambda, Java predicate, same format, 
other files), semantic declarations, file names, the difference finder.
   - `SourceConvertTest` (TUI): the menu offers the other two DSLs for a route 
file and none for other files; the notes at the top of the new file in each 
DSL's comment syntax.
   - Transform tests of camel-jbang-core and `TransformToolsTest` of 
camel-jbang-mcp pass; the `camel-jbang-plugin-tui` suite passes (1587 tests).
   - Tried live: the TUI conversion (screenshot from that run) and `camel 
transform route --format=java`.
   
   _Claude Code on behalf of davsclaus_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
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]

Reply via email to