diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java index 7d775337b581c..da5500a6c5972 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -20,6 +20,7 @@ package com.sun.org.apache.xml.internal.serializer; +import com.sun.org.apache.xml.internal.serializer.dom3.DOMConstants; import com.sun.org.apache.xml.internal.serializer.utils.MsgKey; import com.sun.org.apache.xml.internal.serializer.utils.Utils; import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException; @@ -51,7 +52,7 @@ * serializers (xml, html, text ...) that write output to a stream. * * @xsl.usage internal - * @LastModified: June 2020 + * @LastModified: Jan 2021 */ abstract public class ToStream extends SerializerBase { @@ -492,8 +493,10 @@ void setProp(String name, String val, boolean defaultVal) { if (OutputPropertiesFactory.S_KEY_INDENT_AMOUNT.equals(name)) { setIndentAmount(Integer.parseInt(val)); } else if (OutputKeys.INDENT.equals(name)) { - boolean b = val.endsWith("yes") ? true : false; - m_doIndent = b; + m_doIndent = val.endsWith("yes"); + } else if ((DOMConstants.S_JDK_PROPERTIES_NS + DOMConstants.S_IS_STANDALONE) + .equals(name)) { + m_isStandalone = val.endsWith("yes"); } break; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOMConstants.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOMConstants.java index c50cdf66c8da8..b7c0d2ecef24b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOMConstants.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOMConstants.java @@ -1,6 +1,5 @@ /* - * reserved comment block - * DO NOT REMOVE OR ALTER! + * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one @@ -22,12 +21,15 @@ package com.sun.org.apache.xml.internal.serializer.dom3; +import com.sun.org.apache.xerces.internal.impl.Constants; + /** * DOM Constants used by the DOM Level 3 LSSerializer implementation. * * @xsl.usage internal + * @LastModified: Jan 2021 */ -final class DOMConstants { +public final class DOMConstants { // // Constants: DOM Level 3 feature ids // @@ -35,6 +37,8 @@ final class DOMConstants { public static final String XERCES_URL = "http://xml.apache.org/xerces-2j"; + public static final String ORACLE_URL = "http://www.oracle.com/xml"; + // The namespace used to qualified DOM Level 3 DOMConfiguration parameters public static final String S_DOM3_PROPERTIES_NS = "{" + DOMConstants.DOM3_REC_URL + "}"; @@ -42,6 +46,9 @@ final class DOMConstants { public static final String S_XERCES_PROPERTIES_NS = "{" + DOMConstants.XERCES_URL + "}"; + // The namespace used for the JDK-only parameters + public static final String S_JDK_PROPERTIES_NS = "{" + ORACLE_URL + "}"; + // xmlns namespaces private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; @@ -113,6 +120,25 @@ final class DOMConstants { // The xerces serializer specific 'omit-xml-declaration' property used in LSSerializer public static final String S_XML_VERSION = "xml-version"; + /** + * Indicates that the serializer should treat the output as a standalone document. + * The JDK specific standalone property controls whether a newline should be + * added after the XML header. + * + * @see similar property ORACLE_IS_STANDALONE in OutputPropertiesFactory. + */ + public static final String S_IS_STANDALONE = "isStandalone"; + + // Fully-qualified property name with the JDK Impl prefix + public static final String FQ_IS_STANDALONE = + Constants.ORACLE_JAXP_PROPERTY_PREFIX + S_IS_STANDALONE; + + // The property with namespace as the internal DOMConfiguration format + public static final String NS_IS_STANDALONE = S_JDK_PROPERTIES_NS + S_IS_STANDALONE; + + // Corresponding System property + public static final String SP_IS_STANDALONE = "jdk.xml.isStandalone"; + // public static final String S_XSL_VALUE_ENTITIES = "com/sun/org/apache/xml/internal/serializer/XMLEntities"; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/LSSerializerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/LSSerializerImpl.java index 66f12cc18fac1..e4928a4f06ed3 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/LSSerializerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/LSSerializerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one @@ -21,6 +21,7 @@ package com.sun.org.apache.xml.internal.serializer.dom3; +import com.sun.org.apache.xerces.internal.impl.Constants; import java.io.File; import java.io.FileOutputStream; import java.io.OutputStream; @@ -32,7 +33,7 @@ import java.net.URL; import java.net.URLConnection; import java.util.Properties; - +import jdk.xml.internal.SecuritySupport; import com.sun.org.apache.xml.internal.serializer.DOM3Serializer; import com.sun.org.apache.xml.internal.serializer.Encodings; import com.sun.org.apache.xml.internal.serializer.Serializer; @@ -67,7 +68,7 @@ * @version $Id: * * @xsl.usage internal - * @LastModified: Aug 2019 + * @LastModified: Jan 2021 */ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer { @@ -159,6 +160,10 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer { // Parameter discard-default-content, true [required] (default) private final static int XMLDECL = 0x1 << 18; + + // Parameter is-standalone, jdk specific, not required + private final static int IS_STANDALONE = 0x1 << 19; + // ************************************************************************ // Recognized parameters for which atleast one value can be set @@ -182,6 +187,7 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer { DOMConstants.DOM_FORMAT_PRETTY_PRINT, DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS, DOMConstants.DOM_XMLDECL, + DOMConstants.FQ_IS_STANDALONE, DOMConstants.DOM_ERROR_HANDLER }; @@ -351,6 +357,20 @@ public void initializeSerializerProps () { // xml-declaration fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "no"); + // JDK specific property isStandalone + String p = SecuritySupport.getSystemProperty(DOMConstants.SP_IS_STANDALONE); + if (p == null || p.isEmpty()) { + p = SecuritySupport.readJAXPProperty(DOMConstants.SP_IS_STANDALONE); + } + // the system property is true only if it is "true" and false otherwise + if (p != null && p.equals("true")) { + fFeatures |= IS_STANDALONE; + fDOMConfigProperties.setProperty(DOMConstants.NS_IS_STANDALONE, + DOMConstants.DOM3_EXPLICIT_TRUE); + } else { + fDOMConfigProperties.setProperty(DOMConstants.NS_IS_STANDALONE, + DOMConstants.DOM3_DEFAULT_FALSE); + } } // ************************************************************************ @@ -378,7 +398,8 @@ public boolean canSetParameter(String name, Object value) { || name.equalsIgnoreCase(DOMConstants.DOM_WELLFORMED) || name.equalsIgnoreCase(DOMConstants.DOM_DISCARD_DEFAULT_CONTENT) || name.equalsIgnoreCase(DOMConstants.DOM_FORMAT_PRETTY_PRINT) - || name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)){ + || name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL) + || name.equalsIgnoreCase(DOMConstants.FQ_IS_STANDALONE)){ // both values supported return true; } @@ -390,11 +411,11 @@ else if (name.equalsIgnoreCase(DOMConstants.DOM_CANONICAL_FORM) // || name.equalsIgnoreCase(DOMConstants.DOM_NORMALIZE_CHARACTERS) ) { // true is not supported - return !((Boolean)value).booleanValue(); + return !((Boolean)value); } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { // false is not supported - return ((Boolean)value).booleanValue(); + return ((Boolean)value); } } else if (name.equalsIgnoreCase(DOMConstants.DOM_ERROR_HANDLER) && @@ -436,6 +457,8 @@ public Object getParameter(String name) throws DOMException { return ((fFeatures & PRETTY_PRINT) != 0) ? Boolean.TRUE : Boolean.FALSE; } else if (name.equalsIgnoreCase(DOMConstants.DOM_XMLDECL)) { return ((fFeatures & XMLDECL) != 0) ? Boolean.TRUE : Boolean.FALSE; + } else if (name.equalsIgnoreCase(DOMConstants.FQ_IS_STANDALONE)) { + return ((fFeatures & IS_STANDALONE) != 0) ? Boolean.TRUE : Boolean.FALSE; } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) { return ((fFeatures & ELEM_CONTENT_WHITESPACE) != 0) ? Boolean.TRUE : Boolean.FALSE; } else if (name.equalsIgnoreCase(DOMConstants.DOM_IGNORE_UNKNOWN_CHARACTER_DENORMALIZATIONS)) { @@ -606,6 +629,10 @@ public void setParameter(String name, Object value) throws DOMException { } else { fDOMConfigProperties.setProperty(DOMConstants.S_XSL_OUTPUT_OMIT_XML_DECL, "yes"); } + } else if (name.equalsIgnoreCase(DOMConstants.FQ_IS_STANDALONE)) { + fFeatures = state ? fFeatures | IS_STANDALONE : fFeatures & ~IS_STANDALONE; + fDOMConfigProperties.setProperty(DOMConstants.NS_IS_STANDALONE, state ? "yes" : "no"); + } else if (name.equalsIgnoreCase(DOMConstants.DOM_ELEMENT_CONTENT_WHITESPACE)) { fFeatures = state ? fFeatures | ELEM_CONTENT_WHITESPACE : fFeatures & ~ELEM_CONTENT_WHITESPACE; diff --git a/src/java.xml/share/classes/module-info.java b/src/java.xml/share/classes/module-info.java index 53f166f8a82e3..cb0eaedb3fad9 100644 --- a/src/java.xml/share/classes/module-info.java +++ b/src/java.xml/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,236 @@ * Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX), * the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API. * + * @implNote + *

Implementation Specific Features and Properties

+ * + * In addition to the standard features and properties described within the public + * APIs of this module, the JDK implementation supports a further number of + * implementation specific features and properties. This section describes the + * naming convention, System Properties, jaxp.properties, scope and order, + * and processors to which a property applies. A table listing the implementation + * specific features and properties which the implementation currently supports + * can be found at the end of this note. + * + *

Naming Convention

+ * The names of the features and properties are fully qualified, composed of a + * prefix and name. + *

+ *

Prefix

+ * The prefix for JDK properties is defined as: + *
+ *     {@code http://www.oracle.com/xml/jaxp/properties/}
+ * 
+ * + * The prefix for features: + *
+ *     {@code http://www.oracle.com/xml/jaxp/features/}
+ * 
+ * + * The prefix for System Properties: + *
+ *     {@code jdk.xml.}
+ * 
+ *

+ *

Name

+ * A name may consist of one or multiple words that are case-sensitive. + * All letters of the first word are in lowercase, while the first letter of + * each subsequent word is capitalized. + *

+ * An example of a property that indicates whether an XML document is standalone + * would thus have a format: + *

+ *     {@code http://www.oracle.com/xml/jaxp/properties/isStandalone}
+ * 
+ * and a corresponding System Property: + *
+ *     {@systemProperty jdk.xml.isStandalone}
+ * 
+ * + *

System Properties

+ * A property may have a corresponding System Property that has the same name + * except for the prefix as shown above. A System Property should be set prior + * to the creation of a processor and may be cleared afterwards. + * + *

jaxp.properties

+ * A system property can be specified in the {@code jaxp.properties} file to + * set the behavior for all invocations of the JDK. The format is + * {@code system-property-name=value}. For example: + *
+ *     {@code jdk.xml.isStandalone=true}
+ * 
+ *

+ * For details about the JAXP configuration file {@code jaxp.properties}, refer to + * {@link javax.xml.parsers.SAXParserFactory#newInstance() SAXParserFactory#newInstance}. + * + *

Scope and Order

+ * The {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature + * (hereafter referred to as secure processing) is required for XML processors + * including DOM, SAX, Schema Validation, XSLT, and XPath. Any properties flagged + * as {@code "security: yes"} (hereafter referred to as security properties) in + * table Features And Properties + * are enforced when secure processing is set to true. Such enforcement includes + * setting security features to true and limits to the defined values shown in + * the table. The property values will not be affected, however, when setting + * secure processing to false. + *

+ * When the Java Security Manager is present, secure processing is set to true + * and can not be turned off. The security properties are therefore enforced. + *

+ * Properties specified in the jaxp.properties file affect all invocations of + * the JDK, and will override their default values, or those that may have been + * set by secure processing. + *

+ * System properties, when set, affect the invocation of the JDK and override + * the default settings or those that may have been set in jaxp.properties or + * by secure processing. + *

+ * JAXP properties specified through JAXP factories or processors (e.g. SAXParser) + * take preference over system properties, the jaxp.properties file, as well as + * secure processing. + *

+ * + *

Processor Support

+ * Features and properties may be supported by one or more processors. The + * following table lists the processors by IDs that can be used for reference. + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Processors
IDNameHow to set the property
DOMDOM Parser + * {@code DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();}
+ * {@code dbf.setAttribute(name, value);} + *
SAXSAX Parser + * {@code SAXParserFactory spf = SAXParserFactory.newInstance();}
+ * {@code SAXParser parser = spf.newSAXParser();}
+ * {@code parser.setProperty(name, value);} + *
StAXStAX Parser + * {@code XMLInputFactory xif = XMLInputFactory.newInstance();}
+ * {@code xif.setProperty(name, value);} + *
ValidationXML Validation API + * {@code SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);}
+ * {@code schemaFactory.setProperty(name, value);} + *
TransformXML Transform API + * {@code TransformerFactory factory = TransformerFactory.newInstance();}
+ * {@code factory.setAttribute(name, value);} + *
DOMLSDOM Load and Save + * {@code LSSerializer serializer = domImplementation.createLSSerializer();}
+ * {@code serializer.getDomConfig().setParameter(name, value);} + *
+ * + *

+ *

Implementation Specific Features and Properties

+ * This section lists features and properties supported by the JDK implementation. + * + *

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Features and Properties
Name [1]DescriptionSystem Property [2]jaxp.properties [2]Value [3]Security [4]Supported Processor [5]Since [6]
TypeValueDefault
isStandaloneindicates that the serializer should treat the output as a + * standalone document. The property can be used to ensure a newline is written + * after the XML declaration when the property + * {@link org.w3c.dom.ls.LSSerializer#getDomConfig() format-pretty-print} is set + * to true. Unlike the property + * {@link org.w3c.dom.ls.LSSerializer#getDomConfig() xml-declaration}, this property + * does not have an effect on whether an XML declaration should be written out. + * yesyesbooleantrue/falsefalseNoDOMLS17
+ *

+ * [1] The name of a property. The fully-qualified name, prefix + name, + * should be used when setting the property. + *

+ * [2] A value "yes" indicates there is a corresponding System Property + * for the property, "no" otherwise. + * + *

+ * [3] The value must be exactly as listed in this table, case-sensitive. + * The value type for the corresponding System Property is String. For boolean + * type, the system property is true only if it is "true" and false otherwise. + *

+ * [4] A value "yes" indicates the property is a Security Property. Refer + * to the Scope and Order on how secure processing + * may affect the value of a Security Property. + *

+ * [5] One or more processors that support the property. The values of the + * field are IDs described in table Processors. + *

+ * [6] Indicates the initial release the property is introduced. + * + * + * * @uses javax.xml.datatype.DatatypeFactory * @uses javax.xml.parsers.DocumentBuilderFactory * @uses javax.xml.parsers.SAXParserFactory diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java index 0d652f286f39a..c3e1a68c05944 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,9 @@ package common.prettyprint; +import static jaxp.library.JAXPTestUtilities.clearSystemProperty; +import static jaxp.library.JAXPTestUtilities.setSystemProperty; + import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -30,6 +33,8 @@ import java.io.InputStream; import java.io.StringReader; import java.io.StringWriter; +import java.nio.file.Files; +import java.nio.file.Paths; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -48,6 +53,7 @@ import org.w3c.dom.DOMConfiguration; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; +import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.Text; import org.w3c.dom.bootstrap.DOMImplementationRegistry; @@ -60,7 +66,7 @@ /* * @test - * @bug 6439439 8087303 8174025 8223291 + * @bug 6439439 8087303 8174025 8223291 8249867 * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @run testng/othervm -DrunSecMngr=true common.prettyprint.PrettyPrintTest * @run testng/othervm common.prettyprint.PrettyPrintTest @@ -68,6 +74,15 @@ */ @Listeners({jaxp.library.FilePolicy.class}) public class PrettyPrintTest { + private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print"; + private static final String JDK_IS_STANDALONE = + "http://www.oracle.com/xml/jaxp/properties/isStandalone"; + private static final String SP_JDK_IS_STANDALONE = "jdk.xml.isStandalone"; + private static final String XML_LB + = "\n\n"; + private static final String XML_NOLB + = "\n"; + /* * test CDATA, elements only, text and element, xml:space property, mixed * node types. @@ -83,6 +98,82 @@ public Object[][] xmlData() throws Exception { { "xmltest8.xml", "xmltest8.out" } }; } + /* + * Bug: 8249867 + * DataProvider: for testing the isStandalone property + * Data columns: property, system property, value, expected result + */ + @DataProvider(name = "setting") + Object[][] getData() throws Exception { + return new Object[][]{ + {false, true, true, XML_LB}, //set System property + {false, true, false, XML_NOLB},//set System property + {true, false, true, XML_LB}, //set property + {true, false, false, XML_NOLB},//set property + {false, false, false, XML_NOLB} //default + }; + } + + /* + * Bug: 8249867 + * DataProvider: for verifying the System property + * Data columns: value for system property, expected result + */ + @DataProvider(name = "SP") + Object[][] getSystemProperty() throws Exception { + return new Object[][]{ + // the system property is true only if it is "true" and false otherwise + {"true", true}, + {"false", false}, + {"yes", false}, + {"", false}, + }; + } + + /* + * Bug: 8249867 + * Verifies the use of the new property "isStandalone" and the + * corresponding System property "jdk.xml.isStandalone". + */ + @Test(dataProvider = "setting") + public void test(boolean p, boolean sp, boolean val, String expected) + throws Exception { + if (sp) { + setSystemProperty(SP_JDK_IS_STANDALONE, Boolean.toString(val)); + } + Document document = getDocument(); + DOMImplementationLS impl = (DOMImplementationLS)document.getImplementation(); + LSSerializer ser = impl.createLSSerializer(); + ser.getDomConfig().setParameter("format-pretty-print", true); + if (p && !sp) { + ser.getDomConfig().setParameter(JDK_IS_STANDALONE, val); + } + if (sp) { + clearSystemProperty(SP_JDK_IS_STANDALONE); + } + final StringWriter writer = new StringWriter(); + final LSOutput output = impl.createLSOutput(); + output.setCharacterStream(writer); + ser.write(document, output); + String result = writer.toString(); + + Assert.assertEquals(result, expected); + } + + /* + * Bug: 8249867 + * Verifies the definition of the System property "jdk.xml.isStandalone". + * The system property is true only if it is "true" and false otherwise. + */ + @Test(dataProvider = "SP") + public void testSP(String value, boolean expected) throws Exception { + setSystemProperty(SP_JDK_IS_STANDALONE, value); + DOMConfiguration c = getConfig(); + clearSystemProperty(SP_JDK_IS_STANDALONE); + + Assert.assertEquals(c.getParameter(JDK_IS_STANDALONE), expected); + } + /* * @bug 8087303 * Test the xml document are serialized with pretty-print by @@ -90,19 +181,23 @@ public Object[][] xmlData() throws Exception { * */ @Test(dataProvider = "xml-data") - public void testXMLPrettyPrint(String sourceFile, String expectedFile) throws Exception { + public void testXMLPrettyPrint(String sourceFile, String expectedFile) + throws Exception { String source = read(sourceFile); String expected = read(expectedFile); // test it's no change if no pretty-print String result = serializerWrite(toXmlDocument(source), false); - assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), "The actual is: " + result); + assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), + "The actual is: " + result); // test pretty-print assertEquals(serializerWrite(toXmlDocument(source), true), expected); // test it's no change if no pretty-print result = transform(toXmlDocument(source), false); - assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), "The actual is: " + result); + assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), + "The actual is: " + result); // test pretty-print - assertEquals(transform(toXmlDocument(source), true).replaceAll("\r\n", "\n"), expected); + assertEquals(transform(toXmlDocument(source), true).replaceAll("\r\n", "\n"), + expected); } @@ -164,12 +259,14 @@ public Object[][] whitespaceLS() throws Exception { * */ @Test(dataProvider = "xml-data-whitespace-ls") - public void testWhitespaceWithLSSerializer(String sourceFile, String expectedFile) throws Exception { + public void testWhitespaceWithLSSerializer(String sourceFile, String expectedFile) + throws Exception { String source = read(sourceFile); String expected = read(expectedFile); // test it's no change if no pretty-print String result = serializerWrite(toXmlDocument(source), false); - assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), "The actual is: " + result); + assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), + "The actual is: " + result); // test pretty-print assertEquals(serializerWrite(toXmlDocument(source), true), expected); } @@ -191,14 +288,17 @@ public Object[][] whitespaceXSLT() throws Exception { * */ @Test(dataProvider = "xml-data-whitespace-xslt") - public void testWhitespaceWithTransformer(String sourceFile, String expectedFile) throws Exception { + public void testWhitespaceWithTransformer(String sourceFile, String expectedFile) + throws Exception { String source = read(sourceFile); String expected = read(expectedFile); // test it's no change if no pretty-print String result = transform(toXmlDocument(source), false); - assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), "The actual is: " + result); + assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(result)), + "The actual is: " + result); // test pretty-print - assertEquals(transform(toXmlDocument(source), true).replaceAll("\r\n", "\n"), expected); + assertEquals(transform(toXmlDocument(source), true).replaceAll("\r\n", "\n"), + expected); } /* @@ -223,17 +323,21 @@ public Object[][] htmlData() throws Exception { * */ @Test(dataProvider = "html-data") - public void testTransformToHTML(String sourceFile, String expectedFile) throws Exception { + public void testTransformToHTML(String sourceFile, String expectedFile) + throws Exception { String source = read(sourceFile); String expected = read(expectedFile); // test it's no change if no pretty-print StringWriter writer = new StringWriter(); - getTransformer(true, false).transform(new StreamSource(new StringReader(source)), new StreamResult(writer)); - assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(writer.toString())), "The actual is: " + writer.toString()); + getTransformer(true, false).transform( + new StreamSource(new StringReader(source)), new StreamResult(writer)); + assertTrue(toXmlDocument(source).isEqualNode(toXmlDocument(writer.toString())), + "The actual is: " + writer.toString()); // test pretty-print writer = new StringWriter(); - getTransformer(true, true).transform(new StreamSource(new StringReader(source)), new StreamResult(writer)); + getTransformer(true, true).transform( + new StreamSource(new StringReader(source)), new StreamResult(writer)); assertEquals(writer.toString().replaceAll("\r\n", "\n"), expected); } @@ -248,13 +352,15 @@ public void testDisableOutputEscaping() throws Exception { final String xml ="simple-entity-resolver-config.xml"; final String expectedOutput ="simple-entity-resolver-config-transformed.xml"; TransformerFactory factory = TransformerFactory.newInstance(); - Transformer transformer = factory.newTemplates(new StreamSource(new StringReader(read(xsl)))).newTransformer(); + Transformer transformer = factory.newTemplates( + new StreamSource(new StringReader(read(xsl)))).newTransformer(); String key = "schemaBase"; String value = "schemas"; transformer.setParameter(key, value); StringWriter writer = new StringWriter(); - transformer.transform(new StreamSource(new StringReader(read(xml))), new StreamResult(writer)); + transformer.transform(new StreamSource(new StringReader(read(xml))), + new StreamResult(writer)); assertEquals(writer.toString().replaceAll("\r\n", "\n"), read(expectedOutput)); } @@ -262,7 +368,8 @@ public void testDisableOutputEscaping() throws Exception { public void testLSSerializerFormatPrettyPrint() { final String XML_DOCUMENT = "\n" - + "before child elementafter child element"; + + "before child element" + + "after child element"; /**JDK-8035467 * no newline in default output */ @@ -273,7 +380,8 @@ public void testLSSerializerFormatPrettyPrint() { + "" + "after child element"; - final String XML_DOCUMENT_PRETTY_PRINT = "\n" + + final String XML_DOCUMENT_PRETTY_PRINT = + "\n" + " before child element\n" + " \n" + " \n" + @@ -310,58 +418,73 @@ public void testLSSerializerFormatPrettyPrint() { DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation; LSSerializer lsSerializer = domImplementationLS.createLSSerializer(); - System.out.println("Serializer is: " + lsSerializer.getClass().getName() + " " + lsSerializer); + System.out.println("Serializer is: " + lsSerializer.getClass().getName() + + " " + lsSerializer); // get configuration DOMConfiguration domConfiguration = lsSerializer.getDomConfig(); // query current configuration - Boolean defaultFormatPrettyPrint = (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT); - Boolean canSetFormatPrettyPrintFalse = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE); - Boolean canSetFormatPrettyPrintTrue = (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE); - - System.out.println(DOM_FORMAT_PRETTY_PRINT + " default/can set false/can set true = " + defaultFormatPrettyPrint + "/" + Boolean defaultFormatPrettyPrint = + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT); + Boolean canSetFormatPrettyPrintFalse = + (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE); + Boolean canSetFormatPrettyPrintTrue = + (Boolean) domConfiguration.canSetParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE); + + System.out.println(DOM_FORMAT_PRETTY_PRINT + " default/can set false/can set true = " + + defaultFormatPrettyPrint + "/" + canSetFormatPrettyPrintFalse + "/" + canSetFormatPrettyPrintTrue); // test values - assertEquals(defaultFormatPrettyPrint, Boolean.FALSE, "Default value of " + DOM_FORMAT_PRETTY_PRINT + " should be " + Boolean.FALSE); + assertEquals(defaultFormatPrettyPrint, Boolean.FALSE, + "Default value of " + DOM_FORMAT_PRETTY_PRINT + " should be " + Boolean.FALSE); - assertEquals(canSetFormatPrettyPrintFalse, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.FALSE + " should be " + assertEquals(canSetFormatPrettyPrintFalse, Boolean.TRUE, + "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.FALSE + " should be " + Boolean.TRUE); - assertEquals(canSetFormatPrettyPrintTrue, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.TRUE + " should be " + assertEquals(canSetFormatPrettyPrintTrue, Boolean.TRUE, + "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.TRUE + " should be " + Boolean.TRUE); // get default serialization String prettyPrintDefault = lsSerializer.writeToString(document); - System.out.println("(default) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT) + System.out.println("(default) " + DOM_FORMAT_PRETTY_PRINT + "==" + + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT) + ": \n\"" + prettyPrintDefault + "\""); - assertEquals(prettyPrintDefault, XML_DOCUMENT_DEFAULT_PRINT, "Invalid serialization with default value, " + DOM_FORMAT_PRETTY_PRINT + "==" + assertEquals(prettyPrintDefault, XML_DOCUMENT_DEFAULT_PRINT, + "Invalid serialization with default value, " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)); // configure LSSerializer to not format-pretty-print domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.FALSE); String prettyPrintFalse = lsSerializer.writeToString(document); - System.out.println("(FALSE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT) + System.out.println("(FALSE) " + DOM_FORMAT_PRETTY_PRINT + "==" + + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT) + ": \n\"" + prettyPrintFalse + "\""); - assertEquals(prettyPrintFalse, XML_DOCUMENT_DEFAULT_PRINT, "Invalid serialization with FALSE value, " + DOM_FORMAT_PRETTY_PRINT + "==" + assertEquals(prettyPrintFalse, XML_DOCUMENT_DEFAULT_PRINT, + "Invalid serialization with FALSE value, " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)); // configure LSSerializer to format-pretty-print domConfiguration.setParameter(DOM_FORMAT_PRETTY_PRINT, Boolean.TRUE); String prettyPrintTrue = lsSerializer.writeToString(document); - System.out.println("(TRUE) " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT) + System.out.println("(TRUE) " + DOM_FORMAT_PRETTY_PRINT + "==" + + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT) + ": \n\"" + prettyPrintTrue + "\""); - assertEquals(prettyPrintTrue, XML_DOCUMENT_PRETTY_PRINT, "Invalid serialization with TRUE value, " + DOM_FORMAT_PRETTY_PRINT + "==" + assertEquals(prettyPrintTrue, XML_DOCUMENT_PRETTY_PRINT, + "Invalid serialization with TRUE value, " + DOM_FORMAT_PRETTY_PRINT + "==" + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT)); } private String serializerWrite(Node xml, boolean pretty) throws Exception { DOMImplementationRegistry registry = DOMImplementationRegistry.newInstance(); - DOMImplementationLS domImplementation = (DOMImplementationLS) registry.getDOMImplementation("LS"); + DOMImplementationLS domImplementation = + (DOMImplementationLS) registry.getDOMImplementation("LS"); StringWriter writer = new StringWriter(); LSOutput formattedOutput = domImplementation.createLSOutput(); formattedOutput.setCharacterStream(writer); @@ -457,12 +580,29 @@ private Transformer getTransformer(boolean html, boolean pretty) throws Exceptio return transformer; } - private String read(String filename) throws Exception { try (InputStream in = PrettyPrintTest.class.getResourceAsStream(filename)) { return new String(in.readAllBytes()); } } - private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print"; + private Document getDocument() throws Exception { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + + Element child = document.createElement("sometag"); + document.appendChild(child); + return document; + } + + private DOMImplementationLS getImpl() throws Exception { + Document document = getDocument(); + return (DOMImplementationLS)document.getImplementation(); + } + + private DOMConfiguration getConfig() throws Exception { + LSSerializer ser = getImpl().createLSSerializer(); + return ser.getDomConfig(); + } }