From 989a0454a9d2d26c768637b687a44ccf663697e2 Mon Sep 17 00:00:00 2001 From: Ivan Yakubenko Date: Mon, 10 Aug 2026 16:32:00 +0300 Subject: [PATCH 1/3] Remove optional receiverId field if value is not present --- .../builder/xmlBeans/v21/StructureHeaderXmlBeanBuilder.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/StructureHeaderXmlBeanBuilder.java b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/StructureHeaderXmlBeanBuilder.java index ad59a3c..6055391 100644 --- a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/StructureHeaderXmlBeanBuilder.java +++ b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/StructureHeaderXmlBeanBuilder.java @@ -60,8 +60,6 @@ public StructureHeaderType build(HeaderBean buildFrom) throws SdmxException { headerType.setPrepared(DateUtil.createCalendar(new Date())); SenderType senderType = headerType.addNewSender(); senderType.setId("unknown"); - PartyType receiverType = headerType.addNewReceiver(); - receiverType.setId("unknown"); return headerType; } if (ObjectUtil.validString(buildFrom.getId())) { @@ -124,10 +122,6 @@ public StructureHeaderType build(HeaderBean buildFrom) throws SdmxException { } } } - if (!ObjectUtil.validCollection(headerType.getReceiverList())) { - PartyType receiverType = headerType.addNewReceiver(); - receiverType.setId("unknown"); - } return headerType; } From 5fef50aa706b363e171891846561a31c75b211b6 Mon Sep 17 00:00:00 2001 From: Ivan Yakubenko Date: Mon, 10 Aug 2026 16:44:29 +0300 Subject: [PATCH 2/3] Bump actions/setup-java v1 -> v4 to fix macOS CI runner actions/setup-java@v1 fails to resolve JAVA_HOME on macos-latest runners since GitHub moved them to Apple Silicon (arm64) - it looks for an x64 JDK that was never installed there. v4 with an explicit distribution correctly detects the runner architecture. --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 29df908..16dd4e4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,8 +36,9 @@ jobs: path: ~/.gradle/wrapper key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }} - name: Setup java - uses: actions/setup-java@v1 + uses: actions/setup-java@v4 with: java-version: ${{ matrix.java }} + distribution: 'temurin' - name: Build with gradle run: ./gradlew build \ No newline at end of file From 76c01907cecb31c4ca559c9fc9896025f4284c1c Mon Sep 17 00:00:00 2001 From: Ivan Yakubenko Date: Mon, 10 Aug 2026 16:50:37 +0300 Subject: [PATCH 3/3] Restore mandatory Receiver for RegistryInterfaceType (BasicHeaderType) messages StructureHeaderXmlBeanBuilder is shared by two schema contexts with different Receiver cardinality: StructureHeaderType (query/availability responses, where Receiver is minOccurs="0") and BasicHeaderType via RegistryInterfaceType.Header (submit/query registry protocol, where Receiver is required, exactly one). Removing the forced fallback from the shared builder broke the latter (SchemaValidationException in SubmitStructureResponseBuilderTest). Added V2_1Helper.ensureReceiverPresent(), called from the two call sites that build a RegistryInterfaceType header via StructureHeaderXmlBeanBuilder, to patch in a default Receiver only where the schema actually requires one. --- .../v21/SubmitStructureResponseBuilderV2_1.java | 4 +++- .../registry/response/impl/v21/V2_1Helper.java | 15 +++++++++++++++ .../v21/RegistrySubmitXmlBeanBuilder.java | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/SubmitStructureResponseBuilderV2_1.java b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/SubmitStructureResponseBuilderV2_1.java index 7640105..ae5c82b 100644 --- a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/SubmitStructureResponseBuilderV2_1.java +++ b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/SubmitStructureResponseBuilderV2_1.java @@ -86,7 +86,9 @@ public RegistryInterfaceDocument buildSuccessResponse(SdmxBeans beans) throws Sd RegistryInterfaceType regInterface = responseType.addNewRegistryInterface(); SubmitStructureResponseType returnType = regInterface.addNewSubmitStructureResponse(); - regInterface.setHeader(headerXmlBeansBuilder.build(beans.getHeader())); + var headerType = headerXmlBeansBuilder.build(beans.getHeader()); + V2_1Helper.ensureReceiverPresent(headerType); + regInterface.setHeader(headerType); processMaintainables(returnType, beans.getAllMaintainables()); return responseType; diff --git a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/V2_1Helper.java b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/V2_1Helper.java index d1ad7a9..5f9278b 100644 --- a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/V2_1Helper.java +++ b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/registry/response/impl/v21/V2_1Helper.java @@ -101,4 +101,19 @@ public static void setHeader(BaseHeaderType header, SdmxBeans beans, String... r } } + /** + * RegistryInterfaceType.Header is typed as BasicHeaderType, which (unlike StructureHeaderType) + * requires exactly one Receiver. Callers building a registry request/response header from a + * caller-supplied HeaderBean must ensure one is present, since StructureHeaderXmlBeanBuilder + * no longer invents a default one. + * + * @param header the header to check and, if needed, patch with a default Receiver + */ + public static void ensureReceiverPresent(BaseHeaderType header) { + if (!ObjectUtil.validCollection(header.getReceiverList())) { + PartyType receiver = header.addNewReceiver(); + receiver.setId(HeaderHelper.INSTANCE.getReceiverId()); + } + } + } diff --git a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/RegistrySubmitXmlBeanBuilder.java b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/RegistrySubmitXmlBeanBuilder.java index 495cc79..d459b41 100644 --- a/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/RegistrySubmitXmlBeanBuilder.java +++ b/SdmxStructureParser/src/main/java/org/sdmxsource/sdmx/structureparser/builder/xmlBeans/v21/RegistrySubmitXmlBeanBuilder.java @@ -59,6 +59,7 @@ public RegistryInterfaceDocument build(SdmxBeans buildFrom) throws SdmxException BaseHeaderType headerType; if (buildFrom.getHeader() != null) { headerType = structureHeaderXmlBeanBuilder.build(buildFrom.getHeader()); + V2_1Helper.ensureReceiverPresent(headerType); registryInterfaceType.setHeader(headerType); } else { headerType = registryInterfaceType.addNewHeader();