1 /* 2 * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package test.gaptest; 24 25 import static jaxp.library.JAXPTestUtilities.filenameToURL; 26 import static org.testng.Assert.assertEquals; 27 import static test.gaptest.GapTestConst.GOLDEN_DIR; 28 import static test.gaptest.GapTestConst.XML_DIR; 29 30 import java.io.IOException; 31 import java.nio.file.Files; 32 import java.nio.file.Paths; 33 34 import javax.xml.transform.Transformer; 35 import javax.xml.transform.TransformerException; 36 import javax.xml.transform.TransformerFactory; 37 import javax.xml.transform.dom.DOMResult; 38 import javax.xml.transform.stream.StreamSource; 39 40 import org.testng.annotations.Listeners; 41 import org.testng.annotations.Test; 42 import org.w3c.dom.NamedNodeMap; 43 import org.w3c.dom.Node; 44 import org.w3c.dom.NodeList; 45 46 /* 47 * @bug 4858685 4894410 48 * @summary test transforming text node 49 */ 50 @Listeners({jaxp.library.FilePolicy.class}) 51 public class Bug4858685 { 52 @Test 53 public void test() throws TransformerException, IOException { 54 String uri = XML_DIR + "certificate.xml"; 55 TransformerFactory transformerFactory = TransformerFactory.newInstance(); 56 57 Transformer transformer = transformerFactory.newTransformer(); 58 59 // use URI as a StreamSource 60 StreamSource streamSource = new StreamSource(filenameToURL(uri)); 61 62 DOMResult domResult = new DOMResult(); 63 64 // StreamSource -> DOMResult 65 transformer.transform(streamSource, domResult); 66 67 // dump DOM in a human readable form 68 String gotString = DOMDump.dumpDom(domResult.getNode()); 69 70 String goldenString = new String(Files.readAllBytes(Paths.get(GOLDEN_DIR + "Bug4858685.txt"))); 71 72 assertEquals(gotString, goldenString); 73 74 } 75 76 /** 77 * DOMDump: dump a DOM to a String in human readable form. method dumpDOM() 78 * is static for easy calling: 79 */ 80 private static class DOMDump { 81 82 /** 83 * the maximum level to indent with blanks 84 */ 85 private static final int BLANKS_LEN = 64; 86 87 /** 88 * each level of the tree will be indented with blanks for readability 89 */ 90 private static final String BLANKS = " "; 91 92 /** 93 * dumpDOM will dump the DOM into a String for human readability 94 * 95 * @param domNode 96 * the DOM Node to dump 97 * @return human readabile DOM as a String 98 */ 99 public static String dumpDom(Node domNode) { 100 return dumpInternal(domNode, 0); 101 } 102 103 /** 104 * dumpInternal is used internaly to recursively dump DOM Nodes 105 * 106 * @param domNode 107 * to dump 108 * @param indent 109 * level 110 * @return domNode as human readable String 111 */ 112 private static String dumpInternal(Node domNode, int indent) { 113 114 String result = ""; 115 116 // indent for readability 117 result += indentBlanks(indent); 118 indent += 2; 119 120 // protect against null 121 if (domNode == null) { 122 result = result + "[null]" + "\n"; 123 return result; 124 } 125 126 // what to output depends on NodeType 127 short type = domNode.getNodeType(); 128 switch (type) { 129 case Node.ATTRIBUTE_NODE: { 130 result += "[attribute] " + domNode.getNodeName() + "=\"" + domNode.getNodeValue() + "\""; 131 break; 132 } 133 case Node.CDATA_SECTION_NODE: { 134 result += "[cdata] " + domNode.getNodeValue(); 135 break; 136 } 137 case Node.COMMENT_NODE: { 138 result += "[comment] " + domNode.getNodeValue(); 139 break; 140 } 141 case Node.DOCUMENT_FRAGMENT_NODE: { 142 result += "[document fragment]"; 143 break; 144 } 145 case Node.DOCUMENT_NODE: { 146 result += "[document]"; 147 break; 148 } 149 case Node.DOCUMENT_TYPE_NODE: { 150 result += "[document type] " + domNode.getNodeName(); 151 break; 152 } 153 case Node.ELEMENT_NODE: { 154 result += "[element] " + domNode.getNodeName(); 155 // output all attributes for Element 156 if (domNode.hasAttributes()) { 157 NamedNodeMap attributes = domNode.getAttributes(); 158 for (int onAttribute = 0; onAttribute < attributes.getLength(); onAttribute++) { 159 160 // seprate each attribute with a space 161 result += " "; 162 163 Node attribute = attributes.item(onAttribute); 164 String namespaceURI = attribute.getNamespaceURI(); 165 String prefix = attribute.getPrefix(); 166 String localName = attribute.getLocalName(); 167 String name = attribute.getNodeName(); 168 String value = attribute.getNodeValue(); 169 170 // using Namespaces? 171 if (namespaceURI != null) { 172 result += "{" + namespaceURI + "}"; 173 } 174 if (prefix != null) { 175 result += prefix + ":"; 176 } 177 178 // name="value" 179 result += attribute.getNodeName() + "=\"" + attribute.getNodeValue() + "\""; 180 } 181 } 182 183 break; 184 } 185 case Node.ENTITY_NODE: { 186 result += "[entity] " + domNode.getNodeName(); 187 break; 188 } 189 case Node.ENTITY_REFERENCE_NODE: { 190 result += "[entity reference] " + domNode.getNodeName(); 191 break; 192 } 193 case Node.NOTATION_NODE: { 194 result += "[notation] " + domNode.getNodeName(); 195 break; 196 } 197 case Node.PROCESSING_INSTRUCTION_NODE: { 198 result += "[pi] target=\"" + domNode.getNodeName() + "\" content=\"" + domNode.getNodeValue() + "\""; 199 break; 200 } 201 case Node.TEXT_NODE: { 202 result += "[text] " + domNode.getNodeValue(); 203 break; 204 } 205 default: { 206 result += "[unknown]"; 207 break; 208 } 209 } 210 211 // humans read in lines 212 result += "\n"; 213 214 // process children 215 NodeList children = domNode.getChildNodes(); 216 for (int onChild = 0; onChild < children.getLength(); onChild++) { 217 Node child = children.item(onChild); 218 result += dumpInternal(child, indent); 219 } 220 221 // return human readable DOM as String 222 return result; 223 } 224 225 /** 226 * indentBlanks will return a String of indent blanks 227 * 228 * @param indent 229 * level 230 * @return String of blanks 231 */ 232 private static String indentBlanks(int indent) { 233 if (indent == 0) { 234 return ""; 235 } 236 237 if (indent > BLANKS_LEN) { 238 return BLANKS; 239 } 240 241 return BLANKS.substring(0, indent + 1); 242 } 243 244 } 245 }