Skip to content

Commit e68ec7d

Browse files
author
Vincent Potucek
committed
Test unused stream in DefaultPluginXmlFactory#write
1 parent d777133 commit e68ec7d

File tree

3 files changed

+324
-12
lines changed

3 files changed

+324
-12
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ public void write(XmlWriterRequest<Model> request) throws XmlWriterException {
121121
Writer writer = request.getWriter();
122122
Function<Object, String> inputLocationFormatter = request.getInputLocationFormatter();
123123
if (writer == null && outputStream == null && path == null) {
124-
throw new IllegalArgumentException("writer, outputStream or path must be non null");
124+
throw new IllegalArgumentException("writer, output stream, or path must be non null");
125125
}
126126
try {
127127
MavenStaxWriter w = new MavenStaxWriter();

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

+28-11
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
*/
1919
package org.apache.maven.impl;
2020

21+
import javax.xml.stream.XMLStreamException;
22+
23+
import java.io.IOException;
2124
import java.io.InputStream;
2225
import java.io.OutputStream;
2326
import java.io.Reader;
@@ -45,37 +48,47 @@
4548
@Named
4649
@Singleton
4750
public class DefaultPluginXmlFactory implements PluginXmlFactory {
51+
4852
@Override
4953
public PluginDescriptor read(@Nonnull XmlReaderRequest request) throws XmlReaderException {
5054
nonNull(request, "request");
5155
Path path = request.getPath();
5256
URL url = request.getURL();
5357
Reader reader = request.getReader();
5458
InputStream inputStream = request.getInputStream();
55-
if (path == null && url == null && reader == null && inputStream == null) {
59+
if (inputStream == null && reader == null && path == null && url == null) {
5660
throw new IllegalArgumentException("path, url, reader or inputStream must be non null");
5761
}
62+
return read(request, inputStream, reader, path, url);
63+
}
64+
65+
private static PluginDescriptor read(
66+
XmlReaderRequest request, InputStream inputStream, Reader reader, Path path, URL url) {
5867
try {
5968
PluginDescriptorStaxReader xml = new PluginDescriptorStaxReader();
6069
xml.setAddDefaultEntities(request.isAddDefaultEntities());
6170
if (inputStream != null) {
62-
return xml.read(inputStream, request.isStrict());
71+
return read(request, xml, inputStream);
6372
} else if (reader != null) {
6473
return xml.read(reader, request.isStrict());
6574
} else if (path != null) {
6675
try (InputStream is = Files.newInputStream(path)) {
67-
return xml.read(is, request.isStrict());
68-
}
69-
} else {
70-
try (InputStream is = url.openStream()) {
71-
return xml.read(is, request.isStrict());
76+
return read(request, xml, is);
7277
}
7378
}
74-
} catch (Exception e) {
79+
try (InputStream is = url.openStream()) {
80+
return read(request, xml, is);
81+
}
82+
} catch (IOException | XMLStreamException e) {
7583
throw new XmlReaderException("Unable to read plugin: " + getMessage(e), getLocation(e), e);
7684
}
7785
}
7886

87+
private static PluginDescriptor read(XmlReaderRequest request, PluginDescriptorStaxReader xml, InputStream is)
88+
throws XMLStreamException {
89+
return xml.read(is, request.isStrict());
90+
}
91+
7992
@Override
8093
public void write(XmlWriterRequest<PluginDescriptor> request) throws XmlWriterException {
8194
nonNull(request, "request");
@@ -84,19 +97,23 @@ public void write(XmlWriterRequest<PluginDescriptor> request) throws XmlWriterEx
8497
OutputStream outputStream = request.getOutputStream();
8598
Writer writer = request.getWriter();
8699
if (writer == null && outputStream == null && path == null) {
87-
throw new IllegalArgumentException("writer, outputStream or path must be non null");
100+
throw new IllegalArgumentException("writer, output stream, or path must be non null");
88101
}
102+
write(writer, content, outputStream, path);
103+
}
104+
105+
private static void write(Writer writer, PluginDescriptor content, OutputStream outputStream, Path path) {
89106
try {
90107
if (writer != null) {
91108
new PluginDescriptorStaxWriter().write(writer, content);
92109
} else if (outputStream != null) {
93110
new PluginDescriptorStaxWriter().write(outputStream, content);
94111
} else {
95112
try (OutputStream os = Files.newOutputStream(path)) {
96-
new PluginDescriptorStaxWriter().write(outputStream, content);
113+
new PluginDescriptorStaxWriter().write(os, content);
97114
}
98115
}
99-
} catch (Exception e) {
116+
} catch (IOException | XMLStreamException e) {
100117
throw new XmlWriterException("Unable to write plugin: " + getMessage(e), getLocation(e), e);
101118
}
102119
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package org.apache.maven.impl;
20+
21+
import java.io.ByteArrayInputStream;
22+
import java.io.ByteArrayOutputStream;
23+
import java.io.IOException;
24+
import java.io.StringReader;
25+
import java.io.StringWriter;
26+
import java.io.Writer;
27+
import java.nio.file.Files;
28+
import java.nio.file.Path;
29+
import java.util.List;
30+
31+
import com.ctc.wstx.exc.WstxEOFException;
32+
import org.apache.maven.api.plugin.descriptor.PluginDescriptor;
33+
import org.apache.maven.api.services.xml.ModelXmlFactory;
34+
import org.apache.maven.api.services.xml.XmlReaderException;
35+
import org.apache.maven.api.services.xml.XmlReaderRequest;
36+
import org.apache.maven.api.services.xml.XmlWriterException;
37+
import org.apache.maven.api.services.xml.XmlWriterRequest;
38+
import org.apache.maven.impl.model.DefaultModelProcessor;
39+
import org.junit.jupiter.api.Disabled;
40+
import org.junit.jupiter.api.Test;
41+
import org.junit.jupiter.api.io.TempDir;
42+
43+
import static java.util.UUID.randomUUID;
44+
import static org.assertj.core.api.Assertions.assertThat;
45+
import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType;
46+
import static org.junit.jupiter.api.Assertions.assertNotNull;
47+
import static org.junit.jupiter.api.Assertions.assertThrows;
48+
import static org.mockito.Mockito.mock;
49+
import static org.mockito.Mockito.when;
50+
51+
class DefaultPluginXmlFactoryReadWriteTest {
52+
53+
private static final String NAME = "sample-plugin-" + randomUUID();
54+
private static final String SAMPLE_PLUGIN_XML =
55+
"""
56+
<?xml version="1.0" encoding="UTF-8"?>
57+
<plugin>
58+
<name>%s</name>
59+
<groupId>org.example</groupId>
60+
<artifactId>sample-plugin</artifactId>
61+
<version>1.0.0</version>
62+
</plugin>
63+
"""
64+
.formatted(NAME);
65+
66+
private final DefaultPluginXmlFactory defaultPluginXmlFactory = new DefaultPluginXmlFactory();
67+
68+
@TempDir
69+
Path tempDir;
70+
71+
@Test
72+
void readFromInputStreamParsesPluginDescriptorCorrectly() {
73+
PluginDescriptor descriptor = defaultPluginXmlFactory.read(XmlReaderRequest.builder()
74+
.inputStream(new ByteArrayInputStream(SAMPLE_PLUGIN_XML.getBytes()))
75+
.build());
76+
assertThat(descriptor.getName()).isEqualTo(NAME);
77+
assertThat(descriptor.getGroupId()).isEqualTo("org.example");
78+
assertThat(descriptor.getArtifactId()).isEqualTo("sample-plugin");
79+
assertThat(descriptor.getVersion()).isEqualTo("1.0.0");
80+
}
81+
82+
@Test
83+
void parsePlugin() {
84+
assertThat(defaultPluginXmlFactory
85+
.read(XmlReaderRequest.builder()
86+
.reader(new StringReader(SAMPLE_PLUGIN_XML))
87+
.build())
88+
.getName())
89+
.isEqualTo(NAME);
90+
}
91+
92+
@Test
93+
@Disabled
94+
void readFromPathParsesPluginDescriptorCorrectly() throws Exception {
95+
Path xmlFile = tempDir.resolve("plugin.xml");
96+
Files.write(xmlFile, SAMPLE_PLUGIN_XML.getBytes());
97+
assertThat(defaultPluginXmlFactory
98+
.read(XmlReaderRequest.builder().path(xmlFile).build())
99+
.getName())
100+
.isEqualTo(NAME);
101+
}
102+
103+
@Test
104+
void readWithNoInputThrowsIllegalArgumentException() {
105+
assertThatExceptionOfType(IllegalArgumentException.class)
106+
.isThrownBy(() ->
107+
defaultPluginXmlFactory.read(XmlReaderRequest.builder().build()));
108+
}
109+
110+
@Test
111+
void writeToWriterGeneratesValidXml() {
112+
StringWriter writer = new StringWriter();
113+
defaultPluginXmlFactory.write(XmlWriterRequest.<PluginDescriptor>builder()
114+
.writer(writer)
115+
.content(PluginDescriptor.newBuilder()
116+
.name(NAME)
117+
.groupId("org.example")
118+
.artifactId("sample-plugin")
119+
.version("1.0.0")
120+
.build())
121+
.build());
122+
String output = writer.toString();
123+
assertThat(output).contains("<name>" + NAME + "</name>");
124+
assertThat(output).contains("<groupId>org.example</groupId>");
125+
}
126+
127+
@Test
128+
void writeToOutputStreamGeneratesValidXml() {
129+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
130+
defaultPluginXmlFactory.write(XmlWriterRequest.<PluginDescriptor>builder()
131+
.outputStream(outputStream)
132+
.content(PluginDescriptor.newBuilder().name(NAME).build())
133+
.build());
134+
assertThat(outputStream.toString()).contains("<name>" + NAME + "</name>");
135+
}
136+
137+
@Test
138+
void writeToPathGeneratesValidXmlFile() throws Exception {
139+
Path xmlFile = tempDir.resolve("output-plugin.xml");
140+
defaultPluginXmlFactory.write(XmlWriterRequest.<PluginDescriptor>builder()
141+
.path(xmlFile)
142+
.content(PluginDescriptor.newBuilder().name(NAME).build())
143+
.build());
144+
assertThat(Files.readString(xmlFile)).contains("<name>" + NAME + "</name>");
145+
}
146+
147+
@Test
148+
void fromXmlStringParsesValidXml() {
149+
PluginDescriptor descriptor = defaultPluginXmlFactory.fromXmlString(SAMPLE_PLUGIN_XML);
150+
assertThat(descriptor.getName()).isEqualTo(NAME);
151+
assertThat(descriptor.getGroupId()).isEqualTo("org.example");
152+
assertThat(descriptor.getArtifactId()).isEqualTo("sample-plugin");
153+
assertThat(descriptor.getVersion()).isEqualTo("1.0.0");
154+
}
155+
156+
@Test
157+
void toXmlStringGeneratesValidXml() {
158+
String xml = defaultPluginXmlFactory.toXmlString(PluginDescriptor.newBuilder()
159+
.name(NAME)
160+
.groupId("org.example")
161+
.artifactId("sample-plugin")
162+
.version("1.0.0")
163+
.build());
164+
assertThat(xml).contains("<name>" + NAME + "</name>");
165+
assertThat(xml).contains("<groupId>org.example</groupId>");
166+
assertThat(xml).contains("<artifactId>sample-plugin</artifactId>");
167+
assertThat(xml).contains("<version>1.0.0</version>");
168+
}
169+
170+
@Test
171+
void staticFromXmlParsesValidXml() {
172+
PluginDescriptor descriptor = DefaultPluginXmlFactory.fromXml(SAMPLE_PLUGIN_XML);
173+
assertThat(descriptor.getName()).isEqualTo(NAME);
174+
assertThat(descriptor.getGroupId()).isEqualTo("org.example");
175+
assertThat(descriptor.getArtifactId()).isEqualTo("sample-plugin");
176+
assertThat(descriptor.getVersion()).isEqualTo("1.0.0");
177+
}
178+
179+
@Test
180+
void staticToXmlGeneratesValidXml() {
181+
String xml = DefaultPluginXmlFactory.toXml(PluginDescriptor.newBuilder()
182+
.name(NAME)
183+
.groupId("org.example")
184+
.artifactId("sample-plugin")
185+
.version("1.0.0")
186+
.build());
187+
assertThat(xml).contains("<name>" + NAME + "</name>");
188+
assertThat(xml).contains("<name>" + NAME + "</name>");
189+
assertThat(xml).contains("<groupId>org.example</groupId>");
190+
assertThat(xml).contains("<artifactId>sample-plugin</artifactId>");
191+
assertThat(xml).contains("<version>1.0.0</version>");
192+
}
193+
194+
@Test
195+
void writeWithFailingWriterThrowsXmlWriterException() {
196+
String unableToWritePlugin = "Unable to write plugin" + randomUUID();
197+
String ioEx = "ioEx" + randomUUID();
198+
XmlWriterException exception = assertThatExceptionOfType(XmlWriterException.class)
199+
.isThrownBy(() -> defaultPluginXmlFactory.write(XmlWriterRequest.<PluginDescriptor>builder()
200+
.writer(new Writer() {
201+
@Override
202+
public void write(char[] cbuf, int off, int len) {
203+
throw new XmlWriterException(unableToWritePlugin, null, new IOException(ioEx));
204+
}
205+
206+
@Override
207+
public void flush() {}
208+
209+
@Override
210+
public void close() {}
211+
})
212+
.content(PluginDescriptor.newBuilder()
213+
.name("Failing Plugin")
214+
.build())
215+
.build()))
216+
.actual();
217+
assertThat(exception.getMessage()).contains(unableToWritePlugin);
218+
assertThat(exception.getCause()).isInstanceOf(IOException.class);
219+
assertThat(exception.getCause().getMessage()).isEqualTo(ioEx);
220+
}
221+
222+
@Test
223+
void writeWithNoTargetThrowsIllegalArgumentException() {
224+
assertThat(assertThrows(
225+
IllegalArgumentException.class,
226+
() -> defaultPluginXmlFactory.write(XmlWriterRequest.<PluginDescriptor>builder()
227+
.content(PluginDescriptor.newBuilder()
228+
.name("No Output Plugin")
229+
.build())
230+
.build()))
231+
.getMessage())
232+
.isEqualTo("writer, output stream, or path must be non null");
233+
}
234+
235+
@Test
236+
void readMalformedXmlThrowsXmlReaderException() {
237+
XmlReaderException exception = assertThatExceptionOfType(XmlReaderException.class)
238+
.isThrownBy(() -> defaultPluginXmlFactory.read(XmlReaderRequest.builder()
239+
.inputStream(new ByteArrayInputStream("<plugin><name>Broken Plugin".getBytes()))
240+
.build()))
241+
.actual();
242+
assertThat(exception.getMessage()).contains("Unable to read plugin");
243+
assertThat(exception.getCause()).isInstanceOf(WstxEOFException.class);
244+
}
245+
246+
@Test
247+
void locateExistingPomWithFilePathShouldReturnSameFileIfRegularFile() throws IOException {
248+
Path pomFile = Files.createTempFile(tempDir, "pom", ".xml");
249+
DefaultModelProcessor processor = new DefaultModelProcessor(mock(ModelXmlFactory.class), List.of());
250+
assertThat(processor.locateExistingPom(pomFile)).isEqualTo(pomFile);
251+
}
252+
253+
@Test
254+
void readFromUrlParsesPluginDescriptorCorrectly() throws Exception {
255+
Path xmlFile = tempDir.resolve("plugin.xml");
256+
Files.write(xmlFile, SAMPLE_PLUGIN_XML.getBytes());
257+
PluginDescriptor descriptor = defaultPluginXmlFactory.read(XmlReaderRequest.builder()
258+
.inputStream(xmlFile.toUri().toURL().openStream())
259+
.build());
260+
assertThat(descriptor.getName()).isEqualTo(NAME);
261+
assertThat(descriptor.getGroupId()).isEqualTo("org.example");
262+
assertThat(descriptor.getArtifactId()).isEqualTo("sample-plugin");
263+
assertThat(descriptor.getVersion()).isEqualTo("1.0.0");
264+
}
265+
266+
@Test
267+
void testReadWithPath() throws Exception {
268+
Path tempPath = Files.createTempFile("plugin", ".xml");
269+
Files.writeString(tempPath, "<plugin/>");
270+
XmlReaderRequest request = mock(XmlReaderRequest.class);
271+
when(request.getPath()).thenReturn(tempPath);
272+
when(request.getInputStream()).thenReturn(null);
273+
when(request.getReader()).thenReturn(null);
274+
when(request.getURL()).thenReturn(null);
275+
when(request.isAddDefaultEntities()).thenReturn(false);
276+
when(request.isStrict()).thenReturn(false);
277+
assertNotNull(new DefaultPluginXmlFactory().read(request));
278+
Files.deleteIfExists(tempPath);
279+
}
280+
281+
@Test
282+
void testReadWithPathUrlDefault() throws Exception {
283+
Path tempPath = Files.createTempFile("plugin", ".xml");
284+
Files.writeString(tempPath, "<plugin/>");
285+
XmlReaderRequest request = mock(XmlReaderRequest.class);
286+
when(request.getPath()).thenReturn(null);
287+
when(request.getInputStream()).thenReturn(null);
288+
when(request.getReader()).thenReturn(null);
289+
when(request.getURL()).thenReturn(tempPath.toUri().toURL());
290+
when(request.isAddDefaultEntities()).thenReturn(false);
291+
when(request.isStrict()).thenReturn(false);
292+
assertNotNull(new DefaultPluginXmlFactory().read(request));
293+
Files.deleteIfExists(tempPath);
294+
}
295+
}

0 commit comments

Comments
 (0)