[ 
https://issues.apache.org/jira/browse/MNG-5862?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17804719#comment-17804719
 ] 

ASF GitHub Bot commented on MNG-5862:
-------------------------------------

elharo commented on code in PR #1205:
URL: https://github.com/apache/maven/pull/1205#discussion_r1446059983


##########
maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java:
##########
@@ -100,14 +104,39 @@ private Path getRootDirectory(Map<String, ?> options) {
         return (Path) value;
     }
 
+    private boolean getXInclude(Map<String, ?> options) {
+        Object value = (options != null) ? options.get(XINCLUDE) : null;
+        return value instanceof Boolean && (Boolean) value;
+    }
+
     private Model read(InputStream input, Path pomFile, Map<String, ?> 
options) throws IOException {
         try {
-            XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory();
-            
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
-            XMLStreamReader parser = factory.createXMLStreamReader(input);
-
             InputSource source = getSource(options);
             boolean strict = isStrict(options);
+            Path rootDirectory = getRootDirectory(options);
+
+            Source xmlSource;
+            if (pomFile != null) {
+                if (input != null) {
+                    xmlSource = new StaxPathInputSource(pomFile, input);
+                } else {
+                    xmlSource = new Stax2FileSource(pomFile.toFile());
+                }
+            } else {
+                xmlSource = new StreamSource(input);
+            }
+
+            XMLStreamReader parser;
+            // We only support xml entities and xinclude when reading a file 
in strict mode
+            if (pomFile != null && strict && getXInclude(options)) {
+                parser = XInclude.xinclude(xmlSource, new 
LocalXmlResolver(rootDirectory));
+            } else {
+                XMLInputFactory factory = new 
com.ctc.wstx.stax.WstxInputFactory();
+                
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
+                
factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, false);

Review Comment:
   Nothing you can do here, but this property should have been named 
SUPPORTS_EXTERNAL_ENTITIES



##########
maven-stax-xinclude/src/main/java/org/apache/maven/stax/xinclude/DOMXMLElementEvaluator.java:
##########
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.stax.xinclude;
+
+import java.util.Map;
+import java.util.Objects;
+
+import com.ctc.wstx.dtd.DTDAttribute;
+import com.ctc.wstx.dtd.DTDElement;
+import com.ctc.wstx.dtd.DTDSubset;
+import com.ctc.wstx.util.PrefixedName;
+import org.w3c.dom.Element;
+
+/**
+ * This class extends the XMLElementEvaluator to support the DOM 
implementation in XMLElement.
+ * <p>
+ * This class is based upon a class of the same name in Apache Woden.
+ */
+class DOMXMLElementEvaluator extends XMLElementEvaluator<Element> {
+
+    private DTDSubset dtd;
+
+    /**
+     * Constructs a new DOMXMLElementEvaluator to evaluate a XPointer on a DOM 
Element.
+     *
+     * @param xpointer an XPointer to evaluate
+     * @param element an DOM Element to be evaluated
+     */
+    DOMXMLElementEvaluator(XPointer xpointer, Element element, DTDSubset dtd) {
+        super(xpointer, createXMLElement(element));
+        this.dtd = dtd;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see 
org.apache.woden.internal.xpointer.XMLElementEvaluator#testElementShorthand(org.apache.woden.XMLElement,
 java.lang.String)
+     */
+    public boolean testElementShorthand(XMLElement<Element> element, String 
shorthand) {
+        // Simple http://www.w3.org/TR/xml-id/ support for now until we 
support full scheme based ID's.
+        Element domElement = element.getSource();
+        String attr = 
domElement.getAttributeNS("http://www.w3.org/XML/1998/namespace";, "id");
+        if (Objects.equals(attr, shorthand)) {
+            return true;
+        }
+        if (dtd != null) {
+            Map<PrefixedName, DTDElement> map = dtd.getElementMap();
+            if (map != null) {
+                DTDElement dtdElement = map.get(new 
PrefixedName(domElement.getPrefix(), domElement.getLocalName()));
+                if (dtdElement != null) {
+                    DTDAttribute dtdAttribute = dtdElement.getIdAttribute();
+                    if (dtdAttribute != null) {
+                        attr = 
domElement.getAttribute(dtdAttribute.getName().getLocalName());
+                        if (Objects.equals(attr, shorthand)) {
+                            return true;
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Evaluates the XPointer on the root Element and returns the resulting 
Element or null.
+     *
+     * @return an Element from the resultant evaluation of the root Element or 
null if evaluation fails

Review Comment:
   delete resultant



##########
maven-stax-xinclude/src/main/java/org/apache/maven/stax/xinclude/InvalidXPointerException.java:
##########
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.stax.xinclude;
+
+/**
+ * This class represents Exceptions that can happen during parsing an XPointer 
Expression.

Review Comment:
   during --> while



##########
maven-stax-xinclude/src/main/java/org/apache/maven/stax/xinclude/ElementPointerPart.java:
##########
@@ -0,0 +1,245 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.stax.xinclude;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * ElementPointerPart is a class which represents the element() scheme for the 
XPointer Framework.
+ * The specification is defined at <a 
href="http://www.w3.org/TR/xptr-element/";>http://www.w3.org/TR/xptr-element/</a>
+ * <p>
+ * This class is immutable.
+ * <p>
+ * This class is based upon a class of the same name in Apache Woden.
+ */
+class ElementPointerPart implements PointerPart {
+    private final String ncname;
+    private final List<Integer> childSequence;
+
+    /**
+     * Constructs an ElementPointerPart with only an elementID NCName.
+     *
+     * @param elementID an NCName of the elementID to reference.
+     * @throws NullPointerException is a null elementID is given.
+     */
+    ElementPointerPart(String elementID) {
+        if (elementID == null) {
+            throw new NullPointerException("The elementID argument is null.");
+        }
+        this.ncname = elementID;
+        this.childSequence = null;
+    }
+
+    /**
+     * Constructs an ElementPointerPart with only a childSequence.
+     *
+     * @param childSequence a List of Integers representing the child sequence.
+     * @throws NullPointerException     if childSequence is null.
+     * @throws IllegalArgumentException if childSequence is empty or contains 
elements other than Integers.
+     */
+    ElementPointerPart(List<Integer> childSequence) {
+        if (childSequence == null) {
+            throw new NullPointerException("The childSequence argument is 
null.");
+        }
+        if (childSequence.isEmpty()) {
+            throw new IllegalArgumentException("The childSequence list is 
empty.");
+        }
+        this.ncname = null;
+        this.childSequence = childSequence;
+    }
+
+    /**
+     * Constructs an ElementPointerPart with both an NCName and a 
childSequence.
+     *
+     * @param elementID     an NCName of the elementID to reference.
+     * @param childSequence a List of Integers representing the child sequence.
+     * @throws NullPointerException     if elementID or childSequence are null.
+     * @throws IllegalArgumentException if childSequence is empty or contains 
elements other than Integers.
+     */
+    ElementPointerPart(String elementID, List<Integer> childSequence) {
+        if (elementID == null) {
+            throw new NullPointerException("The elementID argument is null.");
+        }
+        if (childSequence == null) {
+            throw new NullPointerException("The childSequence argument is 
null.");
+        }
+        if (childSequence.isEmpty()) {
+            throw new IllegalArgumentException("The childSequence list is 
empty.");
+        }
+        if (childSequence.contains(0)) {
+            throw new IllegalArgumentException("the childSequence list must 
only contain Integers bigger than 0.");
+        }
+
+        this.ncname = elementID;
+        this.childSequence = childSequence;
+    }
+
+    /**
+     * Returns the NCName for this Element PointerPart.
+     *
+     * @return an NCName if it exists in this Element PointerPart, otherwise 
null.
+     */
+    public String getNCName() {
+        return ncname;
+    }
+
+    /**
+     * Returns the child sequence of this Element PointerPart.
+     *
+     * @return an Integer[] of the child sequence for this element pointer 
part, or an empty array if none exists.
+     */
+    public List<Integer> getChildSequence() {
+        return Collections.unmodifiableList(childSequence);
+    }
+
+    /**
+     * Checks if this Element PointerPart has a NCName or not.
+     *
+     * @return a boolean, true if it has a NCName or false if not.
+     */
+    public boolean hasNCName() {
+        return ncname != null;
+    }
+
+    /**
+     * Checks if this Element PointerPart has a childSequence or not.
+     *
+     * @return a boolean, true if this has a childSequence or false if not.
+     */
+    public boolean hasChildSequence() {
+        return childSequence != null;
+    }
+
+    /*
+     *(non-Javadoc)
+     * @see org.apache.woden.xpointer.PointerPart#toString()
+     */
+    public String toString() {
+        String schemeData;
+        if (childSequence == null) {
+            schemeData = ncname.toString();
+        } else if (ncname == null) {
+            schemeData = serialiseChildSequence();
+        } else {
+            schemeData = ncname.toString() + serialiseChildSequence();
+        }
+        return "element(" + schemeData + ")";
+    }
+
+    /**
+     * Serialises the child sequence and returns it as a string.
+     *
+     * @return a String of the serialised child sequence.
+     */
+    private String serialiseChildSequence() {
+        StringBuilder buffer = new StringBuilder();
+        for (Integer child : childSequence) {
+            buffer.append("/").append(child.toString());
+        }
+        return buffer.toString();
+    }
+
+    /**
+     * Deserialises the schemaData for an ElementPointerPart and constructs a 
new ElementPointerPart from it.
+     *
+     * @param schemeData a String of the schemeaData parsed from the string 
XPointer.
+     * @return an ElementPointerPart representing the parsed schemaData.
+     * @throws IllegalArgumentException if the schemeData has invalid scheme 
syntax.
+     */
+    static ElementPointerPart parseFromString(final String schemeData) throws 
InvalidXPointerException {
+        List<Integer> childSequence;
+        String elementID = null;
+        int startChar;
+        int endChar;
+
+        // Find an NCName if it exists?
+        startChar = schemeData.indexOf("/");

Review Comment:
   declare here



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/LocalXmlResolver.java:
##########
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.model.io;
+
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.stream.StreamSource;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class LocalXmlResolver implements XMLResolver {
+
+    private final Path rootDirectory;
+
+    public LocalXmlResolver(Path rootDirectory) {
+        this.rootDirectory = rootDirectory != null ? rootDirectory.normalize() 
: null;
+    }
+
+    @Override
+    public Object resolveEntity(String publicID, String systemID, String 
baseURI, String namespace)
+            throws XMLStreamException {
+        if (rootDirectory == null) {
+            return null;
+        }
+        if (systemID == null) {
+            throw new XMLStreamException("systemID is null");
+        }
+        if (baseURI == null) {
+            throw new XMLStreamException("baseURI is null");
+        }
+        URI baseUri;
+        try {
+            baseUri = new URI(baseURI).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for baseURI URI: " + 
baseURI, e);
+        }
+        URI sysUri;
+        try {
+            sysUri = new URI(systemID).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for systemID URI: " + 
systemID, e);
+        }
+        if (sysUri.getScheme() != null) {
+            throw new XMLStreamException("systemID must be a relative URI: " + 
systemID);
+        }
+        Path base = Paths.get(baseUri).normalize();
+        if (!base.startsWith(rootDirectory)) {
+            return null;
+        }
+        Path sys = Paths.get(sysUri.getSchemeSpecificPart()).normalize();
+        if (sys.isAbsolute()) {
+            throw new XMLStreamException("systemID must be a relative path: " 
+ systemID);
+        }
+        Path res = base.resolveSibling(sys).normalize();

Review Comment:
   what is res? Please use a non-abbreviated name. 



##########
maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java:
##########
@@ -235,7 +235,7 @@ void testReadInvalidPom() throws Exception {
 
         // single project build entry point
         Exception ex = assertThrows(Exception.class, () -> 
projectBuilder.build(pomFile, configuration));
-        assertThat(ex.getMessage(), containsString("Received 
non-all-whitespace CHARACTERS or CDATA event"));
+        assertThat(ex.getMessage(), containsString("expected START_TAG or 
END_TAG, not CHARACTERS"));
 
         // multi projects build entry point
         ProjectBuildingException pex = assertThrows(

Review Comment:
   Here it looks like it does throw a subclass



##########
maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java:
##########
@@ -235,7 +235,7 @@ void testReadInvalidPom() throws Exception {
 
         // single project build entry point
         Exception ex = assertThrows(Exception.class, () -> 
projectBuilder.build(pomFile, configuration));
-        assertThat(ex.getMessage(), containsString("Received 
non-all-whitespace CHARACTERS or CDATA event"));
+        assertThat(ex.getMessage(), containsString("expected START_TAG or 
END_TAG, not CHARACTERS"));

Review Comment:
   Does this method really throw a plain java.lang.Exception, not a subclass? 
If it does throw a subclass, assert the subclass and ignore the message. If it 
does throw only java.lang.Exception then that's something that should be fixed, 
though not in this PR.
   
   In general asserting exception messages is brittle.



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/LocalXmlResolver.java:
##########
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.model.io;
+
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.stream.StreamSource;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class LocalXmlResolver implements XMLResolver {
+
+    private final Path rootDirectory;
+
+    public LocalXmlResolver(Path rootDirectory) {
+        this.rootDirectory = rootDirectory != null ? rootDirectory.normalize() 
: null;
+    }
+
+    @Override
+    public Object resolveEntity(String publicID, String systemID, String 
baseURI, String namespace)
+            throws XMLStreamException {
+        if (rootDirectory == null) {
+            return null;
+        }
+        if (systemID == null) {
+            throw new XMLStreamException("systemID is null");
+        }
+        if (baseURI == null) {
+            throw new XMLStreamException("baseURI is null");
+        }
+        URI baseUri;
+        try {
+            baseUri = new URI(baseURI).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for baseURI URI: " + 
baseURI, e);
+        }
+        URI sysUri;

Review Comment:
   This is not ewhat I first thought it was. Rename systemIDUrl



##########
maven-core/src/test/java/org/apache/maven/project/ProjectBuilderTest.java:
##########
@@ -246,8 +246,7 @@ void testReadInvalidPom() throws Exception {
         assertThat(pex.getResults().get(0).getProblems().size(), 
greaterThan(0));
         assertThat(
                 pex.getResults(),
-                contains(projectBuildingResultWithProblemMessage(
-                        "Received non-all-whitespace CHARACTERS or CDATA event 
in nextTag()")));
+                contains(projectBuildingResultWithProblemMessage("expected 
START_TAG or END_TAG, not CHARACTERS")));

Review Comment:
   I wouldn't go further than asserting the message is non-null. Messages are 
informative, not part of the stable API



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java:
##########
@@ -100,14 +104,39 @@ private Path getRootDirectory(Map<String, ?> options) {
         return (Path) value;
     }
 
+    private boolean getXInclude(Map<String, ?> options) {
+        Object value = (options != null) ? options.get(XINCLUDE) : null;
+        return value instanceof Boolean && (Boolean) value;
+    }
+
     private Model read(InputStream input, Path pomFile, Map<String, ?> 
options) throws IOException {
         try {
-            XMLInputFactory factory = new com.ctc.wstx.stax.WstxInputFactory();
-            
factory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES, false);
-            XMLStreamReader parser = factory.createXMLStreamReader(input);
-
             InputSource source = getSource(options);
             boolean strict = isStrict(options);
+            Path rootDirectory = getRootDirectory(options);
+
+            Source xmlSource;
+            if (pomFile != null) {
+                if (input != null) {
+                    xmlSource = new StaxPathInputSource(pomFile, input);
+                } else {
+                    xmlSource = new Stax2FileSource(pomFile.toFile());
+                }
+            } else {
+                xmlSource = new StreamSource(input);
+            }
+
+            XMLStreamReader parser;
+            // We only support xml entities and xinclude when reading a file 
in strict mode

Review Comment:
   nit: external general entities and XInclude



##########
maven-stax-xinclude/src/main/java/org/apache/maven/stax/xinclude/NCName.java:
##########
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.stax.xinclude;
+
+/**
+ * This class represents the data type NCName use for XML non-colonized names.
+ */
+@SuppressWarnings("checkstyle:MagicNumber")
+class NCName {

Review Comment:
   This is a lot to reinvent and maintain for one function. Maybe we need this 
to avoid extra dependencies, but I'm sure this already exists in Xerces, XML 
Commons, or any of several other projects.



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/LocalXmlResolver.java:
##########
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.model.io;
+
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.stream.StreamSource;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class LocalXmlResolver implements XMLResolver {
+
+    private final Path rootDirectory;
+
+    public LocalXmlResolver(Path rootDirectory) {
+        this.rootDirectory = rootDirectory != null ? rootDirectory.normalize() 
: null;
+    }
+
+    @Override
+    public Object resolveEntity(String publicID, String systemID, String 
baseURI, String namespace)
+            throws XMLStreamException {
+        if (rootDirectory == null) {
+            return null;
+        }
+        if (systemID == null) {
+            throw new XMLStreamException("systemID is null");
+        }
+        if (baseURI == null) {
+            throw new XMLStreamException("baseURI is null");
+        }
+        URI baseUri;
+        try {
+            baseUri = new URI(baseURI).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for baseURI URI: " + 
baseURI, e);
+        }
+        URI sysUri;
+        try {
+            sysUri = new URI(systemID).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for systemID URI: " + 
systemID, e);
+        }
+        if (sysUri.getScheme() != null) {
+            throw new XMLStreamException("systemID must be a relative URI: " + 
systemID);
+        }
+        Path base = Paths.get(baseUri).normalize();
+        if (!base.startsWith(rootDirectory)) {
+            return null;
+        }
+        Path sys = Paths.get(sysUri.getSchemeSpecificPart()).normalize();
+        if (sys.isAbsolute()) {
+            throw new XMLStreamException("systemID must be a relative path: " 
+ systemID);
+        }
+        Path res = base.resolveSibling(sys).normalize();
+        if (!res.startsWith(rootDirectory)) {
+            throw new XMLStreamException("systemID cannot refer to outside 
rootDirectory: " + systemID);

Review Comment:
   refer to --> refer to a path



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/ModelReader.java:
##########
@@ -45,6 +45,12 @@ public interface ModelReader {
      */
     String INPUT_SOURCE = "org.apache.maven.model.io.inputSource";
 
+    /**
+     * Name of the property used to store a boolean {@code true} if XInclude 
supports

Review Comment:
   supports --> support



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/LocalXmlResolver.java:
##########
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.maven.model.io;
+
+import javax.xml.stream.XMLResolver;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.transform.stream.StreamSource;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class LocalXmlResolver implements XMLResolver {
+
+    private final Path rootDirectory;
+
+    public LocalXmlResolver(Path rootDirectory) {
+        this.rootDirectory = rootDirectory != null ? rootDirectory.normalize() 
: null;
+    }
+
+    @Override
+    public Object resolveEntity(String publicID, String systemID, String 
baseURI, String namespace)
+            throws XMLStreamException {
+        if (rootDirectory == null) {
+            return null;
+        }
+        if (systemID == null) {
+            throw new XMLStreamException("systemID is null");
+        }
+        if (baseURI == null) {
+            throw new XMLStreamException("baseURI is null");
+        }
+        URI baseUri;
+        try {
+            baseUri = new URI(baseURI).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for baseURI URI: " + 
baseURI, e);
+        }
+        URI sysUri;
+        try {
+            sysUri = new URI(systemID).normalize();
+        } catch (URISyntaxException e) {
+            throw new XMLStreamException("Invalid syntax for systemID URI: " + 
systemID, e);
+        }
+        if (sysUri.getScheme() != null) {
+            throw new XMLStreamException("systemID must be a relative URI: " + 
systemID);
+        }
+        Path base = Paths.get(baseUri).normalize();
+        if (!base.startsWith(rootDirectory)) {
+            return null;
+        }
+        Path sys = Paths.get(sysUri.getSchemeSpecificPart()).normalize();

Review Comment:
   sys --> systemIDPath



##########
maven-model-builder/src/main/java/org/apache/maven/model/io/DefaultModelReader.java:
##########
@@ -147,4 +175,18 @@ private Model read(Reader reader, Path pomFile, 
Map<String, ?> options) throws I
             throw new IOException("Unable to transform pom", e);
         }
     }
+
+    private static class StaxPathInputSource extends Stax2FileSource {

Review Comment:
   a comment explaining the point here might be useful. Maybe this associates a 
file with an input stream that doesn't come from the file? or at least not only 
from the file? I'm not sure





> POM XML parser needs XInclude and/or XML Entity support
> -------------------------------------------------------
>
>                 Key: MNG-5862
>                 URL: https://issues.apache.org/jira/browse/MNG-5862
>             Project: Maven
>          Issue Type: New Feature
>          Components: POM
>            Reporter: Jason Vas Dias
>            Assignee: Guillaume Nodet
>            Priority: Major
>
> POM XML files can get very large and repetitive ,  and not all modularizaton 
> scenarios can be resolved by using a Super POM as described in MNG-1980 ,
> and would be easily resolved if only the POM parser supported XIncludes or
> XML Entities - neither are supported. 
> Here is one such scenario:
> I have a large project that has several SureFire plugin based "Test Suites" -
> each test suite uses a "common-at-classes" module of common test classes,
> and is essentially identical except in its XML configuration "test resource"  
> files
>  - so the structure is like this :
> {quote}
> {noformat}
>  Top Level project directory:
>    ./pom.xml
>    ./acceptance-tests/pom.xml
>    ./acceptance-tests/common-at-classes/pom.xml
>    ./acceptance-tests/test-suite_#1/pom.xml
>    ...
>    ./acceptance-tests/test-suite_#N/pom.xml
> {noformat}
> {quote}
> There are @ 10 ( being upgraded to @ 20)  "test suites", 
> which all do exactly the same thing, but with slightly
> different "test resource" configuration files,  
> and depend on the 'acceptance-tests/common-at-classes" JAR .
> We can modularize all the test-suite dependencies OK in the single
> common-at-classes/pom.xml location .
> But their is no way to modularize the actual XML code that runs each
> test-suite with plugin executions - these plugin execution stanzas can 
> currently ONLY
> be in each test-suite#N directory, even though they are identical.
> It would make no sense to have the "Super POM" : acceptance-tests/pom.xml 
> contain the plugin executions to run any single test  suite ;  nor can the 
> common-at-classes/pom.xml contain the plugin execution to run any 
> test suite, since a test suite run depends on the customized test resource
> files that only exist in each "test_suite#N/" sub-project .  
> So the only solution currently available with Maven is to copy the XML stanzas
> that configure and run the test suite ( about 400 lines of XML )  into each of
> the 10-20 test-suite/pom.xml files ; this is all because Maven does not 
> support 
> XML XInclude or XML Entities; if it did, we could put all this code into one 
> XML 
> file provided by the common-at-classes project, and include it in each test 
> suite .
> The test suite XML is then a nightmare to maintain, consistently for all test 
> suites.
> This is becoming such a problem that I am considering making the root project
> POM do nothing more than transform the test-suite poms with XML XInclude-s
> (using an external XML processor), creating a new copy of the whole project,
>  and then run an exec plugin goal which runs maven with the transformed POMs.
> Please, please can we have some form of XInclude or XML Entity support , or 
> support for an "<include ...>" element, in the POM parser !



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to