Skip to content

Commit 4c32684

Browse files
committed
DefaultModelXmlFactory: make location tracking opt-in—disabled by default, enabled when an InputLocationFormatter is provided.
Adapt formatter to Function<InputLocation,String> and write to the actually opened stream for path output. Fixes #10939.
1 parent 667714d commit 4c32684

File tree

2 files changed

+88
-13
lines changed

2 files changed

+88
-13
lines changed

impl/maven-impl/src/main/java/org/apache/maven/impl/DefaultModelXmlFactory.java

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@
2525
import java.net.URL;
2626
import java.nio.file.Files;
2727
import java.nio.file.Path;
28+
import java.util.Objects;
2829
import java.util.function.Function;
2930

3031
import org.apache.maven.api.annotations.Nonnull;
3132
import org.apache.maven.api.di.Named;
3233
import org.apache.maven.api.di.Singleton;
34+
import org.apache.maven.api.model.InputLocation;
3335
import org.apache.maven.api.model.InputSource;
3436
import org.apache.maven.api.model.Model;
3537
import org.apache.maven.api.services.xml.ModelXmlFactory;
@@ -115,28 +117,38 @@ private Model doRead(XmlReaderRequest request) throws XmlReaderException {
115117
}
116118

117119
@Override
118-
public void write(XmlWriterRequest<Model> request) throws XmlWriterException {
119-
requireNonNull(request, "request");
120-
Model content = requireNonNull(request.getContent(), "content");
121-
Path path = request.getPath();
122-
OutputStream outputStream = request.getOutputStream();
123-
Writer writer = request.getWriter();
124-
Function<Object, String> inputLocationFormatter = request.getInputLocationFormatter();
120+
public void write(final XmlWriterRequest<Model> request) throws XmlWriterException {
121+
Objects.requireNonNull(request, "request can not be null");
122+
final Model content = Objects.requireNonNull(request.getContent(), "content can not be null");
123+
124+
final Path path = request.getPath();
125+
final OutputStream outputStream = request.getOutputStream();
126+
final Writer writer = request.getWriter();
127+
125128
if (writer == null && outputStream == null && path == null) {
126129
throw new IllegalArgumentException("writer, outputStream or path must be non null");
127130
}
131+
128132
try {
129-
MavenStaxWriter w = new MavenStaxWriter();
130-
if (inputLocationFormatter != null) {
131-
w.setStringFormatter((Function) inputLocationFormatter);
133+
// OFF by default
134+
final MavenStaxWriter xmlWriter = new MavenStaxWriter();
135+
xmlWriter.setAddLocationInformation(false);
136+
137+
// Opt-in when a formatter is provided; adapt to the required type
138+
final Function<Object, String> fmt = request.getInputLocationFormatter();
139+
if (fmt != null) {
140+
xmlWriter.setAddLocationInformation(true);
141+
final Function<InputLocation, String> adapter = fmt::apply;
142+
xmlWriter.setStringFormatter(adapter);
132143
}
144+
133145
if (writer != null) {
134-
w.write(writer, content);
146+
xmlWriter.write(writer, content);
135147
} else if (outputStream != null) {
136-
w.write(outputStream, content);
148+
xmlWriter.write(outputStream, content);
137149
} else {
138150
try (OutputStream os = Files.newOutputStream(path)) {
139-
w.write(os, content);
151+
xmlWriter.write(os, content);
140152
}
141153
}
142154
} catch (Exception e) {

impl/maven-impl/src/test/java/org/apache/maven/impl/DefaultModelXmlFactoryTest.java

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,18 @@
1919
package org.apache.maven.impl;
2020

2121
import java.io.StringReader;
22+
import java.io.StringWriter;
23+
import java.util.function.Function;
2224

2325
import org.apache.maven.api.model.Model;
2426
import org.apache.maven.api.services.xml.XmlReaderException;
2527
import org.apache.maven.api.services.xml.XmlReaderRequest;
28+
import org.apache.maven.api.services.xml.XmlWriterRequest;
2629
import org.junit.jupiter.api.BeforeEach;
2730
import org.junit.jupiter.api.Test;
2831

2932
import static org.junit.jupiter.api.Assertions.assertEquals;
33+
import static org.junit.jupiter.api.Assertions.assertFalse;
3034
import static org.junit.jupiter.api.Assertions.assertThrows;
3135
import static org.junit.jupiter.api.Assertions.assertTrue;
3236

@@ -122,4 +126,63 @@ void testMalformedModelVersion() throws Exception {
122126
Model model = factory.read(request);
123127
assertEquals("invalid.version", model.getModelVersion());
124128
}
129+
130+
@Test
131+
void testWriteWithoutFormatterDisablesLocationTracking() throws Exception {
132+
// minimal valid model we can round-trip
133+
String xml =
134+
"""
135+
<project xmlns="http://maven.apache.org/POM/4.0.0">
136+
<modelVersion>4.0.0</modelVersion>
137+
<groupId>g</groupId>
138+
<artifactId>a</artifactId>
139+
<version>1</version>
140+
</project>""";
141+
142+
Model model = factory.read(XmlReaderRequest.builder()
143+
.reader(new StringReader(xml))
144+
.strict(true)
145+
.build());
146+
147+
StringWriter out = new StringWriter();
148+
factory.write(XmlWriterRequest.<Model>builder()
149+
.writer(out)
150+
.content(model)
151+
// no formatter -> tracking should be OFF
152+
.build());
153+
154+
String result = out.toString();
155+
// And certainly not our marker
156+
assertFalse(result.contains("LOC_MARK"), "Unexpected marker found in output");
157+
}
158+
159+
@Test
160+
void testWriteWithFormatterEnablesLocationTracking() throws Exception {
161+
String xml =
162+
"""
163+
<project xmlns="http://maven.apache.org/POM/4.0.0">
164+
<modelVersion>4.0.0</modelVersion>
165+
<groupId>g</groupId>
166+
<artifactId>a</artifactId>
167+
<version>1</version>
168+
</project>""";
169+
170+
Model model = factory.read(XmlReaderRequest.builder()
171+
.reader(new StringReader(xml))
172+
.strict(true)
173+
.build());
174+
175+
StringWriter out = new StringWriter();
176+
Function<Object, String> formatter = o -> "LOC_MARK";
177+
178+
factory.write(XmlWriterRequest.<Model>builder()
179+
.writer(out)
180+
.content(model)
181+
.inputLocationFormatter(formatter)
182+
.build());
183+
184+
String result = out.toString();
185+
// Presence of our formatter's output proves tracking was enabled and formatter applied
186+
assertTrue(result.contains("LOC_MARK"), "Expected formatter marker in output when tracking is enabled");
187+
}
125188
}

0 commit comments

Comments
 (0)