8087303: LSSerializer pretty print does not work anymore
8114834: LSSerializerImpl always serializes an entity reference node to" &entityName;" even if "entities" property is false
Reviewed-by: joehw, clanger
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java Mon Dec 19 11:13:32 2016 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: AbstractTranslet.java,v 1.6 2006/06/19 19:49:03 spericas Exp $
- */
package com.sun.org.apache.xalan.internal.xsltc.runtime;
@@ -685,7 +682,8 @@
handler.setVersion(_version);
}
handler.setIndent(_indent);
- handler.setIndentAmount(_indentamount);
+ if (_indentamount >= 0)
+ handler.setIndentAmount(_indentamount);
if (_doctypeSystem != null) {
handler.setDoctype(_doctypeSystem, _doctypePublic);
}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Mon Dec 19 11:13:32 2016 +0800
@@ -17,9 +17,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: TransformerImpl.java,v 1.10 2007/06/13 01:57:09 joehw Exp $
- */
package com.sun.org.apache.xalan.internal.xsltc.trax;
@@ -160,7 +157,7 @@
/**
* Number of indent spaces to add when indentation is on.
*/
- private int _indentNumber;
+ private int _indentNumber = -1;
/**
* A reference to the transformer factory that this templates
@@ -1462,7 +1459,7 @@
_uriResolver = null;
_dom = null;
_parameters = null;
- _indentNumber = 0;
+ _indentNumber = -1;
setOutputProperties (null);
_tohFactory = null;
_ostream = null;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/SerializerBase.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/SerializerBase.java Mon Dec 19 11:13:32 2016 +0800
@@ -93,9 +93,11 @@
protected AttributesImplSerializer m_attributes = new AttributesImplSerializer();
/**
- * Tells if we're in an EntityRef event.
+ * Tells if we're in an EntityRef event, true if it's greater than 0. Use
+ * integer type to handle nested entity reference, increase m_inEntityRef in
+ * startEntity, decrease m_inEntityRef in endEntity.
*/
- protected boolean m_inEntityRef = false;
+ protected int m_inEntityRef = 0;
/** This flag is set while receiving events from the external DTD */
protected boolean m_inExternalDTD = false;
@@ -144,7 +146,7 @@
/**
* Amount to indent.
*/
- protected int m_indentAmount = 0;
+ protected int m_indentAmount = 4;
/**
* Tells the XML version, for writing out to the XML decl.
@@ -444,13 +446,24 @@
public void endEntity(String name) throws org.xml.sax.SAXException {
if (name.equals("[dtd]"))
m_inExternalDTD = false;
- m_inEntityRef = false;
+
+ if (!m_inExternalDTD)
+ m_inEntityRef--;
if (m_tracer != null)
this.fireEndEntity(name);
}
/**
+ * This method checks if current node is in entity reference.
+ *
+ * @return True if current node is in entity reference.
+ */
+ protected boolean isInEntityRef() {
+ return m_inEntityRef > 0;
+ }
+
+ /**
* Flush and close the underlying java.io.Writer. This method applies to
* ToStream serializers, not ToSAXHandler serializers.
* @see ToStream
@@ -1139,8 +1152,8 @@
this.m_doctypePublic = null;
this.m_doctypeSystem = null;
this.m_doIndent = false;
- this.m_indentAmount = 0;
- this.m_inEntityRef = false;
+ this.m_indentAmount = 4;
+ this.m_inEntityRef = 0;
this.m_inExternalDTD = false;
this.m_mediatype = null;
this.m_needToCallStartDocument = true;
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,15 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,22 +17,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: ToHTMLStream.java,v 1.2.4.1 2005/09/15 08:15:26 suresh_emailid Exp $
- */
+
package com.sun.org.apache.xml.internal.serializer;
import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
import java.util.Properties;
import javax.xml.transform.Result;
+import org.xml.sax.Attributes;
+import org.xml.sax.SAXException;
+
import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
import com.sun.org.apache.xml.internal.serializer.utils.Utils;
-import org.xml.sax.Attributes;
-import org.xml.sax.SAXException;
/**
* This serializer takes a series of SAX or
@@ -52,9 +47,8 @@
/** This flag is set while receiving events from the DTD */
protected boolean m_inDTD = false;
- /** True if the current element is a block element. (seems like
- * this needs to be a stack. -sb). */
- private boolean m_inBlockElem = false;
+ /** True if the previous element is a block element. */
+ private boolean m_isprevblock = false;
/**
* Map that tells which XML characters should have special treatment, and it
@@ -723,7 +717,7 @@
*/
public final void endDocument() throws org.xml.sax.SAXException
{
-
+ flushCharactersBuffer();
flushPending();
if (m_doIndent && !m_isprevtext)
{
@@ -743,26 +737,48 @@
}
/**
- * Receive notification of the beginning of an element.
+ * If the previous is an inline element, won't insert a new line before the
+ * text.
+ *
+ */
+ protected boolean shouldIndentForText() {
+ return super.shouldIndentForText() && m_isprevblock;
+ }
+
+ /**
+ * Only check m_doIndent, disregard m_ispreserveSpace.
+ *
+ * @return True if the content should be formatted.
+ */
+ protected boolean shouldFormatOutput() {
+ return m_doIndent;
+ }
+
+ /**
+ * Receive notification of the beginning of an element.
*
*
- * @param namespaceURI
- * @param localName
- * @param name The element type name.
- * @param atts The attributes attached to the element, if any.
- * @throws org.xml.sax.SAXException Any SAX exception, possibly
- * wrapping another exception.
- * @see #endElement
- * @see org.xml.sax.AttributeList
+ * @param namespaceURI
+ * @param localName
+ * @param name
+ * The element type name.
+ * @param atts
+ * The attributes attached to the element, if any.
+ * @throws org.xml.sax.SAXException
+ * Any SAX exception, possibly wrapping another exception.
+ * @see #endElement
+ * @see org.xml.sax.AttributeList
*/
public void startElement(
String namespaceURI,
String localName,
String name,
Attributes atts)
- throws org.xml.sax.SAXException
+ throws SAXException
{
-
+ // will add extra one if having namespace but no matter
+ m_childNodeNum++;
+ flushCharactersBuffer();
ElemContext elemContext = m_elemContext;
// clean up any pending things first
@@ -800,22 +816,18 @@
// deal with indentation issues first
if (m_doIndent)
{
-
boolean isBlockElement = (elemFlags & ElemDesc.BLOCK) != 0;
- if (m_ispreserve)
- m_ispreserve = false;
- else if (
- (null != elemContext.m_elementName)
- && (!m_inBlockElem
- || isBlockElement) /* && !isWhiteSpaceSensitive */
- )
+ if ((elemContext.m_elementName != null)
+ // If this element is a block element,
+ // or if this is not a block element, then if the
+ // previous is neither a text nor an inline
+ && (isBlockElement || (!(m_isprevtext || !m_isprevblock))))
{
m_startNewLine = true;
indent();
-
}
- m_inBlockElem = !isBlockElement;
+ m_isprevblock = isBlockElement;
}
// save any attributes for later processing
@@ -827,7 +839,8 @@
writer.write('<');
writer.write(name);
-
+ m_childNodeNumStack.push(m_childNodeNum);
+ m_childNodeNum = 0;
if (m_tracer != null)
firePseudoAttributes();
@@ -850,6 +863,15 @@
m_elemContext = elemContext;
elemContext.m_elementDesc = elemDesc;
elemContext.m_isRaw = (elemFlags & ElemDesc.RAW) != 0;
+
+ // set m_startNewLine for the next element
+ if (m_doIndent) {
+ // elemFlags is equivalent to m_elemContext.m_elementDesc.getFlags(),
+ // in this branch m_elemContext.m_elementName is not null
+ boolean isBlockElement = (elemFlags & ElemDesc.BLOCK) != 0;
+ if (isBlockElement)
+ m_startNewLine = true;
+ }
}
@@ -893,6 +915,7 @@
final String name)
throws org.xml.sax.SAXException
{
+ flushCharactersBuffer();
// deal with any pending issues
if (m_cdataTagOpen)
closeCDATA();
@@ -919,18 +942,18 @@
final boolean isBlockElement = (elemFlags&ElemDesc.BLOCK) != 0;
boolean shouldIndent = false;
- if (m_ispreserve)
- {
- m_ispreserve = false;
- }
- else if (m_doIndent && (!m_inBlockElem || isBlockElement))
+ // If this element is a block element,
+ // or if this is not a block element, then if the previous is
+ // neither a text nor an inline
+ if (isBlockElement || (!(m_isprevtext || !m_isprevblock)))
{
m_startNewLine = true;
shouldIndent = true;
}
- if (!elemContext.m_startTagOpen && shouldIndent)
+ if (!elemContext.m_startTagOpen && shouldIndent && (m_childNodeNum > 1 || !m_isprevtext))
indent(elemContext.m_currentElemDepth - 1);
- m_inBlockElem = !isBlockElement;
+
+ m_isprevblock = isBlockElement;
}
final java.io.Writer writer = m_writer;
@@ -974,6 +997,7 @@
}
}
+ m_childNodeNum = m_childNodeNumStack.pop();
// clean up because the element has ended
if ((elemFlags & ElemDesc.WHITESPACESENSITIVE) != 0)
m_ispreserve = true;
@@ -1511,7 +1535,7 @@
// writer.write("<![CDATA[");
// writer.write(chars, start, length);
writeNormalizedChars(chars, start, length, false, m_lineSepUse);
-
+ m_isprevtext = true;
// writer.write("]]>");
// time to generate characters event
@@ -1566,7 +1590,6 @@
public final void cdata(char ch[], int start, int length)
throws org.xml.sax.SAXException
{
-
if ((null != m_elemContext.m_elementName)
&& (m_elemContext.m_elementName.equalsIgnoreCase("SCRIPT")
|| m_elemContext.m_elementName.equalsIgnoreCase("STYLE")))
@@ -1617,7 +1640,8 @@
public void processingInstruction(String target, String data)
throws org.xml.sax.SAXException
{
-
+ m_childNodeNum++;
+ flushCharactersBuffer();
// Process any pending starDocument and startElement first.
flushPending();
@@ -1945,10 +1969,8 @@
private void initToHTMLStream()
{
-// m_elementDesc = null;
- m_inBlockElem = false;
+ m_isprevblock = false;
m_inDTD = false;
-// m_isRawStack.clear();
m_omitMetaTag = false;
m_specialEscapeURLs = true;
}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Mon Dec 19 11:13:32 2016 +0800
@@ -29,12 +29,16 @@
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Deque;
+import java.util.EmptyStackException;
import java.util.Enumeration;
-import java.util.Iterator;
import java.util.Properties;
+import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
-import java.util.ArrayList;
import javax.xml.transform.ErrorListener;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
@@ -89,6 +93,29 @@
Object m_charToByteConverter = null;
/**
+ * Used to buffer the text nodes and the entity reference nodes if
+ * indentation is on.
+ */
+ protected CharacterBuffer m_charactersBuffer = new CharacterBuffer();
+
+ /**
+ * Used to decide if a text node is pretty-printed with indentation.
+ * If m_childNodeNum > 1, the text node will be indented.
+ *
+ */
+ protected Deque<Integer> m_childNodeNumStack = new ArrayDeque<>();
+
+ protected int m_childNodeNum = 0;
+
+ /**
+ * Used to handle xml:space attribute
+ *
+ */
+ protected BoolStack m_preserveSpaces = new BoolStack();
+
+ protected boolean m_ispreserveSpace = false;
+
+ /**
* Stack to keep track of whether or not we need to
* preserve whitespace.
*
@@ -767,12 +794,10 @@
if (m_startNewLine)
outputLineSep();
- /* For m_indentAmount > 0 this extra test might be slower
- * but Xalan's default value is 0, so this extra test
- * will run faster in that situation.
+ /*
+ * Default value is 4, so printSpace directly.
*/
- if (m_indentAmount > 0)
- printSpace(depth * m_indentAmount);
+ printSpace(depth * m_indentAmount);
}
@@ -1234,7 +1259,6 @@
protected void cdata(char ch[], int start, final int length)
throws org.xml.sax.SAXException
{
-
try
{
final int old_start = start;
@@ -1323,7 +1347,7 @@
throws org.xml.sax.SAXException
{
- if (m_inEntityRef)
+ if (isInEntityRef())
return;
try
{
@@ -1378,9 +1402,11 @@
// characters to read from array is 0.
// Section 7.6.1 of XSLT 1.0 (http://www.w3.org/TR/xslt#value-of) suggest no text node
// is created if string is empty.
- if (length == 0 || (m_inEntityRef && !m_expandDTDEntities))
+ if (length == 0 || (isInEntityRef()))
return;
- if (m_elemContext.m_startTagOpen)
+
+ final boolean shouldFormat = shouldFormatOutput();
+ if (m_elemContext.m_startTagOpen && !shouldFormat)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
@@ -1407,7 +1433,7 @@
if (m_disableOutputEscapingStates.peekOrFalse() || (!m_escaping))
{
charactersRaw(chars, start, length);
-
+ m_isprevtext = true;
// time to fire off characters generation event
if (m_tracer != null)
super.fireCharEvent(chars, start, length);
@@ -1415,13 +1441,41 @@
return;
}
- if (m_elemContext.m_startTagOpen)
+ if (m_elemContext.m_startTagOpen && !shouldFormat)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
-
+ if (shouldFormat) {
+ m_charactersBuffer.addText(chars, start, length);
+ } else {
+ outputCharacters(chars, start, length);
+ }
+
+ // time to fire off characters generation event
+ if (m_tracer != null)
+ super.fireCharEvent(chars, start, length);
+ }
+
+
+ /**
+ * This method checks if the content in current element should be formatted.
+ *
+ * @return True if the content should be formatted.
+ */
+ protected boolean shouldFormatOutput() {
+ return !m_ispreserveSpace && m_doIndent;
+ }
+
+ /**
+ * Write out the characters.
+ *
+ * @param chars The characters of the text.
+ * @param start The start position in the char array.
+ * @param length The number of characters from the char array.
+ */
+ private void outputCharacters(final char chars[], final int start, final int length) throws SAXException {
try
{
int i;
@@ -1459,8 +1513,8 @@
m_ispreserve = true;
-// int lengthClean; // number of clean characters in a row
-// final boolean[] isAsciiClean = m_charInfo.getASCIIClean();
+// int lengthClean; // number of clean characters in a row
+// final boolean[] isAsciiClean = m_charInfo.getASCIIClean();
final boolean isXML10 = XMLVERSION10.equals(getVersion());
// we've skipped the leading whitespace, now deal with the rest
@@ -1514,11 +1568,54 @@
{
throw new SAXException(e);
}
-
- // time to fire off characters generation event
- if (m_tracer != null)
- super.fireCharEvent(chars, start, length);
}
+
+ /**
+ * Used to flush the buffered characters when indentation is on, this method
+ * will be called when the next node is traversed.
+ *
+ */
+ final protected void flushCharactersBuffer() throws SAXException {
+ try {
+ if (shouldFormatOutput() && m_charactersBuffer.hasContent()) {
+ if (m_elemContext.m_startTagOpen) {
+ closeStartTag();
+ m_elemContext.m_startTagOpen = false;
+ }
+
+ if (m_elemContext.m_isCdataSection) {
+ /*
+ * due to cdata-section-elements atribute, we need this as
+ * cdata
+ */
+ char[] chars = m_charactersBuffer.toChars();
+ cdata(chars, 0, chars.length);
+ return;
+ }
+
+ m_childNodeNum++;
+ if (shouldIndentForText()) {
+ indent();
+ m_startNewLine = true;
+ }
+ m_charactersBuffer.flush();
+ }
+ } catch (IOException e) {
+ throw new SAXException(e);
+ } finally {
+ m_charactersBuffer.clear();
+ }
+ }
+
+ /**
+ * True if should indent in flushCharactersBuffer method.
+ * This method may be overridden in sub-class.
+ *
+ */
+ protected boolean shouldIndentForText() {
+ return (shouldIndent() && m_childNodeNum > 1);
+ }
+
/**
* This method checks if a given character is between C0 or C1 range
* of Control characters.
@@ -1610,7 +1707,7 @@
*/
public void characters(String s) throws org.xml.sax.SAXException
{
- if (m_inEntityRef && !m_expandDTDEntities)
+ if (isInEntityRef())
return;
final int length = s.length();
if (length > m_charsBuff.length)
@@ -1758,9 +1855,12 @@
Attributes atts)
throws org.xml.sax.SAXException
{
- if (m_inEntityRef)
+ if (isInEntityRef())
return;
+ m_childNodeNum++;
+ flushCharactersBuffer();
+
if (m_needToCallStartDocument)
{
startDocumentInternal();
@@ -1812,6 +1912,12 @@
if (atts != null)
addAttributes(atts);
+ m_ispreserveSpace = m_preserveSpaces.peekOrFalse();
+ m_preserveSpaces.push(m_ispreserveSpace);
+
+ m_childNodeNumStack.push(m_childNodeNum);
+ m_childNodeNum = 0;
+
m_elemContext = m_elemContext.push(namespaceURI,localName,name);
m_isprevtext = false;
@@ -2019,9 +2125,10 @@
throws org.xml.sax.SAXException
{
- if (m_inEntityRef)
+ if (isInEntityRef())
return;
+ flushCharactersBuffer();
// namespaces declared at the current depth are no longer valid
// so get rid of them
m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth, null);
@@ -2055,7 +2162,7 @@
if (m_cdataTagOpen)
closeCDATA();
- if (shouldIndent())
+ if (shouldIndent() && (m_childNodeNum > 1 || !m_isprevtext))
indent(m_elemContext.m_currentElemDepth - 1);
writer.write('<');
writer.write('/');
@@ -2073,6 +2180,9 @@
m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
}
+ m_ispreserveSpace = m_preserveSpaces.popAndTop();
+ m_childNodeNum = m_childNodeNumStack.pop();
+
m_isprevtext = false;
// fire off the end element event
@@ -2208,8 +2318,10 @@
{
int start_old = start;
- if (m_inEntityRef)
+ if (isInEntityRef())
return;
+ m_childNodeNum++;
+ flushCharactersBuffer();
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
@@ -2389,6 +2501,9 @@
*/
public void startCDATA() throws org.xml.sax.SAXException
{
+ m_childNodeNum++;
+ flushCharactersBuffer();
+
m_cdataStartCalled = true;
}
@@ -2412,17 +2527,30 @@
if (name.equals("[dtd]"))
m_inExternalDTD = true;
- if (!m_expandDTDEntities && !m_inExternalDTD) {
- /* Only leave the entity as-is if
- * we've been told not to expand them
- * and this is not the magic [dtd] name.
- */
- startNonEscaping();
- characters("&" + name + ';');
- endNonEscaping();
+ // if this is not the magic [dtd] name
+ if (!m_inExternalDTD) {
+ // if it's not in nested entity reference
+ if (!isInEntityRef()) {
+ if (shouldFormatOutput()) {
+ m_charactersBuffer.addEntityReference(name);
+ } else {
+ outputEntityReference(name);
+ }
+ }
+ m_inEntityRef++;
}
-
- m_inEntityRef = true;
+ }
+
+ /**
+ * Write out the entity reference with the form as "&entityName;".
+ *
+ * @param name The name of the entity.
+ */
+ private void outputEntityReference(String name) throws SAXException {
+ startNonEscaping();
+ characters("&" + name + ';');
+ endNonEscaping();
+ m_isprevtext = true;
}
/**
@@ -2523,7 +2651,7 @@
*/
protected boolean shouldIndent()
{
- return m_doIndent && (!m_ispreserve && !m_isprevtext) && (m_elemContext.m_currentElemDepth > 0 || m_isStandalone);
+ return shouldFormatOutput() && (m_elemContext.m_currentElemDepth > 0 || m_isStandalone);
}
/**
@@ -2815,10 +2943,37 @@
String value,
boolean xslAttribute)
{
+ if (m_charactersBuffer.isAnyCharactersBuffered()) {
+ /*
+ * If stylesheet includes xsl:copy-of an attribute node, XSLTC will
+ * fire an addAttribute event. When a text node is handling in
+ * ToStream, addAttribute has no effect. But closeStartTag call is
+ * delayed to flushCharactersBuffer() method if the text node is
+ * buffered, so here we ignore the attribute to avoid corrupting the
+ * start tag content.
+ *
+ */
+ return m_attributes.getIndex(rawName) < 0;
+ } else {
+ return doAddAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
+ }
+ }
+
+ /**
+ * Does really add the attribute to the set of attributes.
+ */
+ private boolean doAddAttributeAlways(
+ String uri,
+ String localName,
+ String rawName,
+ String type,
+ String value,
+ boolean xslAttribute)
+ {
boolean was_added;
int index;
//if (uri == null || localName == null || uri.length() == 0)
- index = m_attributes.getIndex(rawName);
+ index = m_attributes.getIndex(rawName);
// Don't use 'localName' as it gives incorrect value, rely only on 'rawName'
/*else {
index = m_attributes.getIndex(uri, localName);
@@ -2923,12 +3078,26 @@
e.printStackTrace();
}
}
+
m_attributes.addAttribute(uri, localName, rawName, type, value);
was_added = true;
if (m_tracer != null){
firePseudoAttributes();
}
}
+
+ if (rawName.equals("xml:space")) {
+ if (value.equals("preserve")) {
+ m_ispreserveSpace = true;
+ if (m_preserveSpaces.size() > 0)
+ m_preserveSpaces.setTop(m_ispreserveSpace);
+ } else if (value.equals("default")) {
+ m_ispreserveSpace = false;
+ if (m_preserveSpaces.size() > 0)
+ m_preserveSpaces.setTop(m_ispreserveSpace);
+ }
+ }
+
return was_added;
}
@@ -3059,10 +3228,14 @@
// this.m_format = null;
this.m_inDoctype = false;
this.m_ispreserve = false;
- this.m_ispreserve = false;
+ this.m_preserves.clear();
+ this.m_ispreserveSpace = false;
+ this.m_preserveSpaces.clear();
+ this.m_childNodeNum = 0;
+ this.m_childNodeNumStack.clear();
+ this.m_charactersBuffer.clear();
this.m_isprevtext = false;
this.m_isUTF8 = false; // ?? used anywhere ??
- this.m_preserves.clear();
this.m_shouldFlush = true;
this.m_spaceBeforeClose = false;
this.m_startNewLine = false;
@@ -3238,6 +3411,129 @@
}
}
+ /**
+ * This inner class is used to buffer the text nodes and the entity
+ * reference nodes if indentation is on. There is only one CharacterBuffer
+ * instance in ToStream, it contains a queue of GenericCharacters,
+ * GenericCharacters can be a text node or an entity reference node. The
+ * text nodes and entity reference nodes are joined together and then are
+ * flushed.
+ */
+ private class CharacterBuffer {
+ /**
+ * GenericCharacters is immutable.
+ */
+ private abstract class GenericCharacters {
+ /**
+ * @return True if having any character other than whitespace or
+ * line feed.
+ */
+ abstract boolean hasContent();
+
+ abstract void flush() throws SAXException;
+
+ /**
+ * Converts this GenericCharacters to a new character array.
+ */
+ abstract char[] toChars();
+ }
+
+ private Queue<GenericCharacters> bufferedCharacters = new ArrayDeque<>();
+
+ /**
+ * Append a text node to the buffer.
+ */
+ public void addText(final char chars[], final int start, final int length) {
+ bufferedCharacters.add(new GenericCharacters() {
+ char[] text;
+
+ {
+ text = Arrays.copyOfRange(chars, start, start + length);
+ }
+
+ boolean hasContent() {
+ for (int i = 0; i < text.length; i++) {
+ if (!isWhiteSpace(text[i])) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ void flush() throws SAXException {
+ outputCharacters(text, 0, text.length);
+ }
+
+ char[] toChars() {
+ return text;
+ }
+
+ boolean isWhiteSpace(char ch) {
+ return ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r';
+ }
+
+ });
+ }
+
+ /**
+ * Append an entity reference to the buffer.
+ */
+ public void addEntityReference(String entityName) {
+ bufferedCharacters.add(new GenericCharacters() {
+ boolean hasContent() {
+ return true;
+ }
+
+ void flush() throws SAXException {
+ outputEntityReference(entityName);
+ }
+
+ char[] toChars() {
+ return ("&" + entityName + ";").toCharArray();
+ }
+ });
+ }
+
+ /**
+ * @return True if any GenericCharacters is already buffered.
+ */
+ public boolean isAnyCharactersBuffered() {
+ return !bufferedCharacters.isEmpty();
+ }
+
+ /**
+ * @return True if any buffered GenericCharacters has content.
+ */
+ public boolean hasContent() {
+ return bufferedCharacters.stream().anyMatch(GenericCharacters::hasContent);
+ }
+
+ /**
+ * Flush all buffered GenericCharacters.
+ */
+ public void flush() throws SAXException {
+ GenericCharacters element;
+ while ((element = bufferedCharacters.poll()) != null)
+ element.flush();
+ }
+
+ /**
+ * Converts all buffered GenericCharacters to a new character array.
+ */
+ public char[] toChars() {
+ return bufferedCharacters.stream().map(GenericCharacters::toChars)
+ .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString()
+ .toCharArray();
+ }
+
+ /**
+ * Clear the buffer.
+ */
+ public void clear() {
+ bufferedCharacters.clear();
+ }
+ }
+
// Implement DTDHandler
/**
* If this method is called, the serializer is used as a
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Mon Dec 19 11:13:32 2016 +0800
@@ -1,15 +1,15 @@
/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
+ * Copyright (c) 2014, 2016 Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright 2001-2004 The Apache Software Foundation.
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
*
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,9 +17,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-/*
- * $Id: ToXMLStream.java,v 1.2.4.2 2005/09/15 12:01:25 suresh_emailid Exp $
- */
+
package com.sun.org.apache.xml.internal.serializer;
import java.io.IOException;
@@ -92,6 +90,12 @@
m_ispreserve = xmlListener.m_ispreserve;
m_preserves = xmlListener.m_preserves;
+ m_ispreserveSpace = xmlListener.m_ispreserveSpace;
+ m_preserveSpaces = xmlListener.m_preserveSpaces;
+ m_childNodeNum = xmlListener.m_childNodeNum;
+ m_childNodeNumStack = xmlListener.m_childNodeNumStack;
+ m_charactersBuffer = xmlListener.m_charactersBuffer;
+ m_inEntityRef = xmlListener.m_inEntityRef;
m_isprevtext = xmlListener.m_isprevtext;
m_doIndent = xmlListener.m_doIndent;
setIndentAmount(xmlListener.getIndentAmount());
@@ -124,7 +128,7 @@
super.startDocumentInternal();
m_needToCallStartDocument = false;
- if (m_inEntityRef)
+ if (isInEntityRef())
return;
m_needToOutputDocTypeDecl = true;
@@ -197,6 +201,7 @@
*/
public void endDocument() throws org.xml.sax.SAXException
{
+ flushCharactersBuffer();
flushPending();
if (m_doIndent && !m_isprevtext)
{
@@ -265,9 +270,11 @@
public void processingInstruction(String target, String data)
throws org.xml.sax.SAXException
{
- if (m_inEntityRef)
+ if (isInEntityRef())
return;
+ m_childNodeNum++;
+ flushCharactersBuffer();
flushPending();
if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOM3TreeWalker.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/dom3/DOM3TreeWalker.java Mon Dec 19 11:13:32 2016 +0800
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
*/
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -368,8 +368,6 @@
private final void dispatachChars(Node node)
throws org.xml.sax.SAXException {
if (fSerializer != null) {
- this.fSerializer.characters(node);
- } else {
String data = ((Text) node).getData();
this.fSerializer.characters(data.toCharArray(), 0, data.length());
}
@@ -1066,7 +1064,9 @@
// should we pass entity reference nodes to the filter???
}
- if (fLexicalHandler != null) {
+ // if "entities" is true, or EntityReference node has no children,
+ // it will be serialized as the form "&entityName;" in the output.
+ if (fLexicalHandler != null && ((fFeatures & ENTITIES) != 0 || !node.hasChildNodes())) {
// startEntity outputs only Text but not Element, Attr, Comment
// and PI child nodes. It does so by setting the m_inEntityRef
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/output_html.properties Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/output_html.properties Mon Dec 19 11:13:32 2016 +0800
@@ -1,11 +1,12 @@
###########################################################################
-# reserved comment block
-# DO NOT REMOVE OR ALTER!
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
###########################################################################
-###########################################################################
-# Copyright 2003-2004 The Apache Software Foundation.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
+##
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
@@ -16,11 +17,9 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
-##########################################################################
+##
#
-# $Id: output_html.properties,v 1.2.4.1 2005/09/15 08:15:32 suresh_emailid Exp $
-#
-# Specify defaults when method="html". These defaults use output_xml.properties
+# Specify defaults when method="html". These defaults use output_xml.properties
# as a base.
#
@@ -39,7 +38,7 @@
# xalan:content-handler="MyContentHandler"/>
# ...
# Note that the colon after the protocol needs to be escaped.
-{http\u003a//xml.apache.org/xalan}indent-amount=0
+{http\u003a//xml.apache.org/xalan}indent-amount=4
{http\u003a//xml.apache.org/xalan}content-handler=com.sun.org.apache.xml.internal.serializer.ToHTMLStream
{http\u003a//xml.apache.org/xalan}entities=com/sun/org/apache/xml/internal/serializer/HTMLEntities
{http\u003a//xml.apache.org/xalan}use-url-escaping=yes
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf001GF.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf001GF.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><countries>
-<country name="France">
-<city>Paris</city>
-<city>Nice</city>
-<city>Lyon</city>
-</country>
-<country name="Italia">
-<city>Roma</city>
-<city>Milano</city>
-<city>Firenze</city>
-<city>Napoli</city>
-</country>
-<country name="Espana">
-<city>Madrid</city>
-<city>Barcelona</city>
-</country>
+ <country name="France">
+ <city>Paris</city>
+ <city>Nice</city>
+ <city>Lyon</city>
+ </country>
+ <country name="Italia">
+ <city>Roma</city>
+ <city>Milano</city>
+ <city>Firenze</city>
+ <city>Napoli</city>
+ </country>
+ <country name="Espana">
+ <city>Madrid</city>
+ <city>Barcelona</city>
+ </country>
</countries>
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf002GF.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf002GF.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><countries>
-<country name="France">
-<city>Paris</city>
-<city>Nice</city>
-<city>Lyon</city>
-</country>
-<country name="Italia">
-<city>Roma</city>
-<city>Milano</city>
-<city>Firenze</city>
-<city>Napoli</city>
-</country>
-<country name="Espana">
-<city>Madrid</city>
-<city>Barcelona</city>
-</country>
+ <country name="France">
+ <city>Paris</city>
+ <city>Nice</city>
+ <city>Lyon</city>
+ </country>
+ <country name="Italia">
+ <city>Roma</city>
+ <city>Milano</city>
+ <city>Firenze</city>
+ <city>Napoli</city>
+ </country>
+ <country name="Espana">
+ <city>Madrid</city>
+ <city>Barcelona</city>
+ </country>
</countries>
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf003GF.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf003GF.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><countries>
-<country name="France">
-<city>Paris</city>
-<city>Nice</city>
-<city>Lyon</city>
-</country>
-<country name="Italia">
-<city>Roma</city>
-<city>Milano</city>
-<city>Firenze</city>
-<city>Napoli</city>
-</country>
-<country name="Espana">
-<city>Madrid</city>
-<city>Barcelona</city>
-</country>
+ <country name="France">
+ <city>Paris</city>
+ <city>Nice</city>
+ <city>Lyon</city>
+ </country>
+ <country name="Italia">
+ <city>Roma</city>
+ <city>Milano</city>
+ <city>Firenze</city>
+ <city>Napoli</city>
+ </country>
+ <country name="Espana">
+ <city>Madrid</city>
+ <city>Barcelona</city>
+ </country>
</countries>
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf005GF.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf005GF.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><countries>
-<country name="France">
-<city>Paris</city>
-<city>Nice</city>
-<city>Lyon</city>
-</country>
-<country name="Italia">
-<city>Roma</city>
-<city>Milano</city>
-<city>Firenze</city>
-<city>Napoli</city>
-</country>
-<country name="Espana">
-<city>Madrid</city>
-<city>Barcelona</city>
-</country>
+ <country name="France">
+ <city>Paris</city>
+ <city>Nice</city>
+ <city>Lyon</city>
+ </country>
+ <country name="Italia">
+ <city>Roma</city>
+ <city>Milano</city>
+ <city>Firenze</city>
+ <city>Napoli</city>
+ </country>
+ <country name="Espana">
+ <city>Madrid</city>
+ <city>Barcelona</city>
+ </country>
</countries>
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf006GF.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf006GF.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><countries>
-<country name="France">
-<city>Paris</city>
-<city>Nice</city>
-<city>Lyon</city>
-</country>
-<country name="Italia">
-<city>Roma</city>
-<city>Milano</city>
-<city>Firenze</city>
-<city>Napoli</city>
-</country>
-<country name="Espana">
-<city>Madrid</city>
-<city>Barcelona</city>
-</country>
+ <country name="France">
+ <city>Paris</city>
+ <city>Nice</city>
+ <city>Lyon</city>
+ </country>
+ <country name="Italia">
+ <city>Roma</city>
+ <city>Milano</city>
+ <city>Firenze</city>
+ <city>Napoli</city>
+ </country>
+ <country name="Espana">
+ <city>Madrid</city>
+ <city>Barcelona</city>
+ </country>
</countries>
--- a/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf009GF.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/javax/xml/transform/xmlfiles/out/saxtf009GF.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?><countries>
-<country name="France">
-<city>Paris</city>
-<city>Nice</city>
-<city>Lyon</city>
-</country>
-<country name="Italia">
-<city>Roma</city>
-<city>Milano</city>
-<city>Firenze</city>
-<city>Napoli</city>
-</country>
-<country name="Espana">
-<city>Madrid</city>
-<city>Barcelona</city>
-</country>
+ <country name="France">
+ <city>Paris</city>
+ <city>Nice</city>
+ <city>Lyon</city>
+ </country>
+ <country name="Italia">
+ <city>Roma</city>
+ <city>Milano</city>
+ <city>Firenze</city>
+ <city>Napoli</city>
+ </country>
+ <country name="Espana">
+ <city>Madrid</city>
+ <city>Barcelona</city>
+ </country>
</countries>
--- a/jaxp/test/javax/xml/jaxp/functional/test/astro/AstroTest.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/AstroTest.java Mon Dec 19 11:13:32 2016 +0800
@@ -25,14 +25,13 @@
import static java.lang.String.valueOf;
import static jaxp.library.JAXPTestUtilities.USER_DIR;
-import static org.testng.Assert.assertEquals;
+import static jaxp.library.JAXPTestUtilities.compareWithGold;
+import static org.testng.Assert.assertTrue;
import static test.astro.AstroConstants.ASTROCAT;
import static test.astro.AstroConstants.GOLDEN_DIR;
-import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
-import java.util.List;
import javax.xml.transform.sax.TransformerHandler;
@@ -77,10 +76,10 @@
@BeforeClass
public void setup() throws Exception {
data = new FiltersAndGolden[4];
- data[0] = new FiltersAndGolden(getGoldenFileContent(1), astro -> astro.getRAFilter(0.106, 0.108));
- data[1] = new FiltersAndGolden(getGoldenFileContent(2), astro -> astro.getStellarTypeFilter("K0IIIbCN-0.5"));
- data[2] = new FiltersAndGolden(getGoldenFileContent(3), astro -> astro.getStellarTypeFilter("G"), astro -> astro.getDecFilter(-5.0, 60.0));
- data[3] = new FiltersAndGolden(getGoldenFileContent(4), astro -> astro.getRADECFilter(0.084, 0.096, -5.75, 14.0));
+ data[0] = new FiltersAndGolden(getGoldenFileName(1), astro -> astro.getRAFilter(0.106, 0.108));
+ data[1] = new FiltersAndGolden(getGoldenFileName(2), astro -> astro.getStellarTypeFilter("K0IIIbCN-0.5"));
+ data[2] = new FiltersAndGolden(getGoldenFileName(3), astro -> astro.getStellarTypeFilter("G"), astro -> astro.getDecFilter(-5.0, 60.0));
+ data[3] = new FiltersAndGolden(getGoldenFileName(4), astro -> astro.getRADECFilter(0.084, 0.096, -5.75, 14.0));
}
/*
@@ -102,11 +101,11 @@
AstroProcessor astro = new AstroProcessor(fFactClass, ASTROCAT, isFactClass);
for (int i = 0; i < data.length; i++) {
- runProcess(astro, valueOf(i + 1), data[i].getGolden(), data[i].getFilters());
+ runProcess(astro, valueOf(i + 1), data[i].getGoldenFileName(), data[i].getFilters());
}
}
- private void runProcess(AstroProcessor astro, String processNum, List<String> goldenfileContent, FilterCreator... filterCreators) throws Exception {
+ private void runProcess(AstroProcessor astro, String processNum, String goldenFileName, FilterCreator... filterCreators) throws Exception {
System.out.println("run process " + processNum);
TransformerHandler[] filters = new TransformerHandler[filterCreators.length];
for (int i = 0; i < filterCreators.length; i++)
@@ -115,11 +114,11 @@
String outputfile = Files.createTempFile(Paths.get(USER_DIR), "query" + processNum + ".out.", null).toString();
System.out.println("output file: " + outputfile);
astro.process(outputfile, filters);
- assertEquals(Files.readAllLines(Paths.get(outputfile)), goldenfileContent);
+ assertTrue(compareWithGold(goldenFileName, outputfile));
}
- private List<String> getGoldenFileContent(int num) throws IOException {
- return Files.readAllLines(Paths.get(GOLDEN_DIR + "query" + num + ".out"));
+ private String getGoldenFileName(int num) {
+ return GOLDEN_DIR + "query" + num + ".out";
}
@FunctionalInterface
@@ -129,19 +128,19 @@
private static class FiltersAndGolden {
private FilterCreator[] filters;
- private List<String> golden;
+ private String goldenFileName;
- FiltersAndGolden(List<String> golden, FilterCreator... filters) {
+ FiltersAndGolden(String goldenFileName, FilterCreator... filters) {
this.filters = filters;
- this.golden = golden;
+ this.goldenFileName = goldenFileName;
}
FilterCreator[] getFilters() {
return filters;
}
- List<String> getGolden() {
- return golden;
+ String getGoldenFileName() {
+ return goldenFileName;
}
}
}
--- a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query1.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query1.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,15 +1,24 @@
<html xmlns:astro="http://www.astro.com/astro">
-<h1>Bright Star Catalog Extract</h1>
-<body>
-<b>Star Id: </b>7<br>
-<b>Constellation: </b>Cas<br>
-<b>Description: </b>10 Cas<br>
-<b>RA J2000: </b>00:06:26.5<br>
-<b>DEC J2000: </b>64:11:46<br>
-<b>Visual Magnitude: </b>5.59<br>
-<b>Spectral Type: </b>B9III<br>
-<b>Galactic Longitude: </b>118.06<br>
-<b>Galactic Latitude: </b>1.75<br>
-<hr>
-</body>
+ <h1>Bright Star Catalog Extract</h1>
+ <body>
+ <b>Star Id: </b>7
+ <br>
+ <b>Constellation: </b>Cas
+ <br>
+ <b>Description: </b>10 Cas
+ <br>
+ <b>RA J2000: </b>00:06:26.5
+ <br>
+ <b>DEC J2000: </b>64:11:46
+ <br>
+ <b>Visual Magnitude: </b>5.59
+ <br>
+ <b>Spectral Type: </b>B9III
+ <br>
+ <b>Galactic Longitude: </b>118.06
+ <br>
+ <b>Galactic Latitude: </b>1.75
+ <br>
+ <hr>
+ </body>
</html>
--- a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query2.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query2.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,15 +1,24 @@
<html xmlns:astro="http://www.astro.com/astro">
-<h1>Bright Star Catalog Extract</h1>
-<body>
-<b>Star Id: </b>3<br>
-<b>Constellation: </b>Psc<br>
-<b>Description: </b>33 Psc<br>
-<b>RA J2000: </b>00:05:20.1<br>
-<b>DEC J2000: </b>05:42:27<br>
-<b>Visual Magnitude: </b>4.61<br>
-<b>Spectral Type: </b>K0IIIbCN-0.5<br>
-<b>Galactic Longitude: </b>93.75<br>
-<b>Galactic Latitude: </b>-65.93<br>
-<hr>
-</body>
+ <h1>Bright Star Catalog Extract</h1>
+ <body>
+ <b>Star Id: </b>3
+ <br>
+ <b>Constellation: </b>Psc
+ <br>
+ <b>Description: </b>33 Psc
+ <br>
+ <b>RA J2000: </b>00:05:20.1
+ <br>
+ <b>DEC J2000: </b>05:42:27
+ <br>
+ <b>Visual Magnitude: </b>4.61
+ <br>
+ <b>Spectral Type: </b>K0IIIbCN-0.5
+ <br>
+ <b>Galactic Longitude: </b>93.75
+ <br>
+ <b>Galactic Latitude: </b>-65.93
+ <br>
+ <hr>
+ </body>
</html>
--- a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query3.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query3.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,39 +1,62 @@
<html xmlns:astro="http://www.astro.com/astro">
-<h1>Bright Star Catalog Extract</h1>
-<body>
-<b>Star Id: </b>2<br>
-<b>Constellation: </b>
-<br>
-<b>Description: </b>
-<br>
-<b>RA J2000: </b>00:05:03.8<br>
-<b>DEC J2000: </b>00:30:11<br>
-<b>Visual Magnitude: </b>6.29<br>
-<b>Spectral Type: </b>gG9<br>
-<b>Galactic Longitude: </b>98.33<br>
-<b>Galactic Latitude: </b>-61.14<br>
-<hr>
-<b>Star Id: </b>4<br>
-<b>Constellation: </b>Peg<br>
-<b>Description: </b>86 Peg<br>
-<b>RA J2000: </b>00:05:42.0<br>
-<b>DEC J2000: </b>13:23:46<br>
-<b>Visual Magnitude: </b>5.51<br>
-<b>Spectral Type: </b>G5III<br>
-<b>Galactic Longitude: </b>106.19<br>
-<b>Galactic Latitude: </b>-47.98<br>
-<hr>
-<b>Star Id: </b>5<br>
-<b>Constellation: </b>
-<br>
-<b>Description: </b>
-<br>
-<b>RA J2000: </b>00:06:16.0<br>
-<b>DEC J2000: </b>58:26:12<br>
-<b>Visual Magnitude: </b>5.96<br>
-<b>Spectral Type: </b>G5V<br>
-<b>Galactic Longitude: </b>117.03<br>
-<b>Galactic Latitude: </b>-03.92<br>
-<hr>
-</body>
+ <h1>Bright Star Catalog Extract</h1>
+ <body>
+ <b>Star Id: </b>2
+ <br>
+ <b>Constellation: </b>
+ <br>
+ <b>Description: </b>
+ <br>
+ <b>RA J2000: </b>00:05:03.8
+ <br>
+ <b>DEC J2000: </b>00:30:11
+ <br>
+ <b>Visual Magnitude: </b>6.29
+ <br>
+ <b>Spectral Type: </b>gG9
+ <br>
+ <b>Galactic Longitude: </b>98.33
+ <br>
+ <b>Galactic Latitude: </b>-61.14
+ <br>
+ <hr>
+ <b>Star Id: </b>4
+ <br>
+ <b>Constellation: </b>Peg
+ <br>
+ <b>Description: </b>86 Peg
+ <br>
+ <b>RA J2000: </b>00:05:42.0
+ <br>
+ <b>DEC J2000: </b>13:23:46
+ <br>
+ <b>Visual Magnitude: </b>5.51
+ <br>
+ <b>Spectral Type: </b>G5III
+ <br>
+ <b>Galactic Longitude: </b>106.19
+ <br>
+ <b>Galactic Latitude: </b>-47.98
+ <br>
+ <hr>
+ <b>Star Id: </b>5
+ <br>
+ <b>Constellation: </b>
+ <br>
+ <b>Description: </b>
+ <br>
+ <b>RA J2000: </b>00:06:16.0
+ <br>
+ <b>DEC J2000: </b>58:26:12
+ <br>
+ <b>Visual Magnitude: </b>5.96
+ <br>
+ <b>Spectral Type: </b>G5V
+ <br>
+ <b>Galactic Longitude: </b>117.03
+ <br>
+ <b>Galactic Latitude: </b>-03.92
+ <br>
+ <hr>
+ </body>
</html>
--- a/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query4.out Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/functional/test/astro/xmlfiles/gold/query4.out Mon Dec 19 11:13:32 2016 +0800
@@ -1,37 +1,62 @@
<html xmlns:astro="http://www.astro.com/astro">
-<h1>Bright Star Catalog Extract</h1>
-<body>
-<b>Star Id: </b>2<br>
-<b>Constellation: </b>
-<br>
-<b>Description: </b>
-<br>
-<b>RA J2000: </b>00:05:03.8<br>
-<b>DEC J2000: </b>00:30:11<br>
-<b>Visual Magnitude: </b>6.29<br>
-<b>Spectral Type: </b>gG9<br>
-<b>Galactic Longitude: </b>98.33<br>
-<b>Galactic Latitude: </b>-61.14<br>
-<hr>
-<b>Star Id: </b>3<br>
-<b>Constellation: </b>Psc<br>
-<b>Description: </b>33 Psc<br>
-<b>RA J2000: </b>00:05:20.1<br>
-<b>DEC J2000: </b>05:42:27<br>
-<b>Visual Magnitude: </b>4.61<br>
-<b>Spectral Type: </b>K0IIIbCN-0.5<br>
-<b>Galactic Longitude: </b>93.75<br>
-<b>Galactic Latitude: </b>-65.93<br>
-<hr>
-<b>Star Id: </b>4<br>
-<b>Constellation: </b>Peg<br>
-<b>Description: </b>86 Peg<br>
-<b>RA J2000: </b>00:05:42.0<br>
-<b>DEC J2000: </b>13:23:46<br>
-<b>Visual Magnitude: </b>5.51<br>
-<b>Spectral Type: </b>G5III<br>
-<b>Galactic Longitude: </b>106.19<br>
-<b>Galactic Latitude: </b>-47.98<br>
-<hr>
-</body>
+ <h1>Bright Star Catalog Extract</h1>
+ <body>
+ <b>Star Id: </b>2
+ <br>
+ <b>Constellation: </b>
+ <br>
+ <b>Description: </b>
+ <br>
+ <b>RA J2000: </b>00:05:03.8
+ <br>
+ <b>DEC J2000: </b>00:30:11
+ <br>
+ <b>Visual Magnitude: </b>6.29
+ <br>
+ <b>Spectral Type: </b>gG9
+ <br>
+ <b>Galactic Longitude: </b>98.33
+ <br>
+ <b>Galactic Latitude: </b>-61.14
+ <br>
+ <hr>
+ <b>Star Id: </b>3
+ <br>
+ <b>Constellation: </b>Psc
+ <br>
+ <b>Description: </b>33 Psc
+ <br>
+ <b>RA J2000: </b>00:05:20.1
+ <br>
+ <b>DEC J2000: </b>05:42:27
+ <br>
+ <b>Visual Magnitude: </b>4.61
+ <br>
+ <b>Spectral Type: </b>K0IIIbCN-0.5
+ <br>
+ <b>Galactic Longitude: </b>93.75
+ <br>
+ <b>Galactic Latitude: </b>-65.93
+ <br>
+ <hr>
+ <b>Star Id: </b>4
+ <br>
+ <b>Constellation: </b>Peg
+ <br>
+ <b>Description: </b>86 Peg
+ <br>
+ <b>RA J2000: </b>00:05:42.0
+ <br>
+ <b>DEC J2000: </b>13:23:46
+ <br>
+ <b>Visual Magnitude: </b>5.51
+ <br>
+ <b>Spectral Type: </b>G5III
+ <br>
+ <b>Galactic Longitude: </b>106.19
+ <br>
+ <b>Galactic Latitude: </b>-47.98
+ <br>
+ <hr>
+ </body>
</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/PrettyPrintTest.java Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,366 @@
+/*
+ * Copyright (c) 2014, 2016, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package common.prettyprint;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.Test;
+import org.w3c.dom.DOMConfiguration;
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.Text;
+import org.w3c.dom.bootstrap.DOMImplementationRegistry;
+import org.w3c.dom.ls.DOMImplementationLS;
+import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSSerializer;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+/*
+ * @test
+ * @bug 6439439 8087303
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm -DrunSecMngr=true common.prettyprint.PrettyPrintTest
+ * @run testng/othervm common.prettyprint.PrettyPrintTest
+ * @summary Test serializing xml and html with indentation.
+ */
+@Listeners({jaxp.library.FilePolicy.class})
+public class PrettyPrintTest {
+ /*
+ * test CDATA, elements only, text and element, whitespace and element,
+ * xml:space property and nested xml:space property, mixed node types.
+ */
+ @DataProvider(name = "xml-data")
+ public Object[][] xmlData() throws Exception {
+ return new Object[][] {
+ { read("xmltest1.xml"), read("xmltest1.out") },
+ { read("xmltest2.xml"), read("xmltest2.out") },
+ { read("xmltest3.xml"), read("xmltest3.out") },
+ { read("xmltest4.xml"), read("xmltest4.out") },
+ { read("xmltest5.xml"), read("xmltest5.out") },
+ { read("xmltest6.xml"), read("xmltest6.out") },
+ { read("xmltest7.xml"), read("xmltest7.out") },
+ { read("xmltest8.xml"), read("xmltest8.out") } };
+ }
+
+ /*
+ * @bug 8087303
+ * Test the whitespace text nodes are serialized with pretty-print by LSSerializer and transformer correctly
+ *
+ */
+ @Test(dataProvider = "xml-data")
+ public void testXMLPrettyPrint(String source, String expected) throws Exception {
+ // 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);
+ // 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);
+ // test pretty-print
+ assertEquals(transform(toXmlDocument(source), true).replaceAll("\r\n", "\n"), expected);
+ }
+
+ /*
+ * test pure text content, and sequent Text nodes.
+ */
+ @DataProvider(name = "xml-node-data")
+ public Object[][] xmlNodeData() throws Exception {
+ return new Object[][] {
+ { newTextNode(read("nodetest1.txt")), read("nodetest1.out") },
+ { createDocWithSequentTextNodes(), read("nodetest2.out") } };
+ }
+
+ /*
+ * @bug 8087303
+ * Test the whitespace text nodes are serialized with pretty-print by LSSerializer and transformer correctly,
+ * doesn't compare with the source because the test data is Node object
+ *
+ */
+ @Test(dataProvider = "xml-node-data")
+ public void testXMLNodePrettyPrint(Node xml, String expected) throws Exception {
+ assertEquals(serializerWrite(xml, true), expected);
+ assertEquals(transform(xml, true).replaceAll("\r\n", "\n"), expected);
+ }
+
+ /*
+ * test block element, inline element, text, and mixed elements.
+ */
+ @DataProvider(name = "html-data")
+ public Object[][] htmlData() throws Exception {
+ return new Object[][] {
+ { read("htmltest1.xml"), read("htmltest1.out") },
+ { read("htmltest2.xml"), read("htmltest2.out") },
+ { read("htmltest3.xml"), read("htmltest3.out") },
+ { read("htmltest4.xml"), read("htmltest4.out") },
+ { read("htmltest5.xml"), read("htmltest5.out") },
+ { read("htmltest6.xml"), read("htmltest6.out") } };
+ }
+
+ /*
+ * @bug 8087303
+ * Transform to HTML, test Pretty Print for HTML.
+ *
+ */
+ @Test(dataProvider = "html-data")
+ public void testTransformToHTML(String source, String expected) throws Exception {
+ // 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());
+
+ // test pretty-print
+ writer = new StringWriter();
+ getTransformer(true, true).transform(new StreamSource(new StringReader(source)), new StreamResult(writer));
+ assertEquals(writer.toString().replaceAll("\r\n", "\n"), expected);
+ }
+
+ @Test
+ 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>";
+ /**JDK-8035467
+ * no newline in default output
+ */
+ final String XML_DOCUMENT_DEFAULT_PRINT =
+ "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
+ + "<hello>"
+ + "before child element"
+ + "<child><children/><children/></child>"
+ + "after child element</hello>";
+
+ final String XML_DOCUMENT_PRETTY_PRINT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?><hello>\n" +
+ " before child element\n" +
+ " <child>\n" +
+ " <children/>\n" +
+ " <children/>\n" +
+ " </child>\n" +
+ " after child element\n" +
+ "</hello>\n";
+
+ // it all begins with a Document
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder documentBuilder = null;
+ try {
+ documentBuilder = documentBuilderFactory.newDocumentBuilder();
+ } catch (ParserConfigurationException parserConfigurationException) {
+ parserConfigurationException.printStackTrace();
+ Assert.fail(parserConfigurationException.toString());
+ }
+ Document document = null;
+
+ StringReader stringReader = new StringReader(XML_DOCUMENT);
+ InputSource inputSource = new InputSource(stringReader);
+ try {
+ document = documentBuilder.parse(inputSource);
+ } catch (SAXException saxException) {
+ saxException.printStackTrace();
+ Assert.fail(saxException.toString());
+ } catch (IOException ioException) {
+ ioException.printStackTrace();
+ Assert.fail(ioException.toString());
+ }
+
+ // query DOM Interfaces to get to a LSSerializer
+ DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
+ DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
+ LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
+
+ 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 + "/"
+ + canSetFormatPrettyPrintFalse + "/" + canSetFormatPrettyPrintTrue);
+
+ // test values
+ 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 "
+ + Boolean.TRUE);
+
+ 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)
+ + ": \n\"" + prettyPrintDefault + "\"");
+
+ 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)
+ + ": \n\"" + prettyPrintFalse + "\"");
+
+ 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)
+ + ": \n\"" + prettyPrintTrue + "\"");
+
+ 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");
+ StringWriter writer = new StringWriter();
+ LSOutput formattedOutput = domImplementation.createLSOutput();
+ formattedOutput.setCharacterStream(writer);
+ LSSerializer domSerializer = domImplementation.createLSSerializer();
+ domSerializer.getDomConfig().setParameter(DOM_FORMAT_PRETTY_PRINT, pretty);
+ domSerializer.getDomConfig().setParameter("xml-declaration", false);
+ domSerializer.write(xml, formattedOutput);
+ return writer.toString();
+ }
+
+ private String transform(Node xml, boolean pretty) throws Exception {
+ Transformer transformer = getTransformer(false, pretty);
+ StringWriter writer = new StringWriter();
+ transformer.transform(new DOMSource(xml), new StreamResult(writer));
+ return writer.toString();
+ }
+
+ private Document toXmlDocument(String xmlString) throws Exception {
+ InputSource xmlInputSource = new InputSource(new StringReader(xmlString));
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setValidating(true);
+ DocumentBuilder xmlDocumentBuilder = dbf.newDocumentBuilder();
+ Document node = xmlDocumentBuilder.parse(xmlInputSource);
+ return node;
+ }
+
+ private Text newTextNode(String text) throws Exception {
+ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ return db.newDocument().createTextNode(text);
+ }
+
+ private Document createDocWithSequentTextNodes() throws Exception {
+ DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
+ Document doc = db.newDocument();
+ Node root = doc.createElement("root");
+ doc.appendChild(root);
+ root.appendChild(doc.createTextNode(" "));
+ root.appendChild(doc.createTextNode("t"));
+ root.appendChild(doc.createTextNode("\n"));
+ root.appendChild(doc.createTextNode("t"));
+ root.appendChild(doc.createTextNode(" "));
+ Node child1 = doc.createElement("child1");
+ root.appendChild(child1);
+ child1.appendChild(doc.createTextNode(" "));
+ child1.appendChild(doc.createTextNode("\n"));
+ root.appendChild(doc.createTextNode("t"));
+ Node child2 = doc.createElement("child2");
+ root.appendChild(child2);
+ child2.appendChild(doc.createTextNode(" "));
+ root.appendChild(doc.createTextNode(" "));
+ Node child3 = doc.createElement("child3");
+ root.appendChild(child3);
+ child3.appendChild(doc.createTextNode(" "));
+ root.appendChild(doc.createTextNode(" "));
+ Node child4 = doc.createElement("child4");
+ root.appendChild(child4);
+ child4.appendChild(doc.createTextNode(" "));
+
+ root.appendChild(doc.createTextNode(" "));
+ Node child5 = doc.createElement("child5");
+ root.appendChild(child5);
+ child5.appendChild(doc.createTextNode("t"));
+
+ Node child51 = doc.createElement("child51");
+ child5.appendChild(child51);
+ child51.appendChild(doc.createTextNode(" "));
+ Node child511 = doc.createElement("child511");
+ child51.appendChild(child511);
+ child511.appendChild(doc.createTextNode("t"));
+ child51.appendChild(doc.createTextNode(" "));
+ child5.appendChild(doc.createTextNode("t"));
+
+ root.appendChild(doc.createTextNode(" "));
+ root.appendChild(doc.createComment(" test comment "));
+ root.appendChild(doc.createTextNode(" \n"));
+ root.appendChild(doc.createComment(" "));
+ root.appendChild(doc.createTextNode("\n"));
+ root.appendChild(doc.createProcessingInstruction("target1", "test"));
+ root.appendChild(doc.createTextNode(" "));
+ root.appendChild(doc.createTextNode(" "));
+ return doc;
+ }
+
+ private Transformer getTransformer(boolean html, boolean pretty) throws Exception {
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ if (html)
+ transformer.setOutputProperty(OutputKeys.METHOD, "html");
+ transformer.setOutputProperty(OutputKeys.INDENT, pretty ? "yes" : "no");
+ 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";
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest1.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,6 @@
+<rss version="2.0">
+ <channel xml:space="preserve">
+ <title>Java Tutorials and Examples 1</title>
+ <language>en-us</language>
+ </channel>
+</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest1.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<rss version="2.0"><channel xml:space="preserve"><title>Java Tutorials and Examples 1</title> <language>en-us</language></channel></rss>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest2.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,3 @@
+<html>
+ <code>Java</code><b><sup>TM</sup></b>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest2.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<html><code>Java</code><b><sup>TM</sup></b></html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest3.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,3 @@
+<p>
+ this is <a href="test.html">a <strong>test</strong></a> page
+</p>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest3.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<p>this is <a href="test.html">a <strong>test</strong></a> page</p>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest4.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,10 @@
+<html>
+ <body>
+ <h1>A heading</h1>
+ <p>
+ new paragraph
+ <form>an empty form</form>
+ <a href="test.html">test</a>
+ </p>
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest4.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<html><body><h1>A heading</h1><p>new paragraph<form>an empty form</form><a href="test.html">test</a></p></body></html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest5.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,7 @@
+<html>
+ <p>
+ this is a mixed test <a href="test.html">click
+ <p>to the test</p>
+ page</a>link end
+ </p>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest5.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<html><p>this is a mixed test <a href="test.html">click<p>to the test</p>page</a>link end</p></html>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest6.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,6 @@
+<p>
+ <a href="test.html">text
+ <table></table>
+ </a> another
+ <form></form>
+</p>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/htmltest6.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<p><a href="test.html">text<table/></a> another<form/></p>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/nodetest1.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,4 @@
+ abc def
+line2 &a
+ test
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/nodetest1.txt Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,4 @@
+ abc def
+line2 &a
+ test
+
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/nodetest2.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,19 @@
+<root>
+ t
+t
+ <child1/>
+ t
+ <child2/>
+ <child3/>
+ <child4/>
+ <child5>
+ t
+ <child51>
+ <child511>t</child511>
+ </child51>
+ t
+ </child5>
+ <!-- test comment -->
+ <!-- -->
+ <?target1 test?>
+</root>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,3 @@
+<a>
+ <![CDATA[ ]]>
+</a>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest1.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<a><![CDATA[ ]]></a>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,5 @@
+<a>
+ <![CDATA[ abc def
+line2 &a
+ test]]>
+</a>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest2.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,3 @@
+<a><![CDATA[ abc def
+line2 &a
+ test]]></a>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest3.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,5 @@
+<rss version="2.0">
+ <ns:test id="i001">
+ <ns:child/>
+ </ns:test>
+</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest3.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<rss version="2.0"><ns:test id='i001'><ns:child></ns:child></ns:test></rss>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest4.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,6 @@
+<rss version="2.0">
+ <ns:test id="i001">
+ <ns:child>child1</ns:child>
+ <test att1="v1"> abc test</test>
+ </ns:test>
+</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest4.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<rss version="2.0"><ns:test id='i001'><ns:child>child1</ns:child><test att1='v1'> abc test</test></ns:test></rss>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest5.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,10 @@
+<rss version="2.0">
+ <channel>
+ <title>Java Tutorials and Examples 1</title>
+ <language>en-us</language>
+ </channel>
+ <a>
+ <b/>
+ </a>
+ <c/>
+</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest5.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,3 @@
+<rss version="2.0"><channel> <title>Java Tutorials and Examples 1</title> <language>en-us</language></channel><a><b> </b></a> <c>
+
+</c></rss>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest6.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,3 @@
+<rss version="2.0">
+ <channel xml:space="preserve"> <title>Java Tutorials and Examples 1</title> <language>en-us</language></channel>
+</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest6.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,1 @@
+<rss version="2.0"><channel xml:space="preserve"> <title>Java Tutorials and Examples 1</title> <language>en-us</language></channel></rss>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest7.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,10 @@
+<rss>
+ <layer1 xml:space="preserve"> <title>Java </title> <layer2 xml:space="asfsa"> <layer3> <layer4 xml:space="default">
+ <l5>5</l5>
+ </layer4> </layer3> </layer2> <layer2 xml:space="default">
+ <layer3>
+ <l4/>
+ </layer3>
+ <layer3 xml:space="preserve"> <l4> </l4> </layer3>
+ </layer2> </layer1>
+</rss>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest7.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,2 @@
+<rss><layer1 xml:space="preserve"> <title>Java </title> <layer2 xml:space="asfsa"> <layer3> <layer4 xml:space="default"> <l5>5</l5>
+ </layer4> </layer3> </layer2> <layer2 xml:space="default"> <layer3> <l4> </l4> </layer3> <layer3 xml:space="preserve"> <l4> </l4> </layer3></layer2> </layer1></rss>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.out Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,25 @@
+<root>
+
+ t
+ <![CDATA[ ]]>
+
+t
+
+ <child1/>
+
+ t
+ <!-- test comment -->
+ <child2/>
+ <child5>
+
+ t
+ <?target1 test?>
+ <child51>
+ <child511>t</child511>
+ </child51>
+ <?target1 test?>
+
+ t
+
+ </child5>
+</root>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/common/prettyprint/xmltest8.xml Mon Dec 19 11:13:32 2016 +0800
@@ -0,0 +1,15 @@
+<root>
+ t<![CDATA[ ]]>
+t
+ <child1/>
+ t<!-- test comment -->
+ <child2/>
+ <child5>
+ t<?target1 test?>
+ <child51>
+ <child511>t</child511>
+ </child51><?target1 test?>
+ t
+ </child5>
+
+</root>
--- a/jaxp/test/javax/xml/jaxp/unittest/dom/ls/LSSerializerTest.java Fri Dec 16 08:18:05 2016 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/dom/ls/LSSerializerTest.java Mon Dec 19 11:13:32 2016 +0800
@@ -23,6 +23,8 @@
package dom.ls;
+import static org.w3c.dom.ls.DOMImplementationLS.MODE_SYNCHRONOUS;
+
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
@@ -35,22 +37,22 @@
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;
-import org.w3c.dom.DOMConfiguration;
import org.w3c.dom.DOMError;
import org.w3c.dom.DOMErrorHandler;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSException;
+import org.w3c.dom.ls.LSInput;
import org.w3c.dom.ls.LSOutput;
+import org.w3c.dom.ls.LSParser;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-
/*
* @test
- * @bug 6439439 8080906
+ * @bug 8080906 8114834
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true dom.ls.LSSerializerTest
* @run testng/othervm dom.ls.LSSerializerTest
@@ -58,7 +60,6 @@
*/
@Listeners({jaxp.library.BasePolicy.class})
public class LSSerializerTest {
- private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
class DOMErrorHandlerImpl implements DOMErrorHandler {
@@ -167,101 +168,6 @@
}
@Test
- public void testFormatPrettyPrint() {
-
- final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n" + "<hello>" + "world" + "<child><children/><children/></child>"
- + "</hello>";
- /**JDK-8035467
- * no newline in default output
- */
- final String XML_DOCUMENT_DEFAULT_PRINT =
- "<?xml version=\"1.0\" encoding=\"UTF-16\"?>"
- + "<hello>"
- + "world"
- + "<child><children/><children/></child>"
- + "</hello>";
-
- final String XML_DOCUMENT_PRETTY_PRINT = "<?xml version=\"1.0\" encoding=\"UTF-16\"?>" + "<hello>" + "world" + "<child>" + "\n" + " "
- + "<children/>" + "\n" + " " + "<children/>" + "\n" + " " + "</child>" + "\n" + "</hello>" + "\n";
-
- // it all begins with a Document
- DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
- DocumentBuilder documentBuilder = null;
- try {
- documentBuilder = documentBuilderFactory.newDocumentBuilder();
- } catch (ParserConfigurationException parserConfigurationException) {
- parserConfigurationException.printStackTrace();
- Assert.fail(parserConfigurationException.toString());
- }
- Document document = null;
-
- StringReader stringReader = new StringReader(XML_DOCUMENT);
- InputSource inputSource = new InputSource(stringReader);
- try {
- document = documentBuilder.parse(inputSource);
- } catch (SAXException saxException) {
- saxException.printStackTrace();
- Assert.fail(saxException.toString());
- } catch (IOException ioException) {
- ioException.printStackTrace();
- Assert.fail(ioException.toString());
- }
-
- // query DOM Interfaces to get to a LSSerializer
- DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
- DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
- LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
-
- 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 + "/"
- + canSetFormatPrettyPrintFalse + "/" + canSetFormatPrettyPrintTrue);
-
- // test values
- Assert.assertEquals(defaultFormatPrettyPrint, Boolean.FALSE, "Default value of " + DOM_FORMAT_PRETTY_PRINT + " should be " + Boolean.FALSE);
-
- Assert.assertEquals(canSetFormatPrettyPrintFalse, Boolean.TRUE, "Can set " + DOM_FORMAT_PRETTY_PRINT + " to " + Boolean.FALSE + " should be "
- + Boolean.TRUE);
-
- Assert.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)
- + ": \n\"" + prettyPrintDefault + "\"");
-
- Assert.assertEquals(XML_DOCUMENT_DEFAULT_PRINT, prettyPrintDefault, "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)
- + ": \n\"" + prettyPrintFalse + "\"");
-
- Assert.assertEquals(XML_DOCUMENT_DEFAULT_PRINT, prettyPrintFalse, "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)
- + ": \n\"" + prettyPrintTrue + "\"");
-
- Assert.assertEquals(XML_DOCUMENT_PRETTY_PRINT, prettyPrintTrue, "Invalid serialization with TRUE value, " + DOM_FORMAT_PRETTY_PRINT + "=="
- + (Boolean) domConfiguration.getParameter(DOM_FORMAT_PRETTY_PRINT));
- }
-
- @Test
public void testXML11() {
/**
@@ -318,4 +224,109 @@
// output should == input
Assert.assertEquals(XML11_DOCUMENT_OUTPUT, defaultSerialization, "Invalid serialization of XML 1.1 document: ");
}
+
+ /*
+ * @bug 8114834 test entity reference, nested entity reference when entities
+ * is true and false
+ */
+ @Test
+ public void testEntityReference() throws Exception {
+ final String XML_DOCUMENT = "<?xml version=\"1.1\" encoding=\"UTF-16\"?>\n" +
+ "<!DOCTYPE author [\n" +
+ " <!ENTITY name \"Jo Smith\">" +
+ " <!ENTITY name1 \"&name;\">" +
+ " <!ENTITY name2 \"&name1;\">" +
+ "<!ENTITY ele \"<aa><bb>text</bb></aa>\">" +
+ " <!ENTITY ele1 \"&ele;\">" +
+ " <!ENTITY ele2 \"&ele1;\">" +
+ " ]>" +
+ " <author><a>&name1;</a>" +
+ "<b>b &name2; &name1; b</b>" +
+ "<c> &name; </c>" +
+ "<d>&ele1;d</d>" +
+ "<e> &ele2;eee </e>" +
+ "<f><att></f>" +
+ "<g> &ele; g</g>" +
+ "<h>&ele2;</h></author>" ;
+
+
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ DOMImplementation domImplementation = documentBuilder.getDOMImplementation();
+ DOMImplementationLS domImplementationLS = (DOMImplementationLS) domImplementation;
+
+ LSParser domParser = domImplementationLS.createLSParser(MODE_SYNCHRONOUS, null);
+ domParser.getDomConfig().setParameter("entities", Boolean.TRUE);
+
+ LSInput src = domImplementationLS.createLSInput();
+ src.setStringData(XML_DOCUMENT);
+ Document document = domParser.parse(src);
+
+ LSSerializer lsSerializer = domImplementationLS.createLSSerializer();
+
+ lsSerializer.getDomConfig().setParameter("format-pretty-print", true);
+ System.out.println("test with default entities is " + lsSerializer.getDomConfig().getParameter("entities"));
+ Assert.assertEquals(lsSerializer.writeToString(document),
+ "<?xml version=\"1.1\" encoding=\"UTF-16\"?><!DOCTYPE author [ \n" +
+ "<!ENTITY name 'Jo Smith'>\n" +
+ "<!ENTITY name1 '&name;'>\n" +
+ "<!ENTITY name2 '&name1;'>\n" +
+ "<!ENTITY ele '<aa><bb>text</bb></aa>'>\n" +
+ "<!ENTITY ele1 '&ele;'>\n" +
+ "<!ENTITY ele2 '&ele1;'>\n" +
+ "]>\n" +
+ "<author>\n" +
+ " <a>&name1;Jo Smith</a>\n" +
+ " <b>b &name2;Jo Smith &name1;Jo Smith b</b>\n" +
+ " <c> &name;Jo Smith </c>\n" +
+ " <d>&ele1;d</d>\n" +
+ " <e> &ele2;eee </e>\n" +
+ " <f><att></f>\n" +
+ " <g> &ele; g</g>\n" +
+ " <h>&ele2;</h>\n" +
+ "</author>\n");
+
+ lsSerializer.getDomConfig().setParameter("entities", Boolean.FALSE);
+ System.out.println("test with entities is false");
+ Assert.assertEquals(lsSerializer.writeToString(document),
+ "<?xml version=\"1.1\" encoding=\"UTF-16\"?><!DOCTYPE author [ \n" +
+ "<!ENTITY name 'Jo Smith'>\n" +
+ "<!ENTITY name1 '&name;'>\n" +
+ "<!ENTITY name2 '&name1;'>\n" +
+ "<!ENTITY ele '<aa><bb>text</bb></aa>'>\n" +
+ "<!ENTITY ele1 '&ele;'>\n" +
+ "<!ENTITY ele2 '&ele1;'>\n" +
+ "]>\n" +
+ "<author>\n" +
+ " <a>&name;Jo Smith</a>\n" +
+ " <b>b &name;Jo Smith &name;Jo Smith b</b>\n" +
+ " <c> &name;Jo Smith </c>\n" +
+ " <d>\n" +
+ " <aa>\n" +
+ " <bb>text</bb>\n" +
+ " </aa>\n" +
+ " d\n" +
+ " </d>\n" +
+ " <e>\n" +
+ " <aa>\n" +
+ " <bb>text</bb>\n" +
+ " </aa>\n" +
+ " eee \n" +
+ " </e>\n" +
+ " <f><att></f>\n" +
+ " <g>\n" +
+ " <aa>\n" +
+ " <bb>text</bb>\n" +
+ " </aa>\n" +
+ " g\n" +
+ " </g>\n" +
+ " <h>\n" +
+ " <aa>\n" +
+ " <bb>text</bb>\n" +
+ " </aa>\n" +
+ " </h>\n" +
+ "</author>\n");
+
+ }
}