diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java index f447627cc794..e7a699e3b037 100644 --- a/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java +++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java @@ -30,6 +30,7 @@ import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.di.Named; import org.apache.maven.api.di.Singleton; +import org.apache.maven.api.model.InputLocation; import org.apache.maven.api.model.InputSource; import org.apache.maven.api.model.Model; import org.apache.maven.api.services.xml.ModelXmlFactory; @@ -121,22 +122,29 @@ public void write(XmlWriterRequest request) throws XmlWriterException { Path path = request.getPath(); OutputStream outputStream = request.getOutputStream(); Writer writer = request.getWriter(); - Function inputLocationFormatter = request.getInputLocationFormatter(); + if (writer == null && outputStream == null && path == null) { throw new IllegalArgumentException("writer, outputStream or path must be non null"); } + try { - MavenStaxWriter w = new MavenStaxWriter(); - if (inputLocationFormatter != null) { - w.setStringFormatter((Function) inputLocationFormatter); + MavenStaxWriter xmlWriter = new MavenStaxWriter(); + xmlWriter.setAddLocationInformation(false); + + Function formatter = request.getInputLocationFormatter(); + if (formatter != null) { + xmlWriter.setAddLocationInformation(true); + Function adapter = formatter::apply; + xmlWriter.setStringFormatter(adapter); } + if (writer != null) { - w.write(writer, content); + xmlWriter.write(writer, content); } else if (outputStream != null) { - w.write(outputStream, content); + xmlWriter.write(outputStream, content); } else { try (OutputStream os = Files.newOutputStream(path)) { - w.write(os, content); + xmlWriter.write(os, content); } } } catch (Exception e) { diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultModelXmlFactoryTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultModelXmlFactoryTest.java index 436d7b979876..badb8612da3f 100644 --- a/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultModelXmlFactoryTest.java +++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultModelXmlFactoryTest.java @@ -19,14 +19,18 @@ package org.apache.maven.impl; import java.io.StringReader; +import java.io.StringWriter; +import java.util.function.Function; import org.apache.maven.api.model.Model; import org.apache.maven.api.services.xml.XmlReaderException; import org.apache.maven.api.services.xml.XmlReaderRequest; +import org.apache.maven.api.services.xml.XmlWriterRequest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -122,4 +126,62 @@ void testMalformedModelVersion() throws Exception { Model model = factory.read(request); assertEquals("invalid.version", model.getModelVersion()); } + + @Test + void testWriteWithoutFormatterDisablesLocationTracking() throws Exception { + // minimal valid model we can round-trip + String xml = + """ + + 4.0.0 + g + a + 1 + """; + + Model model = factory.read(XmlReaderRequest.builder() + .reader(new StringReader(xml)) + .strict(true) + .build()); + + StringWriter out = new StringWriter(); + factory.write(XmlWriterRequest.builder() + .writer(out) + .content(model) + // no formatter -> tracking should be OFF + .build()); + + String result = out.toString(); + assertFalse(result.contains("LOC_MARK"), "Unexpected marker found in output"); + } + + @Test + void testWriteWithFormatterEnablesLocationTracking() throws Exception { + String xml = + """ + + 4.0.0 + g + a + 1 + """; + + Model model = factory.read(XmlReaderRequest.builder() + .reader(new StringReader(xml)) + .strict(true) + .build()); + + StringWriter out = new StringWriter(); + Function formatter = o -> "LOC_MARK"; + + factory.write(XmlWriterRequest.builder() + .writer(out) + .content(model) + .inputLocationFormatter(formatter) + .build()); + + String result = out.toString(); + // Presence of our formatter's output proves tracking was enabled and formatter applied + assertTrue(result.contains("LOC_MARK"), "Expected formatter marker in output when tracking is enabled"); + } }