Skip to content

Commit c24cf75

Browse files
committed
Optionally enforce required elements in XSDs
This closes codehaus-plexus#162
1 parent 43aa6f4 commit c24cf75

File tree

7 files changed

+49
-9
lines changed

7 files changed

+49
-9
lines changed

modello-core/src/main/java/org/codehaus/modello/ModelloParameterConstants.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ public class ModelloParameterConstants
7171
*/
7272
public static final String EXTENDED_CLASSNAME_SUFFIX = "modello.xpp3.extended.suffix";
7373

74+
/**
75+
* Boolean flag relaxing XSD generation with regards to mandatory elements.
76+
* If set to {@code true} will not require mandatory elements in the XML which can be useful if the XML is post processed (e.g. POM merging with parents)
77+
* @since 2.1
78+
*/
79+
public static final String XSD_MANDATORY_ELEMENTS_NOT_ENFORCED = "modello.xsd.mandatory.element.not.enforced";
7480
private ModelloParameterConstants()
7581
{
7682
}

modello-maven-plugin/src/main/java/org/codehaus/modello/maven/ModelloXsdMojo.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ public class ModelloXsdMojo
4545
@Parameter( defaultValue = "${project.build.directory}/generated-site/resources/xsd", required = true )
4646
private File outputDirectory;
4747

48+
/**
49+
* Boolean flag relaxing XSD generation with regards to mandatory elements.
50+
* If set to {@code true} will not require mandatory elements in the XML which can be useful if the XML is post processed (e.g. POM merging with parents).
51+
* The default value is true for backwards compatibility reasons, but should be set to false for most cases.
52+
* @since 2.1.0
53+
*/
54+
@Parameter( defaultValue = "true")
55+
private boolean areMandatoryElementsNotEnforced;
56+
4857
/**
4958
*
5059
* @since 1.0-alpha-21
@@ -65,6 +74,7 @@ protected void customizeParameters( Properties parameters )
6574
{
6675
parameters.put( ModelloParameterConstants.OUTPUT_XSD_FILE_NAME, xsdFileName );
6776
}
77+
parameters.put( ModelloParameterConstants.XSD_MANDATORY_ELEMENTS_NOT_ENFORCED, areMandatoryElementsNotEnforced );
6878
}
6979

7080
protected boolean producesCompilableResult()

modello-plugins/modello-plugin-xsd/src/main/java/org/codehaus/modello/plugin/xsd/XsdGenerator.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ private void generateXsd( Properties parameters )
8787

8888
// we assume parameters not null
8989
String xsdFileName = parameters.getProperty( ModelloParameterConstants.OUTPUT_XSD_FILE_NAME );
90+
boolean areMandatoryElementsEnforced = !Boolean.valueOf( parameters.getProperty( ModelloParameterConstants.XSD_MANDATORY_ELEMENTS_NOT_ENFORCED ) );
9091

9192
File f = new File( directory, objectModel.getId() + "-" + getGeneratedVersion() + ".xsd" );
9293

@@ -137,7 +138,8 @@ private void generateXsd( Properties parameters )
137138
// Element descriptors
138139
// Traverse from root so "abstract" models aren't included
139140
int initialCapacity = objectModel.getClasses( getGeneratedVersion() ).size();
140-
writeComplexTypeDescriptor( w, objectModel, root, new HashSet<ModelClass>( initialCapacity ) );
141+
writeComplexTypeDescriptor( w, objectModel, root, new HashSet<ModelClass>( initialCapacity ),
142+
areMandatoryElementsEnforced );
141143

142144
w.endElement();
143145
}
@@ -184,7 +186,7 @@ private static void writeDocumentation( XMLWriter w, String version, String desc
184186
}
185187

186188
private void writeComplexTypeDescriptor( XMLWriter w, Model objectModel, ModelClass modelClass,
187-
Set<ModelClass> written )
189+
Set<ModelClass> written, boolean areMandatoryElementsEnforced )
188190
{
189191
written.add( modelClass );
190192

@@ -242,9 +244,12 @@ private void writeComplexTypeDescriptor( XMLWriter w, Model objectModel, ModelCl
242244
{
243245
w.startElement( "xs:element" );
244246

245-
// Usually, would only do this if the field is not "required", but due to inheritance, it may be
246-
// present, even if not here, so we need to let it slide
247-
w.addAttribute( "minOccurs", "0" );
247+
if ( !areMandatoryElementsEnforced || !field.isRequired() )
248+
{
249+
// Usually, would only do this if the field is not "required", but due to inheritance, it may be
250+
// present, even if not here, so we need to let it slide
251+
w.addAttribute( "minOccurs", "0" );
252+
}
248253
}
249254

250255
String xsdType = getXsdType( field.getType() );
@@ -428,7 +433,7 @@ else if ( xsdType == null )
428433
{
429434
if ( !written.contains( fieldModelClass ) )
430435
{
431-
writeComplexTypeDescriptor( w, objectModel, fieldModelClass, written );
436+
writeComplexTypeDescriptor( w, objectModel, fieldModelClass, written, areMandatoryElementsEnforced );
432437
}
433438
}
434439
}

modello-plugins/modello-plugin-xsd/src/test/java/org/codehaus/modello/plugin/xsd/FeaturesXsdGeneratorTest.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,19 @@ public void testXsdGenerator()
8080
catch ( SAXParseException e )
8181
{
8282
// ok, expected exception
83-
assertTrue( String.valueOf( e.getMessage() ).contains( "invalidElement" ) );
83+
assertTrue( e.getMessage().contains( "invalidElement" ) );
84+
}
85+
86+
try
87+
{
88+
validator.validate( new StreamSource( getClass().getResourceAsStream( "/features-missing-required.xml" ) ) );
89+
fail( "parsing of features-invalid.xml should have failed" );
90+
}
91+
catch ( SAXParseException e )
92+
{
93+
// ok, expected exception
94+
assertTrue( e.getMessage().contains( "description" ) );
95+
assertTrue( e.getMessage().endsWith(" is expected."));
8496
}
8597

8698
try
@@ -91,7 +103,7 @@ public void testXsdGenerator()
91103
catch ( SAXParseException e )
92104
{
93105
// ok, expected exception
94-
assertTrue( String.valueOf( e.getMessage() ).contains( "transientString" ) );
106+
assertTrue( e.getMessage().contains( "transientString" ) );
95107
}
96108
}
97109
}

modello-plugins/modello-plugin-xsd/src/test/java/org/codehaus/modello/plugin/xsd/ModelloXsdGeneratorTest.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
import org.codehaus.modello.AbstractModelloGeneratorTest;
26+
import org.codehaus.modello.ModelloParameterConstants;
2627
import org.codehaus.modello.core.ModelloCore;
2728
import org.codehaus.modello.model.Model;
2829
import org.xml.sax.SAXException;
@@ -55,6 +56,7 @@ public void testXsdGenerator()
5556
ModelloCore modello = (ModelloCore) lookup( ModelloCore.ROLE );
5657

5758
Properties parameters = getModelloParameters( "1.4.0" );
59+
parameters.setProperty( ModelloParameterConstants.XSD_MANDATORY_ELEMENTS_NOT_ENFORCED, "true" );
5860

5961
Model model = modello.loadModel( getTestFile( "../../src/main/mdo/modello.mdo" ) );
6062

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0"?>
2+
3+
<features-demo xmlns="http://codehaus-plexus.github.io/FEATURES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://codehaus-plexus.github.io/FEATURES/1.0.0 http://codehaus-plexus.github.io/features-1.0.0.xsd">
5+
</features-demo>

modello-test/src/main/resources/features.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<features-demo xmlns="http://codehaus-plexus.github.io/FEATURES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
44
xsi:schemaLocation="http://codehaus-plexus.github.io/FEATURES/1.0.0 http://codehaus-plexus.github.io/features-1.0.0.xsd">
55
<versionField>1.0.0</versionField>
6-
<!--required></required--><!-- TODO: this field is marked required but not set in the XML, should fail... -->
6+
<required></required>
77
<identifier>id</identifier>
88
<identifierPart2><id>reference</id></identifierPart2>
99

0 commit comments

Comments
 (0)