8249867: xml declaration is not followed by a newline

Reviewed-by: rriggs, naoto, lancea, dfuchs
This commit is contained in:
Joe Wang 2021-01-30 02:34:52 +00:00
parent fb46c91027
commit 69ee314b63
5 changed files with 476 additions and 50 deletions

View File

@ -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 @@ import org.xml.sax.SAXException;
* 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 @@ abstract public class ToStream extends SerializerBase {
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;

View File

@ -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";

View File

@ -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.HttpURLConnection;
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 @@ import org.w3c.dom.ls.LSSerializerFilter;
* @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 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
// 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 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
|| 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 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
// || 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 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
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 @@ final public class LSSerializerImpl implements DOMConfiguration, LSSerializer {
} 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;

View File

@ -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
* <h2>Implementation Specific Features and Properties</h2>
*
* 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.
*
* <h3>Naming Convention</h3>
* The names of the features and properties are fully qualified, composed of a
* prefix and name.
* <p>
* <h4>Prefix</h4>
* The prefix for JDK properties is defined as:
* <pre>
* {@code http://www.oracle.com/xml/jaxp/properties/}
* </pre>
*
* The prefix for features:
* <pre>
* {@code http://www.oracle.com/xml/jaxp/features/}
* </pre>
*
* The prefix for System Properties:
* <pre>
* {@code jdk.xml.}
* </pre>
* <p>
* <h4>Name</h4>
* 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.
* <p>
* An example of a property that indicates whether an XML document is standalone
* would thus have a format:
* <pre>
* {@code http://www.oracle.com/xml/jaxp/properties/isStandalone}
* </pre>
* and a corresponding System Property:
* <pre>
* {@systemProperty jdk.xml.isStandalone}
* </pre>
*
* <h3>System Properties</h3>
* 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.
*
* <h3>jaxp.properties</h3>
* 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:
* <pre>
* {@code jdk.xml.isStandalone=true}
* </pre>
* <p>
* For details about the JAXP configuration file {@code jaxp.properties}, refer to
* {@link javax.xml.parsers.SAXParserFactory#newInstance() SAXParserFactory#newInstance}.
*
* <h3 id="ScopeAndOrder">Scope and Order</h3>
* 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 <a href="#FeaturesAndProperties">Features And Properties</a>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
* 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.
* <p>
*
* <h3 id="Processor">Processor Support</h3>
* 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.
* <p>
*
* <table class="plain" id="Processors">
* <caption>Processors</caption>
* <thead>
* <tr>
* <th scope="col">ID</th>
* <th scope="col">Name</th>
* <th scope="col">How to set the property</th>
* </tr>
* </thead>
*
* <tbody>
* <tr>
* <th scope="row" style="font-weight:normal" id="DOM">DOM</th>
* <td>DOM Parser</td>
* <td>
* {@code DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();}<br>
* {@code dbf.setAttribute(name, value);}
* </td>
* </tr>
* <tr>
* <th scope="row" style="font-weight:normal" id="SAX">SAX</th>
* <td>SAX Parser</td>
* <td>
* {@code SAXParserFactory spf = SAXParserFactory.newInstance();}<br>
* {@code SAXParser parser = spf.newSAXParser();}<br>
* {@code parser.setProperty(name, value);}
* </td>
* </tr>
* <tr>
* <th scope="row" style="font-weight:normal" id="StAX">StAX</th>
* <td>StAX Parser</td>
* <td>
* {@code XMLInputFactory xif = XMLInputFactory.newInstance();}<br>
* {@code xif.setProperty(name, value);}
* </td>
* </tr>
* <tr>
* <th scope="row" style="font-weight:normal" id="Validation">Validation</th>
* <td>XML Validation API</td>
* <td>
* {@code SchemaFactory schemaFactory = SchemaFactory.newInstance(schemaLanguage);}<br>
* {@code schemaFactory.setProperty(name, value);}
* </td>
* </tr>
* </tr>
* <tr>
* <th scope="row" style="font-weight:normal" id="Transform">Transform</th>
* <td>XML Transform API</td>
* <td>
* {@code TransformerFactory factory = TransformerFactory.newInstance();}<br>
* {@code factory.setAttribute(name, value);}
* </td>
* </tr>
* </tr>
* <tr>
* <th scope="row" style="font-weight:normal" id="DOMLS">DOMLS</th>
* <td>DOM Load and Save</td>
* <td>
* {@code LSSerializer serializer = domImplementation.createLSSerializer();} <br>
* {@code serializer.getDomConfig().setParameter(name, value);}
* </td>
* </tr>
* </tbody>
* </table>
*
* <p>
* <h3>Implementation Specific Features and Properties</h3>
* This section lists features and properties supported by the JDK implementation.
*
* <p>
* <table class="plain" id="FeaturesAndProperties">
* <caption>Features and Properties</caption>
* <thead>
* <tr>
* <th scope="col" rowspan="2">Name [1]</th>
* <th scope="col" rowspan="2">Description</th>
* <th scope="col" rowspan="2">System Property [2]</th>
* <th scope="col" rowspan="2">jaxp.properties [2]</th>
* <th scope="col" colspan="3" style="text-align:center">Value [3]</th>
* <th scope="col" rowspan="2">Security [4]</th>
* <th scope="col" rowspan="2">Supported Processor [5]</th>
* <th scope="col" rowspan="2">Since [6]</th>
* </tr>
* <tr>
* <th scope="col">Type</th>
* <th scope="col">Value</th>
* <th scope="col">Default</th>
* </tr>
* </thead>
*
* <tbody>
*
* <tr>
* <th scope="row" style="font-weight:normal" id="ISSTANDALONE">isStandalone</th>
* <td>indicates 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.
* </td>
* <td>yes</td>
* <td>yes</td>
* <td>boolean</td>
* <th id="Value" scope="row" style="font-weight:normal">true/false</th>
* <th id="Default" scope="row" style="font-weight:normal">false</th>
* <td>No</td>
* <td><a href="#DOMLS">DOMLS</a></td>
* <td>17</td>
* </tr>
* </tbody>
* </table>
* <p>
* <b>[1]</b> The name of a property. The fully-qualified name, prefix + name,
* should be used when setting the property.
* <p>
* <b>[2]</b> A value "yes" indicates there is a corresponding System Property
* for the property, "no" otherwise.
*
* <p>
* <b>[3]</b> 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.
* <p>
* <b>[4]</b> A value "yes" indicates the property is a Security Property. Refer
* to the <a href="#ScopeAndOrder">Scope and Order</a> on how secure processing
* may affect the value of a Security Property.
* <p>
* <b>[5]</b> One or more processors that support the property. The values of the
* field are IDs described in table <a href="#Processor">Processors</a>.
* <p>
* <b>[6]</b> Indicates the initial release the property is introduced.
*
*
*
* @uses javax.xml.datatype.DatatypeFactory
* @uses javax.xml.parsers.DocumentBuilderFactory
* @uses javax.xml.parsers.SAXParserFactory

View File

@ -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.IOException;
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.testng.annotations.Test;
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 @@ import org.xml.sax.SAXException;
/*
* @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 @@ import org.xml.sax.SAXException;
*/
@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
= "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<sometag/>\n";
private static final String XML_NOLB
= "<?xml version=\"1.0\" encoding=\"UTF-8\"?><sometag/>\n";
/*
* test CDATA, elements only, text and element, xml:space property, mixed
* node types.
@ -83,6 +98,82 @@ public class PrettyPrintTest {
{ "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 class PrettyPrintTest {
*
*/
@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 class PrettyPrintTest {
*
*/
@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 class PrettyPrintTest {
*
*/
@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 class PrettyPrintTest {
*
*/
@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 class PrettyPrintTest {
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 class PrettyPrintTest {
public void testLSSerializerFormatPrettyPrint() {
final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n"
+ "<hello>before child element<child><children/><children/></child>after child element</hello>";
+ "<hello>before child element<child><children/><children/></child>"
+ "after child element</hello>";
/**JDK-8035467
* no newline in default output
*/
@ -273,7 +380,8 @@ public class PrettyPrintTest {
+ "<child><children/><children/></child>"
+ "after child element</hello>";
final String XML_DOCUMENT_PRETTY_PRINT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?><hello>\n" +
final String XML_DOCUMENT_PRETTY_PRINT =
"<?xml version=\"1.0\" encoding=\"UTF-16\"?><hello>\n" +
" before child element\n" +
" <child>\n" +
" <children/>\n" +
@ -310,58 +418,73 @@ public class PrettyPrintTest {
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);
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 + "/"
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 @@ public class PrettyPrintTest {
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();
}
}