@@ -246,51 +246,76 @@ public class ${className} {
246246#end
247247 } //-- ${root.name} read(InputStream, boolean)
248248
249- /**
250- * Method read.
251- *
252- * @param parser a parser object.
253- * @param strict a strict object.
254- * @throws XMLStreamException XMLStreamException if
255- * any.
256- * @return ${root.name}
257- */
249+ /**
250+ * Method read.
251+ *
252+ * @param parser a parser object.
253+ * @param strict a strict object.
254+ * @throws XMLStreamException XMLStreamException if any.
255+ * @return ${root.name}
256+ */
258257#if ( $locationTracking )
259- public ${root.name} read(XMLStreamReader parser, boolean strict, InputSource inputSrc) throws XMLStreamException {
258+ public ${root.name} read(XMLStreamReader parser, boolean strict, InputSource inputSrc) throws XMLStreamException {
260259#else
261- public ${root.name} read(XMLStreamReader parser, boolean strict) throws XMLStreamException {
260+ public ${root.name} read(XMLStreamReader parser, boolean strict) throws XMLStreamException {
262261#end
263262#if ( $needXmlContext )
264- Deque<Object> context = new ArrayDeque<>();
263+ Deque<Object> context = new ArrayDeque<>();
265264#end
266- $rootUcapName $rootLcapName = null;
267- int eventType = parser.getEventType();
268- boolean parsed = false;
269- while (eventType != XMLStreamReader.END_DOCUMENT) {
270- if (eventType == XMLStreamReader.START_ELEMENT) {
271- if (strict && ! "${rootTag}".equals(parser.getLocalName())) {
272- throw new XMLStreamException("Expected root element '${rootTag}' but found '" + parser.getName() + "'", parser.getLocation(), null);
273- } else if (parsed) {
274- // fallback, already expected a XMLStreamException due to invalid XML
275- throw new XMLStreamException("Duplicated tag: '${rootTag}'", parser.getLocation(), null);
276- }
265+ $rootUcapName $rootLcapName = null;
266+ int eventType = parser.getEventType();
267+ boolean parsed = false;
268+ while (eventType != XMLStreamReader.END_DOCUMENT) {
269+ if (eventType == XMLStreamReader.START_ELEMENT) {
270+ if (strict && ! "${rootTag}".equals(parser.getLocalName())) {
271+ throw new XMLStreamException("Expected root element '${rootTag}' but found '" + parser.getName() + "'", parser.getLocation(), null);
272+ } else if (parsed) {
273+ throw new XMLStreamException("Duplicated tag: '${rootTag}'", parser.getLocation(), null);
274+ }
275+
276+ // Enforce root namespace per model (strict mode).
277+ String rootNs = parser.getNamespaceURI();
278+ boolean hasNs = rootNs != null && !rootNs.isEmpty();
279+ if (strict && hasNs) {
280+ if ("project".equals("${rootTag}")) {
281+ // Accept any official POM namespace version (e.g., 4.0.0, 4.1.0)
282+ if (!rootNs.startsWith("http://maven.apache.org/POM/")) {
283+ throw new XMLStreamException(
284+ "Unrecognized POM namespace '" + rootNs
285+ + "'. Expected something like 'http://maven.apache.org/POM/4.x.y' or no namespace.",
286+ parser.getLocation(), null);
287+ }
288+ } else if ("metadata".equals("${rootTag}")) {
289+ // Accept official METADATA namespaces (e.g., 1.1.0)
290+ if (!rootNs.startsWith("http://maven.apache.org/METADATA/")) {
291+ throw new XMLStreamException(
292+ "Unrecognized METADATA namespace '" + rootNs
293+ + "'. Expected something like 'http://maven.apache.org/METADATA/1.x.y' or no namespace.",
294+ parser.getLocation(), null);
295+ }
296+ } else {
297+ // Other models: do not enforce at root level.
298+ }
299+ }
300+
277301#if ( $locationTracking )
278- $rootLcapName = parse${rootUcapName}(parser, strict, parser.getNamespaceURI() , inputSrc);
302+ $rootLcapName = parse${rootUcapName}(parser, strict, rootNs , inputSrc);
279303#elseif ( $needXmlContext )
280- $rootLcapName = parse${rootUcapName}(parser, strict, parser.getNamespaceURI() , context);
304+ $rootLcapName = parse${rootUcapName}(parser, strict, rootNs , context);
281305#else
282- $rootLcapName = parse${rootUcapName}(parser, strict, parser.getNamespaceURI() );
306+ $rootLcapName = parse${rootUcapName}(parser, strict, rootNs );
283307#end
284- parsed = true;
285- }
286- eventType = parser.next();
287- }
288- if (parsed) {
289- return $rootLcapName;
290- }
291- throw new XMLStreamException("Expected root element '${rootTag}' but found no element at all: invalid XML document", parser.getLocation(), null);
308+ parsed = true;
309+ }
310+ eventType = parser.next();
311+ }
312+ if (parsed) {
313+ return $rootLcapName;
314+ }
315+ throw new XMLStreamException("Expected root element '${rootTag}' but found no element at all: invalid XML document", parser.getLocation(), null);
292316 } //-- ${root.name} read(XMLStreamReader, boolean)
293317
318+
294319#foreach ( $class in $model.allClasses )
295320 #if ( $class.name != "InputSource" && $class.name != "InputLocation" )
296321 #set ( $classUcapName = $Helper.capitalise( $class.name ) )
0 commit comments