fix(intent): server-side PDF renders resolve nomenclature values in the render language (#6947) - #6948
Merged
delchev merged 3 commits intoAug 27, 2026
Conversation
…he render language (eclipse-dirigible#6947) The two server-side PDF paths - the immutable snapshot minted on issue and the notify `attach: print`/`recordPrint`/`report` PDF mailed to the recipient - pick their `.print` template by the mint language but built the `{document, items}` payload by calling the generated `<Master>PrintFeeder` (or the report repository) in-process. The multilingual overlay a generated repository applies reads `User.getLanguage()`, i.e. the request's Accept-Language - and a BPM service task has no request. So nomenclature values (Payment Method, Sent Method, Status, any multilingual nomenclature) fell back to the default language while the template rendered in the mint language (a Bulgarian invoice reading "Bank transfer" / "ISSUED"). This is the server-side half of eclipse-dirigible#6945 (fixed client-side in eclipse-dirigible#6946), which is out of that PR's scope because there is no header to pin. Fix: a thread-bound language override in `UserFacade`, preferred by `getLanguage()` over the absent header, set by each render around the feed/render and cleared in a finally so a pooled worker thread never leaks it. The feeder's HTTP `@Get("/{id}")` path is untouched; all reads still go through repositories. - api-security: `UserFacade.setLanguage/clearLanguage` + override in `getLanguage` - api-modules-java: expose `sdk.security.User.setLanguage/clearLanguage` - templates: `Snapshot`, `Send`, `Notification` wrap feed/render (each attach branch) - tests: `UserFacadeLanguageOverrideTest`; `IntentEmissionCoverageIT` asserts the set/clear on every attach branch - docs: engine-intent guide mint-language bullet Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NicoleNG18
marked this pull request as draft
August 26, 2026 05:57
…and the extracted render local is byte[] (eclipse-dirigible#6947) The eclipse-dirigible#6947 render-language fix wrapped the server-side PDF render in a thread-bound `User.setLanguage`/`clearLanguage` in `Send`, `Notification` and `Snapshot`, but missed `Transition.java.template` - the transition `notify` block is a separate render path with its own three render sites (`attach: print` / `recordPrint` / `report`). So a transition-driven render (the `SendBill` case, generated as `SendBillTransition.java`) still resolved nomenclature values in the default language while the template rendered in the mint language. The same fix also introduced a latent compile error it never surfaced: extracting the render into a local typed it `String data`, but `sdk.print.Print.render` returns `byte[]`. `document.put("data", render(...))` compiled because `put` takes `Object`; a typed `String` local does not (`javac: byte[] cannot be converted to java.lang.String`). It broke the whole emission client-Java batch - every runtime endpoint 404'd - but was masked because `IntentEmissionCoverageIT` failed on the missing-Transition content assertion before it ever compiled the batch. - Transition.java.template: bind the language around all three render sites - Send/Notification/Transition: `String data` -> `byte[] data` (8 sites) (Snapshot was already `byte[] pdf`) - IntentEmissionCoverageIT now passes fully (content + runtime enforcement) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
NicoleNG18
marked this pull request as ready for review
August 26, 2026 10:40
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.
Problem
Fixes #6947.
The two server-side PDF render paths - the immutable snapshot copy minted when a document is issued, and the notify
attach: print/recordPrint/reportPDF mailed to the recipient - render the.printtemplate in the document's (mint) language but resolve the data values (Payment Method, Sent Method, Status, and any multilingual nomenclature) in the default language. For any document whose language is not the default, the archived copy and the emailed PDF come out with, e.g., Bulgarian labels but English values (ФАКТУРА…Bank transfer/ISSUED).This is the same class of defect as the client-side print-language bug (#6945, fixed in #6946), but on a different code path. #6946 is explicitly scoped to the interactive UI dialog and calls this case out as "a different (in-process, thread-local) fix" - which is this PR.
Root cause
Both paths already compute a render language (
language:/languageFrom:, falling back tosdk.print.Print.defaultLanguage()) and pass it toPrint.render(entity, language, payload), so the template is selected from the right CMS language folder. But the payload is built by calling the generated<Master>PrintFeeder().feed(id)(or, forattach: report, the report repository) in-process. The multilingual overlay a generated repository applies readssdk.security.User.getLanguage()→ the request'sAccept-Languageheader. A BPM service task has no request, sogetLanguage()returnsnull,Translatorno-ops, and the values fall back to the base/default language while the template is in the mint language.Fix
A thread-bound language override that
getLanguage()prefers over the (absent) request header - the mechanism the platform lacked for off-request renders. Each server-side render sets it to the language it already computed, around the feed/render, and clears it in afinallyso a pooled BPM worker thread never leaks it. The feeder's HTTP@Get("/{id}")contract is untouched (the browser still carriesAccept-Language), and every read still goes through the generated repositories (validations / events preserved).components/api/api-securityUserFacade:setLanguage(String)/clearLanguage()+ an override branch at the top ofgetLanguage().components/api/api-modules-javasdk.security.User: exposesetLanguage/clearLanguagefor the generated (client-Java) delegates.template-application-events-java:Snapshot.java.template,Send.java.templateandNotification.java.templatewrap the feed/render inUser.setLanguage(language)…finally { User.clearLanguage(); }- for every attach branch (print,recordPrint,report), and forreportthe override also covers the reportfindAllwhose:languagebinding readsgetLanguage().engine-intent/CLAUDE.md: mint-language bullet updated (the mint language now names the template AND the data).Scope / notes
attach: report(intent: notify can attach a parameterized REPORT render (attach: { report, bind }) - the customer-statement mail #6931) shares the exact root cause and is fixed by the same change.UserFacade/User; no behaviour change on the HTTP path. The override is always cleared infinally; these delegates never nest, so worker threads never leak a language.Verification
UserFacadeLanguageOverrideTest(new, api-security): the override wins over the absent request language,clearLanguage()restores the unresolved state, null/blank leaves it unset. Passing locally (4/4).IntentEmissionCoverageIT: each attach branch (SendBillTransition=attach: print,BillFlowMailBillSend=attach: report,BillFlowShareBillSend=attach: recordPrint) now asserts the generated delegate emits theUser.setLanguage(language)/clearLanguage()wrapper around its render - and the IT's client-Java compile proves the emitted code compiles.IntentEngineIT'sOrderCopysnapshot compiles theSnapshottemplate.mvn formatter:validateand the release-profile javadoc build pass on the changed modules.Reminder: the events templates are bundled into the fat jar - a locally running instance needs
template-application-events-java+build/applicationrepackaged and a restart, and target apps need regeneration, to reflect the change.🤖 Generated with Claude Code