Skip to content

Added support for 'standalone' attribute in StaxEventItemWriter #3764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ allprojects {
servletApiVersion = '4.0.1'
sqlfireclientVersion = '1.0.3'
sqliteVersion = '3.32.3.2'
woodstoxVersion = '6.2.0'
woodstoxVersion = '6.2.1'
xmlunitVersion = '2.7.0'
xstreamVersion = '1.4.12'
jrubyVersion = '1.7.27'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2017 the original author or authors.
* Copyright 2006-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -72,7 +72,7 @@
* @author Peter Zozom
* @author Robert Kasanicky
* @author Michael Minella
*
* @author Parikshit Dutta
*/
public class StaxEventItemWriter<T> extends AbstractItemStreamItemWriter<T> implements
ResourceAwareItemWriterItemStream<T>, InitializingBean {
Expand All @@ -85,6 +85,9 @@ public class StaxEventItemWriter<T> extends AbstractItemStreamItemWriter<T> impl
// default encoding
public static final String DEFAULT_XML_VERSION = "1.0";

// default standalone document declaration, value not set
public static final Boolean DEFAULT_STANDALONE_DOCUMENT = null;

// default root tag name
public static final String DEFAULT_ROOT_TAG_NAME = "root";

Expand All @@ -109,6 +112,9 @@ public class StaxEventItemWriter<T> extends AbstractItemStreamItemWriter<T> impl
// XML version
private String version = DEFAULT_XML_VERSION;

// standalone header attribute
private Boolean standalone = DEFAULT_STANDALONE_DOCUMENT;

// name of the root tag
private String rootTagName = DEFAULT_ROOT_TAG_NAME;

Expand Down Expand Up @@ -270,6 +276,29 @@ public void setVersion(String version) {
this.version = version;
}

/**
* Get used standalone document declaration.
*
* @return the standalone document declaration used
*
* @since 4.3
*/
public Boolean getStandalone() {
return standalone;
}

/**
* Set standalone document declaration to be used for output XML. If not set,
* standalone document declaration will be omitted.
*
* @param standalone the XML standalone document declaration to be used
*
* @since 4.3
*/
public void setStandalone(Boolean standalone) {
this.standalone = standalone;
}

/**
* Get the tag name of the root element.
*
Expand Down Expand Up @@ -606,7 +635,12 @@ protected void startDocument(XMLEventWriter writer) throws XMLStreamException {
XMLEventFactory factory = createXmlEventFactory();

// write start document
writer.add(factory.createStartDocument(getEncoding(), getVersion()));
if (getStandalone()==null) {
writer.add(factory.createStartDocument(getEncoding(), getVersion()));
}
else {
writer.add(factory.createStartDocument(getEncoding(), getVersion(), getStandalone()));
}

// write root tag
writer.add(factory.createStartElement(getRootTagNamespacePrefix(), getRootTagNamespace(), getRootTagName()));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -27,6 +27,7 @@
* A builder for the {@link StaxEventItemWriter}.
*
* @author Michael Minella
* @author Parikshit Dutta
* @since 4.0
* @see StaxEventItemWriter
*/
Expand All @@ -50,6 +51,8 @@ public class StaxEventItemWriterBuilder<T> {

private String version = StaxEventItemWriter.DEFAULT_XML_VERSION;

private Boolean standalone = StaxEventItemWriter.DEFAULT_STANDALONE_DOCUMENT;

private String rootTagName = StaxEventItemWriter.DEFAULT_ROOT_TAG_NAME;

private Map<String, String> rootElementAttributes;
Expand Down Expand Up @@ -188,14 +191,29 @@ public StaxEventItemWriterBuilder<T> encoding(String encoding) {
*
* @param version XML version
* @return the current instance of the builder
* @see StaxEventItemWriter#version
* @see StaxEventItemWriter#setVersion(String)
*/
public StaxEventItemWriterBuilder<T> version(String version) {
this.version = version;

return this;
}

/**
* Standalone document declaration for the output document. Defaults to null.
*
* @param standalone Boolean standalone document declaration
* @return the current instance of the builder
* @see StaxEventItemWriter#setStandalone(Boolean)
*
* @since 4.3
*/
public StaxEventItemWriterBuilder<T> standalone(Boolean standalone) {
this.standalone = standalone;

return this;
}

/**
* The name of the root tag for the output document.
*
Expand Down Expand Up @@ -278,6 +296,7 @@ public StaxEventItemWriter<T> build() {
writer.setTransactional(this.transactional);
writer.setVersion(this.version);
writer.setName(this.name);
writer.setStandalone(this.standalone);

return writer;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2008-2014 the original author or authors.
* Copyright 2008-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -55,6 +55,8 @@

/**
* Tests for {@link StaxEventItemWriter}.
*
* @author Parikshit Dutta
*/
public class StaxEventItemWriterTests {

Expand Down Expand Up @@ -137,6 +139,35 @@ public void testAssertWriterIsInitialized() throws Exception {
writer.write(Collections.singletonList("foo"));
}

@Test
public void testStandaloneDeclarationInHeaderWhenNotSet() throws Exception {
writer.open(executionContext);
writer.write(items);
writer.close();
String content = getOutputFileContent(writer.getEncoding(), false);
assertFalse(content.contains("standalone="));
}

@Test
public void testStandaloneDeclarationInHeaderWhenSetToTrue() throws Exception {
writer.setStandalone(true);
writer.open(executionContext);
writer.write(items);
writer.close();
String content = getOutputFileContent(writer.getEncoding(), false);
assertTrue(content.contains("standalone='yes'"));
}

@Test
public void testStandaloneDeclarationInHeaderWhenSetToFalse() throws Exception {
writer.setStandalone(false);
writer.open(executionContext);
writer.write(items);
writer.close();
String content = getOutputFileContent(writer.getEncoding(), false);
assertTrue(content.contains("standalone='no'"));
}

/**
* Item is written to the output file only after flush.
*/
Expand Down Expand Up @@ -982,12 +1013,28 @@ private String getOutputFileContent() throws IOException {
* @return output file content as String
*/
private String getOutputFileContent(String encoding) throws IOException {
return getOutputFileContent(encoding, true);
}

/**
* @param encoding the encoding
* @param discardHeader the flag to strip XML header
* @return output file content as String
*/
private String getOutputFileContent(String encoding, boolean discardHeader) throws IOException {
String value = FileUtils.readFileToString(resource.getFile(), encoding);
value = value.replace("<?xml version='1.0' encoding='" + encoding + "'?>", "");
if (discardHeader) {
// standalone is omitted if not explicitly set, meaning it will be 'yes'/'no' or no standalone attribute
if (value.contains("standalone")) {
boolean standalone = value.contains("standalone='yes'");
return value.replace("<?xml version='1.0' encoding='" + encoding + "' " +
(standalone ? "standalone='yes'" : "standalone='no'") + "?>", "");
}
return value.replace("<?xml version='1.0' encoding='" + encoding + "'?>", "");
}
return value;
}


/**
* @return new instance of fully configured writer
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017 the original author or authors.
* Copyright 2017-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -46,6 +46,7 @@

/**
* @author Michael Minella
* @author Parikshit Dutta
*/
public class StaxEventItemWriterBuilderTests {

Expand Down Expand Up @@ -224,9 +225,85 @@ public void testMissingNameValidation() {
.build();
}

@Test
public void testStandaloneDeclarationInHeaderWhenNotSet() throws Exception {
StaxEventItemWriter<Foo> staxEventItemWriter = new StaxEventItemWriterBuilder<Foo>()
.name("fooWriter")
.marshaller(marshaller)
.resource(this.resource)
.build();

staxEventItemWriter.afterPropertiesSet();

ExecutionContext executionContext = new ExecutionContext();
staxEventItemWriter.open(executionContext);
staxEventItemWriter.write(this.items);
staxEventItemWriter.close();

String output = getOutputFileContent(staxEventItemWriter.getEncoding(), false);
assertFalse(output.contains("standalone="));
}

@Test
public void testStandaloneDeclarationInHeaderWhenSetToTrue() throws Exception {
StaxEventItemWriter<Foo> staxEventItemWriter = new StaxEventItemWriterBuilder<Foo>()
.name("fooWriter")
.marshaller(marshaller)
.resource(this.resource)
.standalone(true)
.build();

staxEventItemWriter.afterPropertiesSet();

ExecutionContext executionContext = new ExecutionContext();
staxEventItemWriter.open(executionContext);
staxEventItemWriter.write(this.items);
staxEventItemWriter.close();

String output = getOutputFileContent(staxEventItemWriter.getEncoding(), false);
assertTrue(output.contains("standalone='yes'"));
}

@Test
public void testStandaloneDeclarationInHeaderWhenSetToFalse() throws Exception {
StaxEventItemWriter<Foo> staxEventItemWriter = new StaxEventItemWriterBuilder<Foo>()
.name("fooWriter")
.marshaller(marshaller)
.resource(this.resource)
.standalone(false)
.build();

staxEventItemWriter.afterPropertiesSet();

ExecutionContext executionContext = new ExecutionContext();
staxEventItemWriter.open(executionContext);
staxEventItemWriter.write(this.items);
staxEventItemWriter.close();

String output = getOutputFileContent(staxEventItemWriter.getEncoding(), false);
assertTrue(output.contains("standalone='no'"));
}

private String getOutputFileContent(String encoding) throws IOException {
return getOutputFileContent(encoding, true);
}

/**
* @param encoding the encoding
* @param discardHeader the flag to strip XML header
* @return output file content as String
*/
private String getOutputFileContent(String encoding, boolean discardHeader) throws IOException {
String value = FileUtils.readFileToString(resource.getFile(), encoding);
value = value.replace("<?xml version='1.0' encoding='" + encoding + "'?>", "");
if (discardHeader) {
// standalone is omitted if not explicitly set, meaning it will be 'yes'/'no' or no standalone attribute
if (value.contains("standalone")) {
boolean standalone = value.contains("standalone='yes'");
return value.replace("<?xml version='1.0' encoding='" + encoding + "' " +
(standalone ? "standalone='yes'" : "standalone='no'") + "?>", "");
}
return value.replace("<?xml version='1.0' encoding='" + encoding + "'?>", "");
}
return value;
}

Expand Down