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
This commit is contained in:
Frank Yuan 2016-12-19 11:13:32 +08:00
parent edf9aa2ce5
commit 1619ba4842
52 changed files with 1377 additions and 441 deletions

View File

@ -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 @@ public abstract class AbstractTranslet implements Translet {
handler.setVersion(_version);
}
handler.setIndent(_indent);
handler.setIndentAmount(_indentamount);
if (_indentamount >= 0)
handler.setIndentAmount(_indentamount);
if (_doctypeSystem != null) {
handler.setDoctype(_doctypeSystem, _doctypePublic);
}

View File

@ -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 @@ public final class TransformerImpl extends Transformer
/**
* 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 @@ public final class TransformerImpl extends Transformer
_uriResolver = null;
_dom = null;
_parameters = null;
_indentNumber = 0;
_indentNumber = -1;
setOutputProperties (null);
_tohFactory = null;
_ostream = null;

View File

@ -93,9 +93,11 @@ public abstract class SerializerBase
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 @@ public abstract class SerializerBase
/**
* 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,12 +446,23 @@ public abstract class SerializerBase
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.
@ -1139,8 +1152,8 @@ public abstract class SerializerBase
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;

View File

@ -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,23 +17,20 @@
* 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 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;
import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
import com.sun.org.apache.xml.internal.serializer.utils.Utils;
/**
* This serializer takes a series of SAX or
* SAX-like events and writes its output
@ -52,9 +47,8 @@ public final class ToHTMLStream extends ToStream
/** 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 class ToHTMLStream extends ToStream
*/
public final void endDocument() throws org.xml.sax.SAXException
{
flushCharactersBuffer();
flushPending();
if (m_doIndent && !m_isprevtext)
{
@ -743,26 +737,48 @@ public final class ToHTMLStream extends ToStream
}
/**
* 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 @@ public final class ToHTMLStream extends ToStream
// 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 @@ public final class ToHTMLStream extends ToStream
writer.write('<');
writer.write(name);
m_childNodeNumStack.push(m_childNodeNum);
m_childNodeNum = 0;
if (m_tracer != null)
firePseudoAttributes();
@ -850,6 +863,15 @@ public final class ToHTMLStream extends ToStream
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 @@ public final class ToHTMLStream extends ToStream
final String name)
throws org.xml.sax.SAXException
{
flushCharactersBuffer();
// deal with any pending issues
if (m_cdataTagOpen)
closeCDATA();
@ -919,18 +942,18 @@ public final class ToHTMLStream extends ToStream
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 @@ public final class ToHTMLStream extends ToStream
}
}
m_childNodeNum = m_childNodeNumStack.pop();
// clean up because the element has ended
if ((elemFlags & ElemDesc.WHITESPACESENSITIVE) != 0)
m_ispreserve = true;
@ -1511,7 +1535,7 @@ public final class ToHTMLStream extends ToStream
// 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 class ToHTMLStream extends ToStream
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 final class ToHTMLStream extends ToStream
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 @@ public final class ToHTMLStream extends ToStream
private void initToHTMLStream()
{
// m_elementDesc = null;
m_inBlockElem = false;
m_isprevblock = false;
m_inDTD = false;
// m_isRawStack.clear();
m_omitMetaTag = false;
m_specialEscapeURLs = true;
}

View File

@ -29,12 +29,16 @@ import java.io.OutputStream;
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;
@ -88,6 +92,29 @@ abstract public class ToStream extends SerializerBase {
*/
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
throws org.xml.sax.SAXException
{
if (m_inEntityRef)
if (isInEntityRef())
return;
try
{
@ -1378,9 +1402,11 @@ abstract public class ToStream extends SerializerBase {
// 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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
{
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 @@ abstract public class ToStream extends SerializerBase {
*/
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 @@ abstract public class ToStream extends SerializerBase {
Attributes atts)
throws org.xml.sax.SAXException
{
if (m_inEntityRef)
if (isInEntityRef())
return;
m_childNodeNum++;
flushCharactersBuffer();
if (m_needToCallStartDocument)
{
startDocumentInternal();
@ -1812,6 +1912,12 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
{
int start_old = start;
if (m_inEntityRef)
if (isInEntityRef())
return;
m_childNodeNum++;
flushCharactersBuffer();
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
@ -2389,6 +2501,9 @@ abstract public class ToStream extends SerializerBase {
*/
public void startCDATA() throws org.xml.sax.SAXException
{
m_childNodeNum++;
flushCharactersBuffer();
m_cdataStartCalled = true;
}
@ -2412,17 +2527,30 @@ abstract public class ToStream extends SerializerBase {
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 "&amp;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 @@ abstract public class ToStream extends SerializerBase {
*/
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);
}
/**
@ -2814,11 +2942,38 @@ abstract public class ToStream extends SerializerBase {
String type,
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 @@ abstract public class ToStream extends SerializerBase {
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 @@ abstract public class ToStream extends SerializerBase {
// 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 @@ abstract public class ToStream extends SerializerBase {
}
}
/**
* 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

View File

@ -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 @@ public final class ToXMLStream extends ToStream
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 @@ public final class ToXMLStream extends ToStream
super.startDocumentInternal();
m_needToCallStartDocument = false;
if (m_inEntityRef)
if (isInEntityRef())
return;
m_needToOutputDocTypeDecl = true;
@ -197,6 +201,7 @@ public final class ToXMLStream extends ToStream
*/
public void endDocument() throws org.xml.sax.SAXException
{
flushCharactersBuffer();
flushPending();
if (m_doIndent && !m_isprevtext)
{
@ -265,9 +270,11 @@ public final class ToXMLStream extends ToStream
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))

View File

@ -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 @@ final class DOM3TreeWalker {
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 @@ final class DOM3TreeWalker {
// 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

View File

@ -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 @@ version=4.0
# 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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -25,14 +25,13 @@ package test.astro;
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 @@ public class AstroTest {
@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 @@ public class AstroTest {
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 @@ public class AstroTest {
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 @@ public class AstroTest {
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;
}
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
<rss version="2.0"><channel xml:space="preserve"><title>Java Tutorials and Examples 1</title> <language>en-us</language></channel></rss>

View File

@ -0,0 +1,3 @@
<html>
<code>Java</code><b><sup>TM</sup></b>
</html>

View File

@ -0,0 +1 @@
<html><code>Java</code><b><sup>TM</sup></b></html>

View File

@ -0,0 +1,3 @@
<p>
this is <a href="test.html">a <strong>test</strong></a> page
</p>

View File

@ -0,0 +1 @@
<p>this is <a href="test.html">a <strong>test</strong></a> page</p>

View File

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

View File

@ -0,0 +1 @@
<html><body><h1>A heading</h1><p>new paragraph<form>an empty form</form><a href="test.html">test</a></p></body></html>

View File

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

View File

@ -0,0 +1 @@
<html><p>this is a mixed test <a href="test.html">click<p>to the test</p>page</a>link end</p></html>

View File

@ -0,0 +1,6 @@
<p>
<a href="test.html">text
<table></table>
</a> another
<form></form>
</p>

View File

@ -0,0 +1 @@
<p><a href="test.html">text<table/></a> another<form/></p>

View File

@ -0,0 +1,4 @@
abc def
line2 &amp;a
test

View File

@ -0,0 +1,4 @@
abc def
line2 &a
test

View File

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

View File

@ -0,0 +1,3 @@
<a>
<![CDATA[ ]]>
</a>

View File

@ -0,0 +1 @@
<a><![CDATA[ ]]></a>

View File

@ -0,0 +1,5 @@
<a>
<![CDATA[ abc def
line2 &a
test]]>
</a>

View File

@ -0,0 +1,3 @@
<a><![CDATA[ abc def
line2 &a
test]]></a>

View File

@ -0,0 +1,5 @@
<rss version="2.0">
<ns:test id="i001">
<ns:child/>
</ns:test>
</rss>

View File

@ -0,0 +1 @@
<rss version="2.0"><ns:test id='i001'><ns:child></ns:child></ns:test></rss>

View File

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

View File

@ -0,0 +1 @@
<rss version="2.0"><ns:test id='i001'><ns:child>child1</ns:child><test att1='v1'> abc test</test></ns:test></rss>

View File

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

View File

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

View File

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

View File

@ -0,0 +1 @@
<rss version="2.0"><channel xml:space="preserve"> <title>Java Tutorials and Examples 1</title> <language>en-us</language></channel></rss>

View File

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

View File

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

View File

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

View File

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

View File

@ -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 javax.xml.parsers.ParserConfigurationException;
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 @@ import org.xml.sax.SAXException;
*/
@Listeners({jaxp.library.BasePolicy.class})
public class LSSerializerTest {
private static final String DOM_FORMAT_PRETTY_PRINT = "format-pretty-print";
class DOMErrorHandlerImpl implements DOMErrorHandler {
@ -166,101 +167,6 @@ public class LSSerializerTest {
Assert.assertTrue(eh.NoOutputSpecifiedErrorReceived, "'no-output-specified' error was expected");
}
@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 @@ public class LSSerializerTest {
// 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>&lt;att&gt;</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>&lt;att&gt;</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>&lt;att&gt;</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");
}
}