1 /*
2  * Copyright (c) 2014, 2017, 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 
24 package transform;
25 
26 import static jaxp.library.JAXPTestUtilities.getSystemProperty;
27 
28 import java.io.ByteArrayInputStream;
29 import java.io.ByteArrayOutputStream;
30 import java.io.IOException;
31 import java.io.StringWriter;
32 
33 import javax.xml.parsers.DocumentBuilderFactory;
34 import javax.xml.parsers.ParserConfigurationException;
35 import javax.xml.parsers.SAXParserFactory;
36 import javax.xml.stream.XMLInputFactory;
37 import javax.xml.stream.XMLStreamException;
38 import javax.xml.transform.Source;
39 import javax.xml.transform.Transformer;
40 import javax.xml.transform.TransformerConfigurationException;
41 import javax.xml.transform.TransformerException;
42 import javax.xml.transform.TransformerFactory;
43 import javax.xml.transform.TransformerFactoryConfigurationError;
44 import javax.xml.transform.dom.DOMResult;
45 import javax.xml.transform.dom.DOMSource;
46 import javax.xml.transform.sax.SAXSource;
47 import javax.xml.transform.stax.StAXSource;
48 import javax.xml.transform.stream.StreamResult;
49 
50 import org.testng.Assert;
51 import org.testng.AssertJUnit;
52 import org.testng.annotations.DataProvider;
53 import org.testng.annotations.Listeners;
54 import org.testng.annotations.Test;
55 import org.w3c.dom.Document;
56 import org.w3c.dom.Element;
57 import org.w3c.dom.Node;
58 import org.w3c.dom.NodeList;
59 import org.xml.sax.ContentHandler;
60 import org.xml.sax.DTDHandler;
61 import org.xml.sax.EntityResolver;
62 import org.xml.sax.ErrorHandler;
63 import org.xml.sax.InputSource;
64 import org.xml.sax.SAXException;
65 import org.xml.sax.SAXNotRecognizedException;
66 import org.xml.sax.SAXNotSupportedException;
67 import org.xml.sax.XMLReader;
68 import org.xml.sax.helpers.AttributesImpl;
69 
70 import transform.util.TransformerTestTemplate;
71 
72 /*
73  * @test
74  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
75  * @run testng/othervm -DrunSecMngr=true transform.TransformerTest
76  * @run testng/othervm transform.TransformerTest
77  * @summary Transformer Tests
78  * @bug 6272879 6305029 6505031 8150704 8162598 8169112 8169631 8169772
79  */
80 @Listeners({jaxp.library.FilePolicy.class})
81 public class TransformerTest {
82 
83     // some global constants
84     private static final String LINE_SEPARATOR =
85         getSystemProperty("line.separator");
86 
87     private static final String NAMESPACES =
88         "http://xml.org/sax/features/namespaces";
89 
90     private static final String NAMESPACE_PREFIXES =
91         "http://xml.org/sax/features/namespace-prefixes";
92 
93     public static class Test6272879 extends TransformerTestTemplate {
94 
95         private static String XSL_INPUT =
96             "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
97             "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR +
98             "<xsl:output method=\"xml\" indent=\"no\" encoding=\"ISO-8859-1\"/>" + LINE_SEPARATOR +
99             "<xsl:template match=\"/\">" + LINE_SEPARATOR +
100             "<xsl:element name=\"TransformateurXML\">" + LINE_SEPARATOR +
101             "  <xsl:for-each select=\"XMLUtils/test\">" + LINE_SEPARATOR +
102             "  <xsl:element name=\"test2\">" + LINE_SEPARATOR +
103             "    <xsl:element name=\"valeur2\">" + LINE_SEPARATOR +
104             "      <xsl:attribute name=\"attribut2\">" + LINE_SEPARATOR +
105             "        <xsl:value-of select=\"valeur/@attribut\"/>" + LINE_SEPARATOR +
106             "      </xsl:attribute>" + LINE_SEPARATOR +
107             "      <xsl:value-of select=\"valeur\"/>" + LINE_SEPARATOR +
108             "    </xsl:element>" + LINE_SEPARATOR +
109             "  </xsl:element>" + LINE_SEPARATOR +
110             "  </xsl:for-each>" + LINE_SEPARATOR +
111             "</xsl:element>" + LINE_SEPARATOR +
112             "</xsl:template>" + LINE_SEPARATOR +
113             "</xsl:stylesheet>";
114 
115         private static String XML_INPUT =
116             "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
117             // "<!DOCTYPE XMLUtils [" + LINE_SEPARATOR +
118             // "<!ELEMENT XMLUtils (test*)>" + LINE_SEPARATOR +
119             // "<!ELEMENT test (valeur*)>" + LINE_SEPARATOR +
120             // "<!ELEMENT valeur (#PCDATA)>" + LINE_SEPARATOR +
121             // "<!ATTLIST valeur attribut CDATA #REQUIRED>]>" +
122             // LINE_SEPARATOR +
123             "<XMLUtils>" + LINE_SEPARATOR +
124             "  <test>" + LINE_SEPARATOR +
125             "    <valeur attribut=\"Attribut 1\">Valeur 1</valeur>" + LINE_SEPARATOR +
126             "  </test>" + LINE_SEPARATOR +
127             "  <test>" + LINE_SEPARATOR +
128             "    <valeur attribut=\"Attribut 2\">Valeur 2</valeur>" + LINE_SEPARATOR +
129             "  </test>" + LINE_SEPARATOR +
130             "</XMLUtils>";
131 
Test6272879()132         public Test6272879() {
133             super(XSL_INPUT, XML_INPUT);
134         }
135 
136         /*
137          * @bug 6272879
138          * @summary Test for JDK-6272879
139          *          DomResult had truncated Strings in some places
140          */
141         @Test
run()142         public void run() throws TransformerException, ClassNotFoundException, InstantiationException,
143             IllegalAccessException, ClassCastException
144         {
145             // print input
146             printSnippet("Stylesheet:", getXsl());
147             printSnippet("Source before transformation:", getSourceXml());
148 
149             // transform to DOM result
150             Transformer t = getTransformer();
151             DOMResult result = new DOMResult();
152             t.transform(getStreamSource(), result);
153 
154             // print output
155             printSnippet("Result after transformation:", prettyPrintDOMResult(result));
156 
157             // do some assertions
158             Document document = (Document)result.getNode();
159             NodeList nodes = document.getElementsByTagName("valeur2");
160             for (int i = 0; i < nodes.getLength(); i++) {
161                 Node node = nodes.item(i);
162                 AssertJUnit.assertEquals("Node value mismatch",
163                                          "Valeur " + (i + 1),
164                                          node.getFirstChild().getNodeValue());
165                 AssertJUnit.assertEquals("Node attribute mismatch",
166                                          "Attribut " + (i + 1),
167                                          node.getAttributes().item(0).getNodeValue());
168             }
169         }
170     }
171 
172     public static class Test6305029 extends TransformerTestTemplate {
173 
174         private static String XML_INPUT =
175             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<prefix:localName xmlns:prefix=\"namespaceUri\"/>";
176 
177         // custom XMLReader representing XML_INPUT
178         private class MyXMLReader implements XMLReader {
179             private boolean namespaces = true;
180             private boolean namespacePrefixes = false;
181             private EntityResolver resolver;
182             private DTDHandler dtdHandler;
183             private ContentHandler contentHandler;
184             private ErrorHandler errorHandler;
185 
getFeature(final String name)186             public boolean getFeature(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
187                 if (name.equals(NAMESPACES)) {
188                     return namespaces;
189                 } else if (name.equals(NAMESPACE_PREFIXES)) {
190                     return namespacePrefixes;
191                 } else {
192                     throw new SAXNotRecognizedException();
193                 }
194             }
195 
setFeature(final String name, final boolean value)196             public void setFeature(final String name, final boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
197                 if (name.equals(NAMESPACES)) {
198                     namespaces = value;
199                 } else if (name.equals(NAMESPACE_PREFIXES)) {
200                     namespacePrefixes = value;
201                 } else {
202                     throw new SAXNotRecognizedException();
203                 }
204             }
205 
getProperty(final String name)206             public Object getProperty(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
207                 return null;
208             }
209 
setProperty(final String name, final Object value)210             public void setProperty(final String name, final Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
211             }
212 
setEntityResolver(final EntityResolver theResolver)213             public void setEntityResolver(final EntityResolver theResolver) {
214                 this.resolver = theResolver;
215             }
216 
getEntityResolver()217             public EntityResolver getEntityResolver() {
218                 return resolver;
219             }
220 
setDTDHandler(final DTDHandler theHandler)221             public void setDTDHandler(final DTDHandler theHandler) {
222                 dtdHandler = theHandler;
223             }
224 
getDTDHandler()225             public DTDHandler getDTDHandler() {
226                 return dtdHandler;
227             }
228 
setContentHandler(final ContentHandler handler)229             public void setContentHandler(final ContentHandler handler) {
230                 contentHandler = handler;
231             }
232 
getContentHandler()233             public ContentHandler getContentHandler() {
234                 return contentHandler;
235             }
236 
setErrorHandler(final ErrorHandler handler)237             public void setErrorHandler(final ErrorHandler handler) {
238                 errorHandler = handler;
239             }
240 
getErrorHandler()241             public ErrorHandler getErrorHandler() {
242                 return errorHandler;
243             }
244 
parse(final InputSource input)245             public void parse(final InputSource input) throws IOException, SAXException {
246                 parse();
247             }
248 
parse(final String systemId)249             public void parse(final String systemId) throws IOException, SAXException {
250                 parse();
251             }
252 
parse()253             private void parse() throws SAXException {
254                 contentHandler.startDocument();
255                 contentHandler.startPrefixMapping("prefix", "namespaceUri");
256 
257                 AttributesImpl atts = new AttributesImpl();
258                 if (namespacePrefixes) {
259                     atts.addAttribute("", "xmlns:prefix", "xmlns:prefix", "CDATA", "namespaceUri");
260                 }
261 
262                 contentHandler.startElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "", atts);
263                 contentHandler.endElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "");
264                 contentHandler.endPrefixMapping("prefix");
265                 contentHandler.endDocument();
266             }
267         }
268 
Test6305029()269         public Test6305029() {
270             super(null, XML_INPUT);
271         }
272 
273         /*
274          * @bug 6305029
275          * @summary Test for JDK-6305029
276          *          Test identity transformation
277          */
278         @Test
run()279         public void run() throws TransformerFactoryConfigurationError, TransformerException {
280             // get Identity transformer
281             Transformer t = getTransformer();
282 
283             // test SAXSource from custom XMLReader
284             SAXSource saxSource = new SAXSource(new MyXMLReader(), new InputSource());
285             StringWriter resultWriter = new StringWriter();
286             t.transform(saxSource, new StreamResult(resultWriter));
287             String resultString = resultWriter.toString();
288             printSnippet("Result after transformation from custom SAXSource:", resultString);
289             AssertJUnit.assertEquals("Identity transform of SAXSource", getSourceXml(), resultString);
290 
291             // test StreamSource
292             printSnippet("Source before transformation of StreamSource:", getSourceXml());
293             resultWriter = new StringWriter();
294             t.transform(getStreamSource(), new StreamResult(resultWriter));
295             resultString = resultWriter.toString();
296             printSnippet("Result after transformation of StreamSource:", resultString);
297             AssertJUnit.assertEquals("Identity transform of StreamSource", getSourceXml(), resultString);
298         }
299     }
300 
301     public static class Test6505031 extends TransformerTestTemplate {
302 
Test6505031()303         public Test6505031() throws IOException {
304             super();
305             setXsl(fromInputStream(getClass().getResourceAsStream("transform.xsl")));
306             setSourceXml(fromInputStream(getClass().getResourceAsStream("template.xml")));
307         }
308 
309         /*
310          * @bug 6505031
311          * @summary Test transformer parses keys and their values coming from different xml documents.
312          */
313         @Test
run()314         public void run() throws TransformerFactoryConfigurationError, TransformerException {
315             Transformer t = getTransformer();
316             t.setParameter("config", getClass().getResource("config.xml").toString());
317             t.setParameter("mapsFile", getClass().getResource("maps.xml").toString());
318             StringWriter resultWriter = new StringWriter();
319             t.transform(getStreamSource(), new StreamResult(resultWriter));
320             String resultString = resultWriter.toString();
321             Assert.assertTrue(resultString.contains("map1key1value") && resultString.contains("map2key1value"));
322         }
323     }
324 
325     public static class Test8169631 extends TransformerTestTemplate {
326 
327         private static String XSL_INPUT =
328             "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
329             "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
330             "  <xsl:template match=\"/\">" + LINE_SEPARATOR +
331             "    <xsl:variable name=\"Counter\" select=\"count(//row)\"/>" + LINE_SEPARATOR +
332             "    <xsl:variable name=\"AttribCounter\" select=\"count(//@attrib)\"/>" + LINE_SEPARATOR +
333             "    <Counter><xsl:value-of select=\"$Counter\"/></Counter>" + LINE_SEPARATOR +
334             "    <AttribCounter><xsl:value-of select=\"$AttribCounter\"/></AttribCounter>" + LINE_SEPARATOR +
335             "  </xsl:template>" + LINE_SEPARATOR +
336             "</xsl:stylesheet>" + LINE_SEPARATOR;
337 
338         private static String XML_INPUT =
339             "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
340             "<envelope xmlns=\"http://www.sap.com/myns\" xmlns:sap=\"http://www.sap.com/myns\">" + LINE_SEPARATOR +
341             "  <sap:row sap:attrib=\"a\">1</sap:row>" + LINE_SEPARATOR +
342             "  <row attrib=\"b\">2</row>" + LINE_SEPARATOR +
343             "  <row sap:attrib=\"c\">3</row>" + LINE_SEPARATOR +
344             "</envelope>" + LINE_SEPARATOR;
345 
Test8169631()346         public Test8169631() {
347             super(XSL_INPUT, XML_INPUT);
348         }
349 
350         /**
351          * Utility method to print out transformation result and check values.
352          *
353          * @param type
354          * Text describing type of transformation
355          * @param result
356          * Resulting output of transformation
357          * @param elementCount
358          * Counter of elements to check
359          * @param attribCount
360          * Counter of attributes to check
361          */
verifyResult(String type, String result, int elementCount, int attribCount)362         private void verifyResult(String type, String result, int elementCount,
363                                   int attribCount)
364         {
365             printSnippet("Result of transformation from " + type + ":",
366                          result);
367             Assert.assertEquals(
368                 result.contains("<Counter>" + elementCount + "</Counter>"),
369                 true, "Result of transformation from " + type +
370                 " should have count of " + elementCount + " elements.");
371             Assert.assertEquals(
372                 result.contains("<AttribCounter>" + attribCount +
373                 "</AttribCounter>"), true, "Result of transformation from " +
374                 type + " should have count of "+ attribCount + " attributes.");
375         }
376 
377         @DataProvider(name = "testdata8169631")
testData()378         public Object[][] testData()
379             throws TransformerConfigurationException, SAXException, IOException,
380             ParserConfigurationException, XMLStreamException
381         {
382             // get Transformers
383             TransformerFactory tf = TransformerFactory.newInstance();
384             Transformer t = getTransformer(tf);
385             Transformer tFromTemplates = getTemplates(tf).newTransformer();
386 
387             // get DOMSource objects
388             DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
389             DOMSource domSourceWithoutNS = getDOMSource(dbf);
390             dbf.setNamespaceAware(true);
391             DOMSource domSourceWithNS = getDOMSource(dbf);
392 
393             // get SAXSource objects
394             SAXParserFactory spf = SAXParserFactory.newInstance();
395             SAXSource saxSourceWithoutNS = getSAXSource(spf);
396             spf.setNamespaceAware(true);
397             SAXSource saxSourceWithNS = getSAXSource(spf);
398 
399             // get StAXSource objects
400             XMLInputFactory xif = XMLInputFactory.newInstance();
401             StAXSource staxSourceWithNS = getStAXSource(xif);
402 
403             // print XML/XSL snippets to ease understanding of result
404             printSnippet("Source:", getSourceXml());
405             printSnippet("Stylesheet:", getXsl());
406 
407             return new Object[][] {
408                 // test StreamSource input with all transformers
409                 // namespace awareness is set by transformer
410                 {t, getStreamSource(), "StreamSource with namespace support", 0, 1},
411                 {tFromTemplates, getStreamSource(), "StreamSource with namespace support using templates", 0, 1},
412                 // now test DOMSource, SAXSource and StAXSource
413                 // with rotating use of created transformers
414                 // namespace awareness is set by source objects
415                 {t, domSourceWithNS, "DOMSource with namespace support", 0, 1},
416                 {t, domSourceWithoutNS, "DOMSource without namespace support", 3, 3},
417                 {tFromTemplates, saxSourceWithNS, "SAXSource with namespace support", 0, 1},
418                 {tFromTemplates, saxSourceWithoutNS, "SAXSource without namespace support", 3, 3},
419                 {t, staxSourceWithNS, "StAXSource with namespace support", 0, 1}
420             };
421         }
422 
423         /*
424          * @bug 8169631
425          * @summary Test combinations of namespace awareness settings on
426          *          XSL transformations
427          */
428         @Test(dataProvider = "testdata8169631")
run(Transformer t, Source s, String label, int elementcount, int attributecount)429         public void run(Transformer t, Source s, String label, int elementcount, int attributecount)
430             throws TransformerException
431         {
432             ByteArrayOutputStream baos = new ByteArrayOutputStream();
433             t.transform(s, new StreamResult(baos));
434             verifyResult(label, baos.toString(), elementcount, attributecount);
435         }
436     }
437 
438     public static class Test8150704 extends TransformerTestTemplate {
439 
Test8150704()440         public Test8150704() {
441             super();
442         }
443 
444         @DataProvider(name = "testdata8150704")
testData()445         public Object[][] testData() {
446             return new Object[][] {
447                 {"Bug8150704-1.xsl", "Bug8150704-1.xml", "Bug8150704-1.ref"},
448                 {"Bug8150704-2.xsl", "Bug8150704-2.xml", "Bug8150704-2.ref"}
449             };
450         }
451 
452         /*
453          * @bug 8150704
454          * @summary Test that XSL transformation with lots of temporary result
455          *          trees will not run out of DTM IDs.
456          */
457         @Test(dataProvider = "testdata8150704")
run(String xsl, String xml, String ref)458         public void run(String xsl, String xml, String ref) throws IOException, TransformerException {
459             System.out.println("Testing transformation of " + xml + "...");
460             setXsl(fromInputStream(getClass().getResourceAsStream(xsl)));
461             setSourceXml(fromInputStream(getClass().getResourceAsStream(xml)));
462             Transformer t = getTransformer();
463             StringWriter resultWriter = new StringWriter();
464             t.transform(getStreamSource(), new StreamResult(resultWriter));
465             String resultString = resultWriter.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n").trim();
466             String reference = fromInputStream(getClass().getResourceAsStream(ref)).trim();
467             Assert.assertEquals(resultString, reference, "Output of transformation of " + xml + " does not match reference");
468             System.out.println("Passed.");
469         }
470     }
471 
472     public static class Test8162598 extends TransformerTestTemplate {
473 
474         private static String XSL_INPUT =
475             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + LINE_SEPARATOR +
476             "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
477             "    <xsl:template match=\"/\">" + LINE_SEPARATOR +
478             "        <root xmlns=\"ns1\">" + LINE_SEPARATOR +
479             "            <xsl:call-template name=\"transform\"/>" + LINE_SEPARATOR +
480             "        </root>" + LINE_SEPARATOR +
481             "    </xsl:template>" + LINE_SEPARATOR +
482             "    <xsl:template name=\"transform\">" + LINE_SEPARATOR +
483             "        <test1 xmlns=\"ns2\"><b xmlns=\"ns2\"><c xmlns=\"\"></c></b></test1>" + LINE_SEPARATOR +
484             "        <test2 xmlns=\"ns1\"><b xmlns=\"ns2\"><c xmlns=\"\"></c></b></test2>" + LINE_SEPARATOR +
485             "        <test3><b><c xmlns=\"\"></c></b></test3>" + LINE_SEPARATOR +
486             "        <test4 xmlns=\"\"><b><c xmlns=\"\"></c></b></test4>" + LINE_SEPARATOR +
487             "        <test5 xmlns=\"ns1\"><b><c xmlns=\"\"></c></b></test5>" + LINE_SEPARATOR +
488             "        <test6 xmlns=\"\"/>" + LINE_SEPARATOR +
489             "    </xsl:template>" + LINE_SEPARATOR +
490             "</xsl:stylesheet>";
491 
492         private static String XML_INPUT =
493             "<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
494 
Test8162598()495         public Test8162598() {
496             super(XSL_INPUT, XML_INPUT);
497         }
498 
499         /**
500          * Utility method for testBug8162598().
501          * Provides a convenient way to check/assert the expected namespaces
502          * of a Node and its siblings.
503          *
504          * @param test
505          * The node to check
506          * @param nstest
507          * Expected namespace of the node
508          * @param nsb
509          * Expected namespace of the first sibling
510          * @param nsc
511          * Expected namespace of the first sibling of the first sibling
512          */
checkNodeNS(Node test, String nstest, String nsb, String nsc)513         private void checkNodeNS(Node test, String nstest, String nsb, String nsc) {
514             String testNodeName = test.getNodeName();
515             if (nstest == null) {
516                 Assert.assertNull(test.getNamespaceURI(), "unexpected namespace for " + testNodeName);
517             } else {
518                 Assert.assertEquals(test.getNamespaceURI(), nstest, "unexpected namespace for " + testNodeName);
519             }
520             Node b = test.getChildNodes().item(0);
521             if (nsb == null) {
522                 Assert.assertNull(b.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b");
523             } else {
524                 Assert.assertEquals(b.getNamespaceURI(), nsb, "unexpected namespace for " + testNodeName + "->b");
525             }
526             Node c = b.getChildNodes().item(0);
527             if (nsc == null) {
528                 Assert.assertNull(c.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b->c");
529             } else {
530                 Assert.assertEquals(c.getNamespaceURI(), nsc, "unexpected namespace for " + testNodeName + "->b->c");
531             }
532         }
533 
534         /*
535          * @bug 8162598
536          * @summary Test XSLTC handling of namespaces, especially empty namespace
537          *          definitions to reset the default namespace
538          */
539         @Test
run()540         public void run()  throws Exception {
541             // print input
542             printSnippet("Source:", getSourceXml());
543             printSnippet("Stylesheet:", getXsl());
544 
545             // transform to DOM result
546             Transformer t = getTransformer();
547             DOMResult result = new DOMResult();
548             t.transform(getStreamSource(), result);
549 
550             // print output
551             printSnippet("Result after transformation:", prettyPrintDOMResult(result));
552 
553             // do some verifications
554             Document document = (Document)result.getNode();
555             checkNodeNS(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
556             checkNodeNS(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
557             checkNodeNS(document.getElementsByTagName("test3").item(0), null, null, null);
558             checkNodeNS(document.getElementsByTagName("test4").item(0), null, null, null);
559             checkNodeNS(document.getElementsByTagName("test5").item(0), "ns1", "ns1", null);
560             Assert.assertNull(document.getElementsByTagName("test6").item(0).getNamespaceURI(),
561                 "unexpected namespace for test6");
562         }
563     }
564 
565     public static class Test8169112 extends TransformerTestTemplate{
566 
567         public static String XML_INPUT =
568             "<?xml version=\"1.0\"?><DOCROOT/>";
569 
Test8169112()570         public Test8169112() throws IOException {
571             super();
572             setXsl(fromInputStream(getClass().getResourceAsStream("Bug8169112.xsl")));
573             setSourceXml(XML_INPUT);
574         }
575 
576         /**
577          * @throws TransformerException
578          * @bug 8169112
579          * @summary Test compilation of large xsl file with outlining.
580          *
581          * This test merely compiles a large xsl file and tests if its bytecode
582          * passes verification by invoking the transform() method for
583          * dummy content. The test succeeds if no Exception is thrown
584          */
585         @Test
run()586         public void run() throws TransformerException {
587             Transformer t = getTransformer();
588             t.transform(getStreamSource(), new StreamResult(new ByteArrayOutputStream()));
589         }
590     }
591 
592     public static class Test8169772 extends TransformerTestTemplate {
593 
Test8169772()594         public Test8169772() {
595             super();
596         }
597 
getDOMWithBadElement()598         private Document getDOMWithBadElement() throws SAXException, IOException, ParserConfigurationException {
599             // create a small DOM
600             Document doc = DocumentBuilderFactory.newInstance().
601                 newDocumentBuilder().parse(
602                     new ByteArrayInputStream(
603                         "<?xml version=\"1.0\"?><DOCROOT/>".getBytes()
604                     )
605                 );
606 
607             // insert a bad element
608             Element e = doc.createElement("ERROR");
609             e.appendChild(doc.createTextNode(null));
610             doc.getDocumentElement().appendChild(e);
611 
612             return doc;
613         }
614 
615         /**
616          * @throws ParserConfigurationException
617          * @throws IOException
618          * @throws SAXException
619          * @throws TransformerException
620          * @bug 8169772
621          * @summary Test transformation of DOM with null valued text node
622          *
623          * This test would throw a NullPointerException during transform when the
624          * fix was not present.
625          */
626         @Test
run()627         public void run() throws SAXException, IOException, ParserConfigurationException, TransformerException {
628             Transformer t = getTransformer();
629             StringWriter resultWriter = new StringWriter();
630             DOMSource d = new DOMSource(getDOMWithBadElement().getDocumentElement());
631             t.transform(d, new StreamResult(resultWriter));
632             printSnippet("Transformation result (DOM with null text node):", resultWriter.toString());
633         }
634     }
635 }
636