1 /*
   2  * Copyright (c) 2014, 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 
  24 package transform;
  25 
  26 import static jaxp.library.JAXPTestUtilities.getSystemProperty;
  27 
  28 import java.io.BufferedReader;
  29 import java.io.ByteArrayInputStream;
  30 import java.io.ByteArrayOutputStream;
  31 import java.io.File;
  32 import java.io.FileReader;
  33 import java.io.IOException;
  34 import java.io.StringReader;
  35 import java.io.StringWriter;
  36 
  37 import javax.xml.parsers.DocumentBuilderFactory;
  38 import javax.xml.parsers.ParserConfigurationException;
  39 import javax.xml.parsers.SAXParserFactory;
  40 import javax.xml.transform.Transformer;
  41 import javax.xml.transform.TransformerException;
  42 import javax.xml.transform.TransformerFactory;
  43 import javax.xml.transform.dom.DOMResult;
  44 import javax.xml.transform.dom.DOMSource;
  45 import javax.xml.transform.sax.SAXSource;
  46 import javax.xml.transform.stream.StreamResult;
  47 import javax.xml.transform.stream.StreamSource;
  48 
  49 import org.testng.Assert;
  50 import org.testng.AssertJUnit;
  51 import org.testng.annotations.Listeners;
  52 import org.testng.annotations.Test;
  53 import org.w3c.dom.Document;
  54 import org.w3c.dom.Node;
  55 import org.w3c.dom.NodeList;
  56 import org.xml.sax.ContentHandler;
  57 import org.xml.sax.DTDHandler;
  58 import org.xml.sax.EntityResolver;
  59 import org.xml.sax.ErrorHandler;
  60 import org.xml.sax.InputSource;
  61 import org.xml.sax.SAXException;
  62 import org.xml.sax.SAXNotRecognizedException;
  63 import org.xml.sax.SAXNotSupportedException;
  64 import org.xml.sax.XMLReader;
  65 import org.xml.sax.helpers.AttributesImpl;
  66 
  67 import com.sun.org.apache.xml.internal.serialize.OutputFormat;
  68 import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
  69 
  70 /*
  71  * @test
  72  * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
  73  * @run testng/othervm -DrunSecMngr=true transform.TransformerTest
  74  * @run testng/othervm transform.TransformerTest
  75  * @summary Transformer Tests
  76  * @bug 6272879 6305029 6505031 8023653 8150704 8162598 8169631
  77  */
  78 @Listeners({jaxp.library.FilePolicy.class})
  79 public class TransformerTest {
  80     private static final String NAMESPACES = "http://xml.org/sax/features/namespaces";
  81     private static final String NAMESPACE_PREFIXES = "http://xml.org/sax/features/namespace-prefixes";
  82 
  83     /*
  84     private StringWriter transformResourceToStringWriter(Transformer transformer, String xmlResource) throws TransformerException {
  85         StringWriter sw = new StringWriter();
  86         transformer.transform(new StreamSource(getClass().getResource(xmlResource).toString()), new StreamResult(sw));
  87         return sw;
  88     }
  89 */
  90     /**
  91      * Reads the contents of the given file into a string.
  92      * WARNING: this method adds a final line feed even if the last line of the file doesn't contain one.
  93      *
  94      * @param f
  95      * The file to read
  96      * @return The content of the file as a string, with line terminators as \"n"
  97      * for all platforms
  98      * @throws IOException
  99      * If there was an error reading
 100      */
 101     private String getFileContentAsString(File f) throws IOException {
 102         try (BufferedReader reader = new BufferedReader(new FileReader(f))) {
 103             String line;
 104             StringBuilder sb = new StringBuilder();
 105             while ((line = reader.readLine()) != null) {
 106                 sb.append(line).append("\n");
 107             }
 108             return sb.toString();
 109         }
 110     }
 111 
 112     /**
 113      * Utility method for testBug8162598().
 114      * Provides a convenient way to check/assert the expected namespaces
 115      * of a Node and its siblings.
 116      *
 117      * @param test
 118      * The node to check
 119      * @param nstest
 120      * Expected namespace of the node
 121      * @param nsb
 122      * Expected namespace of the first sibling
 123      * @param nsc
 124      * Expected namespace of the first sibling of the first sibling
 125      */
 126     private void checkNodeNS8162598(Node test, String nstest, String nsb, String nsc) {
 127         String testNodeName = test.getNodeName();
 128         if (nstest == null) {
 129             Assert.assertNull(test.getNamespaceURI(), "unexpected namespace for " + testNodeName);
 130         } else {
 131             Assert.assertEquals(test.getNamespaceURI(), nstest, "unexpected namespace for " + testNodeName);
 132         }
 133         Node b = test.getChildNodes().item(0);
 134         if (nsb == null) {
 135             Assert.assertNull(b.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b");
 136         } else {
 137             Assert.assertEquals(b.getNamespaceURI(), nsb, "unexpected namespace for " + testNodeName + "->b");
 138         }
 139         Node c = b.getChildNodes().item(0);
 140         if (nsc == null) {
 141             Assert.assertNull(c.getNamespaceURI(), "unexpected namespace for " + testNodeName + "->b->c");
 142         } else {
 143             Assert.assertEquals(c.getNamespaceURI(), nsc, "unexpected namespace for " + testNodeName + "->b->c");
 144         }
 145     }
 146 
 147     private class XMLReaderFor6305029 implements XMLReader {
 148         private boolean namespaces = true;
 149         private boolean namespacePrefixes = false;
 150         private EntityResolver resolver;
 151         private DTDHandler dtdHandler;
 152         private ContentHandler contentHandler;
 153         private ErrorHandler errorHandler;
 154 
 155         public boolean getFeature(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
 156             if (name.equals(NAMESPACES)) {
 157                 return namespaces;
 158             } else if (name.equals(NAMESPACE_PREFIXES)) {
 159                 return namespacePrefixes;
 160             } else {
 161                 throw new SAXNotRecognizedException();
 162             }
 163         }
 164 
 165         public void setFeature(final String name, final boolean value) throws SAXNotRecognizedException, SAXNotSupportedException {
 166             if (name.equals(NAMESPACES)) {
 167                 namespaces = value;
 168             } else if (name.equals(NAMESPACE_PREFIXES)) {
 169                 namespacePrefixes = value;
 170             } else {
 171                 throw new SAXNotRecognizedException();
 172             }
 173         }
 174 
 175         public Object getProperty(final String name) throws SAXNotRecognizedException, SAXNotSupportedException {
 176             return null;
 177         }
 178 
 179         public void setProperty(final String name, final Object value) throws SAXNotRecognizedException, SAXNotSupportedException {
 180         }
 181 
 182         public void setEntityResolver(final EntityResolver theResolver) {
 183             this.resolver = theResolver;
 184         }
 185 
 186         public EntityResolver getEntityResolver() {
 187             return resolver;
 188         }
 189 
 190         public void setDTDHandler(final DTDHandler theHandler) {
 191             dtdHandler = theHandler;
 192         }
 193 
 194         public DTDHandler getDTDHandler() {
 195             return dtdHandler;
 196         }
 197 
 198         public void setContentHandler(final ContentHandler handler) {
 199             contentHandler = handler;
 200         }
 201 
 202         public ContentHandler getContentHandler() {
 203             return contentHandler;
 204         }
 205 
 206         public void setErrorHandler(final ErrorHandler handler) {
 207             errorHandler = handler;
 208         }
 209 
 210         public ErrorHandler getErrorHandler() {
 211             return errorHandler;
 212         }
 213 
 214         public void parse(final InputSource input) throws IOException, SAXException {
 215             parse();
 216         }
 217 
 218         public void parse(final String systemId) throws IOException, SAXException {
 219             parse();
 220         }
 221 
 222         private void parse() throws SAXException {
 223             contentHandler.startDocument();
 224             contentHandler.startPrefixMapping("prefix", "namespaceUri");
 225 
 226             AttributesImpl atts = new AttributesImpl();
 227             if (namespacePrefixes) {
 228                 atts.addAttribute("", "xmlns:prefix", "xmlns:prefix", "CDATA", "namespaceUri");
 229             }
 230 
 231             contentHandler.startElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "", atts);
 232             contentHandler.endElement("namespaceUri", "localName", namespacePrefixes ? "prefix:localName" : "");
 233             contentHandler.endPrefixMapping("prefix");
 234             contentHandler.endDocument();
 235         }
 236     }
 237 
 238     /*
 239      * @bug 6272879
 240      * @summary Test for JDK-6272879
 241      */
 242     @Test
 243     public final void testBug6272879() throws IOException, TransformerException {
 244         final String LINE_SEPARATOR = getSystemProperty("line.separator");
 245 
 246         final String xsl =
 247                 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
 248                 "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" + LINE_SEPARATOR +
 249                 "<xsl:output method=\"xml\" indent=\"no\" encoding=\"ISO-8859-1\"/>" + LINE_SEPARATOR +
 250                 "<xsl:template match=\"/\">" + LINE_SEPARATOR +
 251                 "<xsl:element name=\"TransformateurXML\">" + LINE_SEPARATOR +
 252                 "  <xsl:for-each select=\"XMLUtils/test\">" + LINE_SEPARATOR +
 253                 "  <xsl:element name=\"test2\">" + LINE_SEPARATOR +
 254                 "    <xsl:element name=\"valeur2\">" + LINE_SEPARATOR +
 255                 "      <xsl:attribute name=\"attribut2\">" + LINE_SEPARATOR +
 256                 "        <xsl:value-of select=\"valeur/@attribut\"/>" + LINE_SEPARATOR +
 257                 "      </xsl:attribute>" + LINE_SEPARATOR +
 258                 "      <xsl:value-of select=\"valeur\"/>" + LINE_SEPARATOR +
 259                 "    </xsl:element>" + LINE_SEPARATOR +
 260                 "  </xsl:element>" + LINE_SEPARATOR +
 261                 "  </xsl:for-each>" + LINE_SEPARATOR +
 262                 "</xsl:element>" + LINE_SEPARATOR +
 263                 "</xsl:template>" + LINE_SEPARATOR +
 264                 "</xsl:stylesheet>";
 265 
 266         final String sourceXml =
 267                 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>" + LINE_SEPARATOR +
 268                 // "<!DOCTYPE XMLUtils [" + LINE_SEPARATOR +
 269                 // "<!ELEMENT XMLUtils (test*)>" + LINE_SEPARATOR +
 270                 // "<!ELEMENT test (valeur*)>" + LINE_SEPARATOR +
 271                 // "<!ELEMENT valeur (#PCDATA)>" + LINE_SEPARATOR +
 272                 // "<!ATTLIST valeur attribut CDATA #REQUIRED>]>" +
 273                 // LINE_SEPARATOR +
 274                 "<XMLUtils>" + LINE_SEPARATOR +
 275                 "  <test>" + LINE_SEPARATOR +
 276                 "    <valeur attribut=\"Attribut 1\">Valeur 1</valeur>" + LINE_SEPARATOR +
 277                 "  </test>" + LINE_SEPARATOR +
 278                 "  <test>" + LINE_SEPARATOR +
 279                 "    <valeur attribut=\"Attribut 2\">Valeur 2</valeur>" + LINE_SEPARATOR +
 280                 "  </test>" + LINE_SEPARATOR +
 281                 "</XMLUtils>";
 282 
 283         System.out.println("Stylesheet:");
 284         System.out.println("=============================");
 285         System.out.println(xsl);
 286         System.out.println();
 287 
 288         System.out.println("Source before transformation:");
 289         System.out.println("=============================");
 290         System.out.println(sourceXml);
 291         System.out.println();
 292 
 293         // transform to DOM result
 294         TransformerFactory tf = TransformerFactory.newInstance();
 295         Transformer t = tf.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
 296         DOMResult result = new DOMResult();
 297         t.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())), result);
 298         Document document = (Document)result.getNode();
 299 
 300         System.out.println("Result after transformation:");
 301         System.out.println("============================");
 302         OutputFormat format = new OutputFormat();
 303         format.setIndenting(true);
 304         new XMLSerializer(System.out, format).serialize(document);
 305         System.out.println();
 306 
 307         System.out.println("Node content for element valeur2:");
 308         System.out.println("=================================");
 309         NodeList nodes = document.getElementsByTagName("valeur2");
 310         for (int i = 0; i < nodes.getLength(); i++) {
 311             Node node = nodes.item(i);
 312             System.out.println("  Node value: " + node.getFirstChild().getNodeValue());
 313             System.out.println("  Node attribute: " + node.getAttributes().item(0).getNodeValue());
 314 
 315             AssertJUnit.assertEquals("Node value mismatch", "Valeur " + (i + 1), node.getFirstChild().getNodeValue());
 316             AssertJUnit.assertEquals("Node attribute mismatch", "Attribut " + (i + 1), node.getAttributes().item(0).getNodeValue());
 317         }
 318     }
 319 
 320     /*
 321      * @bug 6305029
 322      * @summary Test for JDK-6305029
 323      */
 324     @Test
 325     public final void testBug6305029() throws TransformerException {
 326         final String XML_DOCUMENT = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<prefix:localName xmlns:prefix=\"namespaceUri\"/>";
 327 
 328         // test SAXSource
 329         SAXSource saxSource = new SAXSource(new XMLReaderFor6305029(), new InputSource());
 330         StringWriter resultWriter = new StringWriter();
 331         TransformerFactory tf = TransformerFactory.newInstance();
 332         tf.newTransformer().transform(saxSource, new StreamResult(resultWriter));
 333         AssertJUnit.assertEquals("Identity transform of SAXSource", XML_DOCUMENT, resultWriter.toString());
 334 
 335         // test StreamSource
 336         StreamSource streamSource = new StreamSource(new StringReader(XML_DOCUMENT));
 337         resultWriter = new StringWriter();
 338         tf.newTransformer().transform(streamSource, new StreamResult(resultWriter));
 339         AssertJUnit.assertEquals("Identity transform of StreamSource", XML_DOCUMENT, resultWriter.toString());
 340     }
 341 
 342     /*
 343      * @bug 6505031
 344      * @summary Test transformer parses keys and their values coming from different xml documents.
 345      */
 346     @Test
 347     public final void testBug6505031() throws TransformerException {
 348         TransformerFactory tf = TransformerFactory.newInstance();
 349         Transformer t = tf.newTransformer(new StreamSource(getClass().getResource("transform.xsl").toString()));
 350         t.setParameter("config", getClass().getResource("config.xml").toString());
 351         t.setParameter("mapsFile", getClass().getResource("maps.xml").toString());
 352         StringWriter sw = new StringWriter();
 353         t.transform(new StreamSource(getClass().getResource("template.xml").toString()), new StreamResult(sw));
 354         String s = sw.toString();
 355         Assert.assertTrue(s.contains("map1key1value") && s.contains("map2key1value"));
 356     }
 357 
 358     /*
 359      * @bug 8023653 8169631
 360      * @summary Test combinations of namespace awareness settings on XSL transformations
 361      */
 362     @Test
 363     public final void testBug8023653And8169631() throws IOException, TransformerException, SAXException, ParserConfigurationException {
 364         final String LINE_SEPARATOR = getSystemProperty("line.separator");
 365 
 366         final String xsl =
 367             "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
 368             "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
 369             "  <xsl:template match=\"/\">" + LINE_SEPARATOR +
 370             "    <xsl:variable name=\"Counter\" select=\"count(//row)\"/>" + LINE_SEPARATOR +
 371             "    <Counter><xsl:value-of select=\"$Counter\"/></Counter>" + LINE_SEPARATOR +
 372             "  </xsl:template>" + LINE_SEPARATOR +
 373             "</xsl:stylesheet>" + LINE_SEPARATOR;
 374 
 375         final String sourceXml =
 376                 "<?xml version=\"1.0\"?>" + LINE_SEPARATOR +
 377                 "<envelope xmlns=\"http://www.sap.com/myns\">" + LINE_SEPARATOR +
 378                 "  <row>1</row>" + LINE_SEPARATOR +
 379                 "  <row>2</row>" + LINE_SEPARATOR +
 380                 "  <row>3</row>" + LINE_SEPARATOR +
 381                 "</envelope>" + LINE_SEPARATOR;
 382 
 383         System.out.println("Stylesheet:");
 384         System.out.println("=============================");
 385         System.out.println(xsl);
 386         System.out.println();
 387 
 388         System.out.println("Source before transformation:");
 389         System.out.println("=============================");
 390         System.out.println(sourceXml);
 391         System.out.println();
 392 
 393         // create default transformer (namespace aware)
 394         TransformerFactory tf1 = TransformerFactory.newInstance();
 395         Transformer t1 = tf1.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
 396 
 397         // create transformer with namespaces feature set to false
 398         TransformerFactory tf2 = TransformerFactory.newInstance();
 399         tf2.setFeature(NAMESPACES, false);
 400         Transformer t2 = tf2.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
 401 
 402         // test transformation from stream source with namespace support
 403         ByteArrayOutputStream baos = new ByteArrayOutputStream();
 404         t1.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())),
 405                     new StreamResult(baos));
 406         String resFromStream = baos.toString();
 407 
 408         // test transformation from stream source without namespace support
 409         baos.reset();
 410         t2.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())),
 411                     new StreamResult(baos));
 412         String resFromStreamWONS = baos.toString();
 413 
 414         // now use transformers vice versa
 415 
 416         // test transformation from DOM source with namespace support
 417         baos.reset();
 418         DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
 419         dbf.setNamespaceAware(true);
 420         Document doc = dbf.newDocumentBuilder().parse(new InputSource(new ByteArrayInputStream(sourceXml.getBytes())));
 421         t2.transform(new DOMSource(doc), new StreamResult(baos));
 422         String resFromDOM = baos.toString();
 423 
 424         // test transformation from DOM source without namespace support
 425         baos.reset();
 426         dbf.setNamespaceAware(false);
 427         doc = dbf.newDocumentBuilder().parse(new InputSource(new ByteArrayInputStream(sourceXml.getBytes())));
 428         t1.transform(new DOMSource(doc), new StreamResult(baos));
 429         String resFromDOMWONS = baos.toString();
 430 
 431         // test transformation from SAX source with namespace support
 432         baos.reset();
 433         SAXParserFactory spf = SAXParserFactory.newInstance();
 434         spf.setNamespaceAware(true);
 435         XMLReader xmlr = spf.newSAXParser().getXMLReader();
 436         t2.transform(new SAXSource(xmlr, new InputSource(new ByteArrayInputStream(sourceXml.getBytes()))), new StreamResult(baos));
 437         String resFromSAX = baos.toString();
 438 
 439         // test transformation from SAX source without namespace support
 440         baos.reset();
 441         spf.setNamespaceAware(false);
 442         xmlr = spf.newSAXParser().getXMLReader();
 443         t1.transform(new SAXSource(xmlr, new InputSource(new ByteArrayInputStream(sourceXml.getBytes()))), new StreamResult(baos));
 444         String resFromSAXWONS = baos.toString();
 445 
 446         System.out.println("Result after transformation from StreamSource with namespace support:");
 447         System.out.println("=====================================================================");
 448         System.out.println(resFromStream);
 449         System.out.println();
 450 
 451         System.out.println("Result after transformation from StreamSource without namespace support:");
 452         System.out.println("========================================================================");
 453         System.out.println(resFromStreamWONS);
 454         System.out.println();
 455 
 456         System.out.println("Result after transformation from DOMSource with namespace support:");
 457         System.out.println("==================================================================");
 458         System.out.println(resFromDOM);
 459         System.out.println();
 460 
 461         System.out.println("Result after transformation from DOMSource without namespace support:");
 462         System.out.println("=====================================================================");
 463         System.out.println(resFromDOMWONS);
 464         System.out.println();
 465 
 466         System.out.println("Result after transformation from SAXSource with namespace support:");
 467         System.out.println("==================================================================");
 468         System.out.println(resFromSAX);
 469         System.out.println();
 470 
 471         System.out.println("Result after transformation from SAXSource without namespace support:");
 472         System.out.println("=====================================================================");
 473         System.out.println(resFromSAXWONS);
 474         System.out.println();
 475 
 476         Assert.assertEquals(resFromStream.contains("<Counter>0</Counter>"), true,
 477                             "Output from Stream with namespace support should count 0");
 478         Assert.assertEquals(resFromStreamWONS.contains("<Counter>3</Counter>"), true,
 479                             "Output from Stream without namespace support should count 3");
 480         Assert.assertEquals(resFromDOM.contains("<Counter>0</Counter>"), true,
 481                             "Output from DOM with namespace support should count 0");
 482         Assert.assertEquals(resFromDOMWONS.contains("<Counter>3</Counter>"), true,
 483                             "Output from DOM without namespace support should count 3");
 484         Assert.assertEquals(resFromSAX.contains("<Counter>0</Counter>"), true,
 485                             "Output from SAX with namespace support should count 0");
 486         Assert.assertEquals(resFromSAXWONS.contains("<Counter>3</Counter>"), true,
 487                             "Output from SAX without namespace support should count 3");
 488     }
 489 
 490     /*
 491      * @bug 8150704
 492      * @summary Test that XSL transformation with lots of temporary result trees will not run out of DTM IDs.
 493      */
 494     @Test
 495     public final void testBug8150704() throws TransformerException, IOException {
 496         System.out.println("Testing transformation of Bug8150704-1.xml...");
 497         TransformerFactory tf = TransformerFactory.newInstance();
 498         Transformer t = tf.newTransformer(new StreamSource(getClass().getResource("Bug8150704-1.xsl").toString()));
 499         StringWriter sw = new StringWriter();
 500         t.transform(new StreamSource(getClass().getResource("Bug8150704-1.xml").toString()), new StreamResult(sw));
 501         String resultstring = sw.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n");
 502         String reference = getFileContentAsString(new File(getClass().getResource("Bug8150704-1.ref").getPath()));
 503         Assert.assertEquals(resultstring, reference, "Output of transformation of Bug8150704-1.xml does not match reference");
 504         System.out.println("Passed.");
 505 
 506         System.out.println("Testing transformation of Bug8150704-2.xml...");
 507         t = tf.newTransformer(new StreamSource(getClass().getResource("Bug8150704-2.xsl").toString()));
 508         sw = new StringWriter();
 509         t.transform(new StreamSource(getClass().getResource("Bug8150704-2.xml").toString()), new StreamResult(sw));
 510         resultstring = sw.toString().replaceAll("\\r\\n", "\n").replaceAll("\\r", "\n");
 511         reference = getFileContentAsString(new File(getClass().getResource("Bug8150704-2.ref").getPath()));
 512         Assert.assertEquals(resultstring, reference, "Output of transformation of Bug8150704-2.xml does not match reference");
 513         System.out.println("Passed.");
 514     }
 515 
 516     /*
 517      * @bug 8162598
 518      * @summary Test XSLTC handling of namespaces, especially empty namespace definitions to reset the
 519      *          default namespace
 520      */
 521     @Test
 522     public final void testBug8162598() throws IOException, TransformerException {
 523         final String LINE_SEPARATOR = getSystemProperty("line.separator");
 524 
 525         final String xsl =
 526             "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + LINE_SEPARATOR +
 527             "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">" + LINE_SEPARATOR +
 528             "    <xsl:template match=\"/\">" + LINE_SEPARATOR +
 529             "        <root xmlns=\"ns1\">" + LINE_SEPARATOR +
 530             "            <xsl:call-template name=\"transform\"/>" + LINE_SEPARATOR +
 531             "        </root>" + LINE_SEPARATOR +
 532             "    </xsl:template>" + LINE_SEPARATOR +
 533             "    <xsl:template name=\"transform\">" + LINE_SEPARATOR +
 534             "        <test1 xmlns=\"ns2\"><b xmlns=\"ns2\"><c xmlns=\"\"></c></b></test1>" + LINE_SEPARATOR +
 535             "        <test2 xmlns=\"ns1\"><b xmlns=\"ns2\"><c xmlns=\"\"></c></b></test2>" + LINE_SEPARATOR +
 536             "        <test3><b><c xmlns=\"\"></c></b></test3>" + LINE_SEPARATOR +
 537             "        <test4 xmlns=\"\"><b><c xmlns=\"\"></c></b></test4>" + LINE_SEPARATOR +
 538             "        <test5 xmlns=\"ns1\"><b><c xmlns=\"\"></c></b></test5>" + LINE_SEPARATOR +
 539             "        <test6 xmlns=\"\"/>" + LINE_SEPARATOR +
 540             "    </xsl:template>" + LINE_SEPARATOR +
 541             "</xsl:stylesheet>";
 542 
 543 
 544         final String sourceXml =
 545                 "<?xml version=\"1.0\" encoding=\"UTF-8\"?><aaa></aaa>" + LINE_SEPARATOR;
 546 
 547         System.out.println("Stylesheet:");
 548         System.out.println("=============================");
 549         System.out.println(xsl);
 550         System.out.println();
 551 
 552         System.out.println("Source before transformation:");
 553         System.out.println("=============================");
 554         System.out.println(sourceXml);
 555         System.out.println();
 556 
 557         // transform to DOM result
 558         TransformerFactory tf = TransformerFactory.newInstance();
 559         Transformer t = tf.newTransformer(new StreamSource(new ByteArrayInputStream(xsl.getBytes())));
 560         DOMResult result = new DOMResult();
 561         t.transform(new StreamSource(new ByteArrayInputStream(sourceXml.getBytes())), result);
 562         Document document = (Document)result.getNode();
 563         
 564         System.out.println("Result after transformation:");
 565         System.out.println("============================");
 566         OutputFormat format = new OutputFormat();
 567         format.setIndenting(true);
 568         new XMLSerializer(System.out, format).serialize(document);
 569         System.out.println();
 570         checkNodeNS8162598(document.getElementsByTagName("test1").item(0), "ns2", "ns2", null);
 571         checkNodeNS8162598(document.getElementsByTagName("test2").item(0), "ns1", "ns2", null);
 572         checkNodeNS8162598(document.getElementsByTagName("test3").item(0), null, null, null);
 573         checkNodeNS8162598(document.getElementsByTagName("test4").item(0), null, null, null);
 574         checkNodeNS8162598(document.getElementsByTagName("test5").item(0), "ns1", "ns1", null);
 575         Assert.assertNull(document.getElementsByTagName("test6").item(0).getNamespaceURI(), "unexpected namespace for test6");
 576     }
 577 }