From e299fc0dfde259a4e9872b82c2a75c9bb0116221 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 07:30:06 +0000 Subject: [PATCH 1/4] Initial plan From ecf65ac680279054fa70db201f5441d5ccebda79 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 07:43:58 +0000 Subject: [PATCH 2/4] Fix required attribute not being respected in XSD generation - Modified XsdGenerator to respect field.isRequired() directly instead of depending on enforceMandatoryElements parameter - Removed required=true from type field in modello.mdo since type is optional when association is present - Required fields now correctly omit minOccurs="0" in generated XSD, making them mandatory Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- .../java/org/codehaus/modello/plugin/xsd/XsdGenerator.java | 4 +--- src/main/mdo/modello.mdo | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java b/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java index 21efc9dd8..deff7c679 100644 --- a/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java +++ b/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java @@ -232,9 +232,7 @@ private void writeComplexTypeDescriptor( } w.startElement("xs:element"); - if (!enforceMandatoryElements || !field.isRequired()) { - // Usually, would only do this if the field is not "required", but due to inheritance, it may be - // present, even if not here, so we need to let it slide + if (!field.isRequired()) { w.addAttribute("minOccurs", "0"); } } diff --git a/src/main/mdo/modello.mdo b/src/main/mdo/modello.mdo index ce792f471..a01bda070 100644 --- a/src/main/mdo/modello.mdo +++ b/src/main/mdo/modello.mdo @@ -672,7 +672,6 @@ type 1.0.0+ - true String boolean, byte, From 3b2091724440794d798ef495b685a9c1eae39c86 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 26 Oct 2025 07:48:09 +0000 Subject: [PATCH 3/4] Add comment explaining backward compatibility for enforceMandatoryElements parameter Co-authored-by: slachiewicz <6705942+slachiewicz@users.noreply.github.com> --- .../main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java b/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java index deff7c679..99af81981 100644 --- a/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java +++ b/modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java @@ -87,6 +87,8 @@ private void generateXsd(Map parameters) throws IOException, Mod // we assume parameters not null String xsdFileName = (String) parameters.get(ModelloParameterConstants.OUTPUT_XSD_FILE_NAME); + // enforceMandatoryElements parameter is kept for backward compatibility but is no longer used. + // Required fields are now always enforced based on field.isRequired() value. boolean enforceMandatoryElements = Boolean.parseBoolean((String) parameters.get(ModelloParameterConstants.XSD_ENFORCE_MANDATORY_ELEMENTS)); From 449af725e654eac3f537ba82762f0cc615431a1f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Oct 2025 06:42:55 +0000 Subject: [PATCH 4/4] Add unit test for required field enforcement without XSD_ENFORCE_MANDATORY_ELEMENTS parameter - Created RequiredFieldXsdGeneratorTest to verify required fields are enforced by default - Added required-field.mdo test model with both required and optional fields - Test validates that XML missing required fields fails validation - Test validates that XML with required fields passes validation Co-authored-by: slawekjaranowski <3578921+slawekjaranowski@users.noreply.github.com> --- .../xsd/RequiredFieldXsdGeneratorTest.java | 107 ++++++++++++++++++ .../src/test/resources/required-field.mdo | 42 +++++++ 2 files changed, 149 insertions(+) create mode 100644 modello-plugins/modello-plugin-xsd/src/test/java/org/codehaus/modello/plugin/xsd/RequiredFieldXsdGeneratorTest.java create mode 100644 modello-plugins/modello-plugin-xsd/src/test/resources/required-field.mdo diff --git a/modello-plugins/modello-plugin-xsd/src/test/java/org/codehaus/modello/plugin/xsd/RequiredFieldXsdGeneratorTest.java b/modello-plugins/modello-plugin-xsd/src/test/java/org/codehaus/modello/plugin/xsd/RequiredFieldXsdGeneratorTest.java new file mode 100644 index 000000000..fe0298870 --- /dev/null +++ b/modello-plugins/modello-plugin-xsd/src/test/java/org/codehaus/modello/plugin/xsd/RequiredFieldXsdGeneratorTest.java @@ -0,0 +1,107 @@ +package org.codehaus.modello.plugin.xsd; + +/* + * Copyright (c) 2004, Codehaus.org + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is furnished to do + * so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import javax.inject.Inject; +import javax.xml.XMLConstants; +import javax.xml.transform.stream.StreamSource; +import javax.xml.validation.Schema; +import javax.xml.validation.SchemaFactory; +import javax.xml.validation.Validator; + +import java.io.File; +import java.io.StringReader; +import java.util.Map; + +import org.codehaus.modello.AbstractModelloGeneratorTest; +import org.codehaus.modello.core.ModelloCore; +import org.codehaus.modello.model.Model; +import org.codehaus.plexus.testing.PlexusTest; +import org.junit.jupiter.api.Test; +import org.xml.sax.SAXParseException; + +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * Test that verifies required fields are properly enforced in generated XSD schemas + * without needing the XSD_ENFORCE_MANDATORY_ELEMENTS parameter. + * + * @author Modello Team + */ +@PlexusTest +public class RequiredFieldXsdGeneratorTest extends AbstractModelloGeneratorTest { + @Inject + private ModelloCore modello; + + public RequiredFieldXsdGeneratorTest() { + super("required-field"); + } + + @Test + public void testRequiredFieldsEnforcedWithoutParameter() throws Throwable { + Model model = modello.loadModel(getXmlResourceReader("/required-field.mdo")); + + // Generate XSD WITHOUT the XSD_ENFORCE_MANDATORY_ELEMENTS parameter + Map parameters = getModelloParameters("1.0.0"); + // Note: NOT setting XSD_ENFORCE_MANDATORY_ELEMENTS parameter + + modello.generate(model, "xsd", parameters); + + SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); + Schema schema = sf.newSchema(new StreamSource(new File(getOutputDirectory(), "test-1.0.0.xsd"))); + Validator validator = schema.newValidator(); + + // Test 1: Valid XML with all required fields should pass + String validXml = "\n" + + "\n" + + " value\n" + + ""; + + validator.validate(new StreamSource(new StringReader(validXml))); + + // Test 2: XML missing required field should fail + String missingRequiredXml = "\n" + + "\n" + + " value\n" + + ""; + + try { + validator.validate(new StreamSource(new StringReader(missingRequiredXml))); + fail("Validation should have failed for XML missing required field"); + } catch (SAXParseException e) { + // Expected - the error should mention the required field + assertTrue( + e.getMessage().contains("requiredField") || e.getMessage().contains("expected"), + "Error message should indicate missing required field: " + e.getMessage()); + } + + // Test 3: XML with optional field omitted should pass + String withoutOptionalXml = "\n" + + "\n" + + " value\n" + + ""; + + validator.validate(new StreamSource(new StringReader(withoutOptionalXml))); + } +} diff --git a/modello-plugins/modello-plugin-xsd/src/test/resources/required-field.mdo b/modello-plugins/modello-plugin-xsd/src/test/resources/required-field.mdo new file mode 100644 index 000000000..3dcfea125 --- /dev/null +++ b/modello-plugins/modello-plugin-xsd/src/test/resources/required-field.mdo @@ -0,0 +1,42 @@ + + + test + Test + + Simple test model for required field validation. + + + + package + org.codehaus.modello.test + + + + + TestModel + 1.0.0+ + + A simple model to test required field enforcement. + + + + requiredField + 1.0.0+ + true + String + This field is required and must be present. + + + optionalField + 1.0.0+ + String + This field is optional and may be omitted. + + + + +