templates: seven more authored strings reach a generated Java literal escaped, through one shared escape (#7295) - #7341
Merged
Conversation
… escaped, through one shared escape (#7295) #7262 routed four message families through JavaLiterals.escape and its body said every other authored string was still interpolated verbatim. It was, at seven more sites: an entity `label:` pattern's literal segments and formats, a `setField` step's `value:`, a report parameter's `initial:`, a field `description:` (the entity's @documentation argument), a `number:` series name, the seeded status names a lifecycle refusal quotes, and the `cron` / `destination` / `path` a job, a listener and a webhook declare. A `description: Customer's "trade" name` or a `setField` value with a quote ends the literal it is written into and fails the javac of the WHOLE generated module - the client Java batch is all-or-nothing, so one authored quote takes every generated class with it. Each site now renders from an escaped twin derived once, where every other model value is derived: ModelParameterProcessor for the property and label values, GlueGenerator for the glue descriptors, the report adapter for a parameter's initial. The raw values stay for the surfaces that render them as text. The seeded status names were the one site an escape alone could not fix: they travelled as a single `id=name,` join that the generated repository split apart at class-init time, so a comma in a name shifted every entry after it. They are now carried structurally (`lifecycleStatusNameList`, a structured .edm attribute transform-edm parses back) and emitted one escaped put() per pair; a .model written before this still carries the join and is read back, so nothing regenerates differently for a name that never held a separator. And the helper stopped multiplying: every hand-rolled copy of the loop - NotificationSupport, ScheduleSupport, IntegrationSupport, four in GlueIntentGenerator, MappingCompiler, and widgetPatternJava/widgetPatternJs in ModelParameterProcessor - now calls JavaLiterals.escape (or JsLiterals.escape). The copies were not identical: one dropped a carriage return, several escaped neither the newline nor the control characters, and a lone CR used to survive raw into a mapping literal and break its line. Verified: IntentEmissionCoverageIT's fixture carries a quote in a label pattern, a field description, a setField value and a report parameter initial, so the generated module is javac'd and published with them, and the assertions name the escaped value each site wrote; the runtime label assertions read the quotes back off the stored display name. ide-template + engine-intent unit suites, plus ModelGenerationIT and IntentEngineIT (81 tests), green. formatter:validate green with the cache wiped; the release javadoc profile builds both modules clean. Fixes #7295 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…eral-escape # Conflicts: # components/ide/ide-template/src/main/java/org/eclipse/dirigible/components/ide/template/service/model/GlueGenerator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Cause
#7262 routed four message families (
checks, guards,unique,refuse) throughJavaLiterals.escape, and its own body said: "Every other authored string the templates write into a Java string literal was still interpolated verbatim." That was still true at seven more sites:label:pattern literal segments + formatsRepository.java.templatelabel.append("${part.text}")setFieldstepvalue:SetField.java.templateupdateProperty(..., "${value}")initial:reportFileEntity.java.templatevalue(filter, ..., "${parameter.initial}")description:Entity.java.template@Documentation("${property.description}")number: { series: ... }Repository.java.template+Numbering.java.templateallocator callsid=name,Repository.java.template"${lifecycleStatusNames}".split(",")cron,destination,pathJob/InboundFile/InboundMessage/Outbound/WebhooktemplatesA
description: Customer's "trade" name, asetFieldvalue with a quote or a reportinitial: O'Neil "the" noteends the literal it is written into. The client Java batch is all-or-nothing, so one authored quote fails the javac of every generated class of the module — the #7241 / #7154 class of defect.Change
Each site renders from an escaped twin derived once, where every other model value is derived — so a hand-authored
.edm/.gluegets the same treatment as an intent-generated one:ModelParameterProcessor—descriptionJavaLiteral,numberSeriesJavaLiteral, and per label parttextJavaLiteral/formatJavaLiteral.GlueGenerator— onecopyJavaLiterals(...)for a setter'svalue, a numberingseries/perDefault, a schedule and inbound-filecron, an inbound-message and outbounddestination, a webhookpath. A key the descriptor does not carry is removed rather than emptied, so a template's#ifreads its absence exactly as before.initialJavaLiteral.The raw values stay for the surfaces that render them as text (a form's description paragraph, the diagram, the editor).
The seeded status names were the one site an escape alone could not fix. They travelled as a single
id=name,join the generated repository split apart at class-init time, so a comma in a name shifted every entry after it — silently. They are now carried structurally (lifecycleStatusNameList, a structured.edmattributetransform-edm.jsparses back) and emitted as one escapednames.put(...)per pair. A.modelwritten before this still carries the join and is read back by the parameter pass, so nothing regenerates differently for a name that never held a separator....and the helper stopped multiplying
Every hand-rolled copy of the loop now calls
JavaLiterals.escape(orJsLiterals.escapefor its JavaScript twin):NotificationSupport.quote,ScheduleSupport,IntegrationSupport, four inGlueIntentGenerator,MappingCompiler.javaString, andwidgetPatternJava/widgetPatternJs/widgetOptionsFilterValueJsinModelParameterProcessor.The copies were not identical, which is the argument for the shared one: one dropped a carriage return, several escaped neither the newline nor the control characters, and a lone CR used to survive raw into a mapping literal and break its line.
Verification
IntentEmissionCoverageIT— the fixture now carries a quote in a label pattern (the "{note}" ({Person.name}) {period|yyyy MMMM}), a fielddescription, asetFieldvalue and a new report's parameterinitial, so the generated module is javac'd and published with them. The assertions name the escaped value each site wrote, and the runtimeNameassertions read the quotes back off the stored display name. Green (270 s).ModelGenerationIT+IntentEngineIT— 81 tests, green.ide-template+engine-intentunit suites green, with new coverage for each derivation and for the structured-vs-joined status names.mvn formatter:validategreen with the cache wiped; thereleasejavadoc profile builds both modules clean.Not verified: the full IT suite, and no PostgreSQL run — nothing here touches SQL.
Fixes #7295
🤖 Generated with Claude Code