Skip to content

Commit

Permalink
Fix bug where xml:space="preserve" would not preserve XML element whi…
Browse files Browse the repository at this point in the history
…tespace content. (#407)

Always save text for XML element that has xml:space="preserve"
Removing thrown exceptions for test utils

Co-authored-by: Björn Ekryd <bjornatekryd.se>
  • Loading branch information
Ekryd authored Feb 20, 2024
1 parent 2f45af3 commit e79e319
Show file tree
Hide file tree
Showing 39 changed files with 329 additions and 208 deletions.
3 changes: 3 additions & 0 deletions sorter/src/main/java/sortpom/content/NewlineText.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@
* in XmlProcessor.PatchedXMLWriter
*/
public class NewlineText extends AbstractText {
public static final NewlineText INSTANCE = new NewlineText();
private static final long serialVersionUID = -7552189498553321263L;

private NewlineText() {}

/**
* This returns a <code>String</code> representation of the <code>NewlineText</code>, suitable for
* debugging.
Expand Down
38 changes: 19 additions & 19 deletions sorter/src/main/java/sortpom/output/PatchedXMLWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,25 @@ public PatchedXMLWriter(
this.endWithNewline = endWithNewline;
}

@Override
public void write(Document doc) throws IOException {
writeDeclaration();

if (doc.getDocType() != null) {
indent();
writeDocType(doc.getDocType());
}

for (int i = 0, size = doc.nodeCount(); i < size; i++) {
var node = doc.node(i);
writeNode(node);
}

if (endWithNewline) {
writePrintln();
}
}

/** Handle spaceBeforeCloseEmptyElement option */
@Override
protected void writeEmptyElementClose(String qualifiedName) throws IOException {
Expand All @@ -62,25 +81,6 @@ protected void writeProcessingInstruction(ProcessingInstruction pi) throws IOExc
lastOutputNodeType = Node.PROCESSING_INSTRUCTION_NODE;
}

@Override
public void write(Document doc) throws IOException {
writeDeclaration();

if (doc.getDocType() != null) {
indent();
writeDocType(doc.getDocType());
}

for (int i = 0, size = doc.nodeCount(); i < size; i++) {
var node = doc.node(i);
writeNode(node);
}

if (endWithNewline) {
writePrintln();
}
}

/** Handle Custom NewLineTest node and potential indent of empty line */
@Override
protected void writeNodeText(Node node) throws IOException {
Expand Down
27 changes: 23 additions & 4 deletions sorter/src/main/java/sortpom/wrapper/TextWrapperCreator.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package sortpom.wrapper;

import java.util.regex.Pattern;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.Text;
import sortpom.content.NewlineText;
import sortpom.parameter.PluginParameters;
import sortpom.wrapper.content.SingleNewlineInTextWrapper;
import sortpom.wrapper.content.UnsortedWrapper;
Expand All @@ -13,29 +14,47 @@
* @since 2012-05-19
*/
public class TextWrapperCreator {

public static final Pattern REGEX_ONE_NEWLINE =
Pattern.compile("^[\\t ]*(\\r|\\n|\\r\\n)[\\t ]*$");
public static final Pattern REGEX_ONE_OR_MORE_NEWLINE = Pattern.compile("^\\s*?([\\r\\n])\\s*$");
private boolean keepBlankLines;

public void setup(PluginParameters pluginParameters) {
keepBlankLines = pluginParameters.keepBlankLines;
}

Wrapper<Node> createWrapper(Text text) {
if (isElementSpacePreserved(text.getParent())) {
return new UnsortedWrapper<>(text);
}
if (isSingleNewLine(text)) {
return SingleNewlineInTextWrapper.INSTANCE;
} else if (isBlankLineOrLines(text)) {
return new UnsortedWrapper<>(new NewlineText());
return UnsortedWrapper.NEWLINE_TEXT_WRAPPER_INSTANCE;
}
return new UnsortedWrapper<>(text);
}

private boolean isElementSpacePreserved(Element element) {
if (element == null) {
return false;
}
var attr = element.attribute("space");

return attr != null
&& "xml".equals(attr.getNamespacePrefix())
&& "preserve".equals(attr.getText());
}

private boolean isSingleNewLine(Text content) {
return content.getText().matches("[\\t ]*\\r?\\n?[\\t ]*");
return REGEX_ONE_NEWLINE.matcher(content.getText()).matches();
}

boolean isBlankLineOrLines(Text content) {
if (!keepBlankLines) {
return false;
}
return content.getText().matches("^\\s*?([\\r\\n])\\s*$");
return REGEX_ONE_OR_MORE_NEWLINE.matcher(content.getText()).matches();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

import org.dom4j.Element;
import org.dom4j.Node;
import sortpom.content.NewlineText;

/** A wrapper that lets is element be unsorted */
public class UnsortedWrapper<T extends Node> implements Wrapper<T> {
public static final UnsortedWrapper<Node> NEWLINE_TEXT_WRAPPER_INSTANCE =
new UnsortedWrapper<>(NewlineText.INSTANCE);

/** The wrapped dom content. */
private final T content;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,23 @@ void illegalEncodingWhenSavingPomFileShouldNotWork() throws IOException {
}

@Test
void differentEncodingShouldWork1() throws Exception {
void differentEncodingShouldWork1() {
SortPomImplUtil.create()
.predefinedSortOrder("default_0_4_0")
.encoding("UTF-32BE")
.testFiles("/UTF32Encoding_input.xml", "/UTF32Encoding_expected.xml");
}

@Test
void differentEncodingShouldWork2() throws Exception {
void differentEncodingShouldWork2() {
SortPomImplUtil.create()
.predefinedSortOrder("default_0_4_0")
.encoding("UTF-16")
.testFiles("/UTF16Encoding_input.xml", "/UTF16Encoding_expected.xml");
}

@Test
void differentEncodingShouldWork3() throws Exception {
void differentEncodingShouldWork3() {
SortPomImplUtil.create()
.predefinedSortOrder("default_0_4_0")
.encoding("ISO-8859-1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
class IgnoreLineSeparatorsTest {

@Test
void ignoringLineSeparatorsShouldNotSort() throws Exception {
void ignoringLineSeparatorsShouldNotSort() {
SortPomImplUtil.create()
.lineSeparator("\n")
.ignoreLineSeparators(true)
.testNoSorting("/ignore_line_separators_input.xml");
}

@Test
void doNotIgnoreLineSeparatorsShouldSort() throws Exception {
void doNotIgnoreLineSeparatorsShouldSort() {
SortPomImplUtil.create()
.lineSeparator("\n")
.ignoreLineSeparators(false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class KeepTimestampParameterTest {

@Test
void whenKeepTimestampNotSetTimestampsShouldDiffer() throws Exception {
void whenKeepTimestampNotSetTimestampsShouldDiffer() {
SortPomImplUtil.create()
.customSortOrderFile("difforder/differentOrder.xml")
.lineSeparator("\n")
Expand All @@ -16,7 +16,7 @@ void whenKeepTimestampNotSetTimestampsShouldDiffer() throws Exception {
}

@Test
void whenKeepTimestampIsSetTimestampsShouldRemain() throws Exception {
void whenKeepTimestampIsSetTimestampsShouldRemain() {
SortPomImplUtil.create()
.customSortOrderFile("difforder/differentOrder.xml")
.lineSeparator("\n")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.lang.reflect.InvocationTargetException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import sortpom.exception.FailureException;
Expand Down Expand Up @@ -52,11 +51,10 @@ void incorrectCustomSortOrderShouldThrowException2() {
.customSortOrderFile("difforder/VERYdifferentOrder.xml")
.testVerifyXmlIsOrdered("/sortOrderFiles/sorted_differentOrder.xml");

var thrown = assertThrows(InvocationTargetException.class, testMethod);
var thrown = assertThrows(RuntimeException.class, testMethod).getCause().getCause();

var cause = thrown.getTargetException();
assertThat(cause, isA(FailureException.class));
assertThat(cause.getMessage(), endsWith("VERYdifferentOrder.xml in classpath"));
assertThat(thrown, isA(FailureException.class));
assertThat(thrown.getMessage(), endsWith("VERYdifferentOrder.xml in classpath"));
}

@Test
Expand All @@ -68,12 +66,11 @@ void incorrectPredefinedSortOrderShouldThrowException2() {
.lineSeparator("\n")
.testVerifyXmlIsOrdered("/sortOrderFiles/sorted_default_0_4_0.xml");

var thrown = assertThrows(InvocationTargetException.class, testMethod);
var thrown = assertThrows(RuntimeException.class, testMethod).getCause().getCause();

var cause = thrown.getTargetException();
assertThat(cause, isA(IllegalArgumentException.class));
assertThat(thrown, isA(IllegalArgumentException.class));
assertThat(
cause.getMessage(),
thrown.getMessage(),
is(equalTo("Cannot find abbie_normal_brain.xml among the predefined plugin resources")));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void violationFileShouldBeCreatedOnVerificationStop() {
}

@Test
void violationFileWithParentDirectoryShouldBeCreatedOnVerificationWarn() throws Exception {
void violationFileWithParentDirectoryShouldBeCreatedOnVerificationWarn() {
SortPomImplUtil.create()
.verifyFail("Warn")
.violationFile(FILENAME_WITH_DIRECTORIES)
Expand Down
2 changes: 1 addition & 1 deletion sorter/src/test/java/sortpom/sort/EndWithNewlineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class EndWithNewlineTest {
@Test
void endWithNewlineFalseShouldNotOutputFinalNewline() throws Exception {
void endWithNewlineFalseShouldNotOutputFinalNewline() {
XmlProcessorTestUtil.create()
.predefinedSortOrder("default_0_4_0")
.endWithNewlineFalse()
Expand Down
2 changes: 1 addition & 1 deletion sorter/src/test/java/sortpom/sort/IgnoreSectionsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

class IgnoreSectionsTest {
@Test
void forceDependencyToTopTrickShouldWork() throws Exception {
void forceDependencyToTopTrickShouldWork() {
SortPomImplUtil.create()
.sortDependencies("scope,groupId,artifactId")
.lineSeparator("\n")
Expand Down
8 changes: 4 additions & 4 deletions sorter/src/test/java/sortpom/sort/IndentationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class IndentationTest {

@ParameterizedTest()
@ValueSource(ints = {0, 1, 4, -1})
void differentIndentsShouldWork(int indent) throws Exception {
void differentIndentsShouldWork(int indent) {
var expectedFile = "/SortModules_expectedIndent" + indent + ".xml";
SortPomImplUtil.create()
.sortProperties()
Expand All @@ -28,7 +28,7 @@ void differentIndentsShouldWork(int indent) throws Exception {

@ParameterizedTest()
@ValueSource(ints = {0, 1, 4, -1})
void indentSchemaLocationShouldBeIndentTimesTwoPlusOne(int indent) throws Exception {
void indentSchemaLocationShouldBeIndentTimesTwoPlusOne(int indent) {
var expectedFile = "/SortModules_expectedSchemaIndent" + indent + ".xml";
SortPomImplUtil.create()
.sortProperties()
Expand Down Expand Up @@ -73,7 +73,7 @@ void indentSchemaLocationShouldAddNewlineAndIndentation(int indent) {
+ lineSeparator
+ indentChars
+ indentChars
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">"
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd\">"
+ lineSeparator
+ indentChars
+ "<Gurka xmlns=\"\"></Gurka>"
Expand Down Expand Up @@ -106,7 +106,7 @@ void otherAttributeShouldNotBeIndented() {
+ lineSeparator
+ indentChars
+ indentChars
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">"
+ " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd\">"
+ lineSeparator
+ indentChars
+ "<Gurka xmlns=\"\" key=\"value\"></Gurka>"
Expand Down
Loading

0 comments on commit e79e319

Please sign in to comment.