diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 8c9af748..b2889996 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -31,6 +31,10 @@
* `Input` builder now supports `java.nio.file.Path`
[#196](https://github.com/xmlunit/xmlunit/issues/196)
+* It is now possible to specify a custom `TransformerFactory` for
+ `DefaultComparisonFormatter`.
+ [#195](https://github.com/xmlunit/xmlunit/issues/195)
+
## XMLUnit for Java 2.7.0 - /Released 2020-05-12/
This version contains a backwards incompatible change to the
diff --git a/xmlunit-core/src/main/java/org/xmlunit/diff/DefaultComparisonFormatter.java b/xmlunit-core/src/main/java/org/xmlunit/diff/DefaultComparisonFormatter.java
index be31a4bd..c55710af 100644
--- a/xmlunit-core/src/main/java/org/xmlunit/diff/DefaultComparisonFormatter.java
+++ b/xmlunit-core/src/main/java/org/xmlunit/diff/DefaultComparisonFormatter.java
@@ -42,6 +42,8 @@
*/
public class DefaultComparisonFormatter implements ComparisonFormatter {
+ private TransformerFactory factory;
+
/**
* Return a short String of the Comparison including the XPath and the shorten value of the effected control and
* test Node.
@@ -81,6 +83,17 @@ public String getDescription(Comparison difference) {
controlTarget, testTarget);
}
+ /**
+ * Set the TraX factory to use.
+ *
+ * @param f the factory to use - may be null in which case the
+ * default factory will be used.
+ * @since 2.8.0
+ */
+ public void setTransformerFactory(final TransformerFactory f) {
+ factory = f;
+ }
+
/**
* May alter the display of a comparison value for {@link #getShortString} based on the comparison type.
*
@@ -453,16 +466,19 @@ protected String getFormattedNodeXml(final Node nodeToConvert, boolean formatXml
* @since XMLUnit 2.4.0
*/
protected Transformer createXmlTransformer(int numberOfBlanksToIndent) throws TransformerConfigurationException {
- TransformerFactoryConfigurer.Builder b = TransformerFactoryConfigurer.builder()
- .withExternalStylesheetLoadingDisabled()
- .withDTDLoadingDisabled();
-
- if (numberOfBlanksToIndent >= 0) {
- // not all TransformerFactories support this feature
- b = b.withSafeAttribute("indent-number", numberOfBlanksToIndent);
+ TransformerFactory fac = factory;
+ if (fac == null) {
+ TransformerFactoryConfigurer.Builder b = TransformerFactoryConfigurer.builder()
+ .withExternalStylesheetLoadingDisabled()
+ .withDTDLoadingDisabled();
+
+ if (numberOfBlanksToIndent >= 0) {
+ // not all TransformerFactories support this feature
+ b = b.withSafeAttribute("indent-number", numberOfBlanksToIndent);
+ }
+ fac = b.build().configure(TransformerFactory.newInstance());
}
- final TransformerFactory factory = b.build().configure(TransformerFactory.newInstance());
- final Transformer transformer = factory.newTransformer();
+ final Transformer transformer = fac.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
if (numberOfBlanksToIndent >= 0) {
diff --git a/xmlunit-core/src/test/java/org/xmlunit/diff/DefaultComparisonFormatterTest.java b/xmlunit-core/src/test/java/org/xmlunit/diff/DefaultComparisonFormatterTest.java
index 6dfc87e3..400f00f4 100644
--- a/xmlunit-core/src/test/java/org/xmlunit/diff/DefaultComparisonFormatterTest.java
+++ b/xmlunit-core/src/test/java/org/xmlunit/diff/DefaultComparisonFormatterTest.java
@@ -17,6 +17,8 @@
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import org.xmlunit.builder.DiffBuilder;
import org.xmlunit.builder.Input;
@@ -24,32 +26,36 @@
import org.junit.Assert;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.w3c.dom.Document;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
-
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerFactory;
public class DefaultComparisonFormatterTest {
private DefaultComparisonFormatter compFormatter = new DefaultComparisonFormatter();
+ @Mock
+ private TransformerFactory fac;
+
private static final boolean JAVA_9_PLUS, JAVA_14_PLUS;
static {
boolean j9 = false;
try {
Class.forName("java.lang.module.ModuleDescriptor");
j9 = true;
- } catch (ClassNotFoundException e) {
- } catch (Error e) {
+ } catch (ClassNotFoundException | Error e) {
}
JAVA_9_PLUS = j9;
boolean j14 = false;
try {
Class.forName("java.lang.reflect.RecordComponent");
j14 = true;
- } catch (ClassNotFoundException e) {
- } catch (Error e) {
+ } catch (ClassNotFoundException | Error e) {
}
JAVA_14_PLUS = j14;
}
@@ -639,6 +645,20 @@ public void testComparisonType_WhitespacesAndUnformattedDetails() {
assertEquals("\n \n", testDetailsUnformatted);
}
+ @Test
+ public void usesCustomTransformerFactory() throws TransformerConfigurationException {
+ Diff diff = DiffBuilder.compare("").withTest("\n \n").build();
+ Comparison firstDiff = diff.getDifferences().iterator().next().getComparison();
+
+ MockitoAnnotations.initMocks(this);
+ when(fac.newTransformer())
+ .thenReturn(TransformerFactory.newInstance().newTransformer());
+
+ compFormatter.setTransformerFactory(fac);
+ getDetails(firstDiff.getControlDetails(), firstDiff.getType());
+ verify(fac).newTransformer();
+ }
+
private DocumentBuilderFactory getDocumentBuilderFactoryWithoutValidation() throws ParserConfigurationException {
// code snippet from http://stackoverflow.com/a/155874/702345
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();