Bug4858685.java revision 968:874082a9b565
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 */
23package test.gaptest;
24
25import static jaxp.library.JAXPTestUtilities.filenameToURL;
26import static org.testng.Assert.assertEquals;
27import static test.gaptest.GapTestConst.GOLDEN_DIR;
28import static test.gaptest.GapTestConst.XML_DIR;
29
30import java.io.IOException;
31import java.nio.file.Files;
32import java.nio.file.Paths;
33
34import javax.xml.transform.Transformer;
35import javax.xml.transform.TransformerException;
36import javax.xml.transform.TransformerFactory;
37import javax.xml.transform.dom.DOMResult;
38import javax.xml.transform.stream.StreamSource;
39
40import org.testng.annotations.Listeners;
41import org.testng.annotations.Test;
42import org.w3c.dom.NamedNodeMap;
43import org.w3c.dom.Node;
44import org.w3c.dom.NodeList;
45
46/*
47 * @test
48 * @bug 4858685 4894410
49 * @library /javax/xml/jaxp/libs
50 * @run testng/othervm -DrunSecMngr=true test.gaptest.Bug4858685
51 * @run testng/othervm test.gaptest.Bug4858685
52 * @summary test transforming text node
53 */
54@Listeners({jaxp.library.FilePolicy.class})
55public class Bug4858685 {
56    @Test
57    public void test() throws TransformerException, IOException {
58        String uri = XML_DIR + "certificate.xml";
59        TransformerFactory transformerFactory = TransformerFactory.newInstance();
60
61        Transformer transformer = transformerFactory.newTransformer();
62
63        // use URI as a StreamSource
64        StreamSource streamSource = new StreamSource(filenameToURL(uri));
65
66        DOMResult domResult = new DOMResult();
67
68        // StreamSource -> DOMResult
69        transformer.transform(streamSource, domResult);
70
71        // dump DOM in a human readable form
72        String gotString = DOMDump.dumpDom(domResult.getNode());
73
74        String goldenString = new String(Files.readAllBytes(Paths.get(GOLDEN_DIR + "Bug4858685.txt")));
75
76        assertEquals(gotString, goldenString);
77
78    }
79
80    /**
81     * DOMDump: dump a DOM to a String in human readable form. method dumpDOM()
82     * is static for easy calling:
83     */
84    private static class DOMDump {
85
86        /**
87         * the maximum level to indent with blanks
88         */
89        private static final int BLANKS_LEN = 64;
90
91        /**
92         * each level of the tree will be indented with blanks for readability
93         */
94        private static final String BLANKS = "                                                              ";
95
96        /**
97         * dumpDOM will dump the DOM into a String for human readability
98         *
99         * @param domNode
100         *            the DOM Node to dump
101         * @return human readabile DOM as a String
102         */
103        public static String dumpDom(Node domNode) {
104            return dumpInternal(domNode, 0);
105        }
106
107        /**
108         * dumpInternal is used internaly to recursively dump DOM Nodes
109         *
110         * @param domNode
111         *            to dump
112         * @param indent
113         *            level
114         * @return domNode as human readable String
115         */
116        private static String dumpInternal(Node domNode, int indent) {
117
118            String result = "";
119
120            // indent for readability
121            result += indentBlanks(indent);
122            indent += 2;
123
124            // protect against null
125            if (domNode == null) {
126                result = result + "[null]" + "\n";
127                return result;
128            }
129
130            // what to output depends on NodeType
131            short type = domNode.getNodeType();
132            switch (type) {
133                case Node.ATTRIBUTE_NODE: {
134                    result += "[attribute] " + domNode.getNodeName() + "=\"" + domNode.getNodeValue() + "\"";
135                    break;
136                }
137                case Node.CDATA_SECTION_NODE: {
138                    result += "[cdata] " + domNode.getNodeValue();
139                    break;
140                }
141                case Node.COMMENT_NODE: {
142                    result += "[comment] " + domNode.getNodeValue();
143                    break;
144                }
145                case Node.DOCUMENT_FRAGMENT_NODE: {
146                    result += "[document fragment]";
147                    break;
148                }
149                case Node.DOCUMENT_NODE: {
150                    result += "[document]";
151                    break;
152                }
153                case Node.DOCUMENT_TYPE_NODE: {
154                    result += "[document type] " + domNode.getNodeName();
155                    break;
156                }
157                case Node.ELEMENT_NODE: {
158                    result += "[element] " + domNode.getNodeName();
159                    // output all attributes for Element
160                    if (domNode.hasAttributes()) {
161                        NamedNodeMap attributes = domNode.getAttributes();
162                        for (int onAttribute = 0; onAttribute < attributes.getLength(); onAttribute++) {
163
164                            // seprate each attribute with a space
165                            result += " ";
166
167                            Node attribute = attributes.item(onAttribute);
168                            String namespaceURI = attribute.getNamespaceURI();
169                            String prefix = attribute.getPrefix();
170                            String localName = attribute.getLocalName();
171                            String name = attribute.getNodeName();
172                            String value = attribute.getNodeValue();
173
174                            // using Namespaces?
175                            if (namespaceURI != null) {
176                                result += "{" + namespaceURI + "}";
177                            }
178                            if (prefix != null) {
179                                result += prefix + ":";
180                            }
181
182                            // name="value"
183                            result += attribute.getNodeName() + "=\"" + attribute.getNodeValue() + "\"";
184                        }
185                    }
186
187                    break;
188                }
189                case Node.ENTITY_NODE: {
190                    result += "[entity] " + domNode.getNodeName();
191                    break;
192                }
193                case Node.ENTITY_REFERENCE_NODE: {
194                    result += "[entity reference] " + domNode.getNodeName();
195                    break;
196                }
197                case Node.NOTATION_NODE: {
198                    result += "[notation] " + domNode.getNodeName();
199                    break;
200                }
201                case Node.PROCESSING_INSTRUCTION_NODE: {
202                    result += "[pi] target=\"" + domNode.getNodeName() + "\" content=\"" + domNode.getNodeValue() + "\"";
203                    break;
204                }
205                case Node.TEXT_NODE: {
206                    result += "[text] " + domNode.getNodeValue();
207                    break;
208                }
209                default: {
210                    result += "[unknown]";
211                    break;
212                }
213            }
214
215            // humans read in lines
216            result += "\n";
217
218            // process children
219            NodeList children = domNode.getChildNodes();
220            for (int onChild = 0; onChild < children.getLength(); onChild++) {
221                Node child = children.item(onChild);
222                result += dumpInternal(child, indent);
223            }
224
225            // return human readable DOM as String
226            return result;
227        }
228
229        /**
230         * indentBlanks will return a String of indent blanks
231         *
232         * @param indent
233         *            level
234         * @return String of blanks
235         */
236        private static String indentBlanks(int indent) {
237            if (indent == 0) {
238                return "";
239            }
240
241            if (indent > BLANKS_LEN) {
242                return BLANKS;
243            }
244
245            return BLANKS.substring(0, indent + 1);
246        }
247
248    }
249}
250
251