1 /*
   2  * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
   3  */
   4 /*
   5  * Licensed to the Apache Software Foundation (ASF) under one or more
   6  * contributor license agreements.  See the NOTICE file distributed with
   7  * this work for additional information regarding copyright ownership.
   8  * The ASF licenses this file to You under the Apache License, Version 2.0
   9  * (the "License"); you may not use this file except in compliance with
  10  * the License.  You may obtain a copy of the License at
  11  *
  12  *      http://www.apache.org/licenses/LICENSE-2.0
  13  *
  14  * Unless required by applicable law or agreed to in writing, software
  15  * distributed under the License is distributed on an "AS IS" BASIS,
  16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  17  * See the License for the specific language governing permissions and
  18  * limitations under the License.
  19  */
  20 package org.apache.qetest.trax.sax;
  21 
  22 import java.io.FilePermission;
  23 import java.io.IOException;
  24 import java.io.StringReader;
  25 import java.nio.file.Files;
  26 import java.nio.file.Paths;
  27 import java.util.stream.Collectors;
  28 import javax.xml.parsers.ParserConfigurationException;
  29 import javax.xml.parsers.SAXParser;
  30 import javax.xml.parsers.SAXParserFactory;
  31 import javax.xml.transform.Transformer;
  32 import javax.xml.transform.TransformerConfigurationException;
  33 import javax.xml.transform.TransformerException;
  34 import javax.xml.transform.TransformerFactory;
  35 import javax.xml.transform.sax.SAXTransformerFactory;
  36 import javax.xml.transform.sax.TransformerHandler;
  37 import javax.xml.transform.stream.StreamResult;
  38 import javax.xml.transform.stream.StreamSource;
  39 import jaxp.library.JAXPBaseTest;
  40 import static jaxp.library.JAXPTestUtilities.CLASS_DIR;
  41 import static org.apache.qetest.trax.TraxConst.XML_DIR;
  42 import static jaxp.library.JAXPTestUtilities.getNextFile;
  43 import org.apache.qetest.xsl.CheckingSAXErrorHandler;
  44 import static org.testng.Assert.assertEquals;
  45 import org.testng.annotations.AfterGroups;
  46 import org.testng.annotations.BeforeGroups;
  47 import org.testng.annotations.Test;
  48 import org.xml.sax.SAXException;
  49 import org.xml.sax.SAXParseException;
  50 
  51 /**
  52  * Basic functionality test for the TransformerHandler class of TRAX.
  53  */
  54 public class TransformerHandlerTest extends JAXPBaseTest {
  55 
  56     /**
  57      * Un-formed XML string(note mismatched tags).
  58      */
  59     private static final String XML_ERROR_STR
  60             = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  61             + "<root1></root2>";
  62 
  63     /**
  64      * Well-formed XML string.
  65      */
  66     private static final String XML_GOOD_STR
  67             = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  68             + "<root>Hello world</root>";
  69 
  70     /**
  71      * XSLT string.
  72      */
  73     private static final String XSL_STR
  74             = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
  75             + "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">"
  76             + "<xsl:template match=\"/\">"
  77             + "<xsl:copy-of select=\".\"/>"
  78             + "</xsl:template>"
  79             + "</xsl:stylesheet>";
  80     
  81     /**
  82      * Golden validation string.
  83      */
  84     private static final String GOLDEN_STR
  85             = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><root>Hello world</root>";
  86     
  87     /**
  88      * Save system property for restoring.
  89      */
  90     @BeforeGroups (groups = {"readLocalFiles"})
  91     public void setFilePermissions() {
  92         setPermissions(new FilePermission(XML_DIR + "/-", "read"),
  93                 new FilePermission(CLASS_DIR + "/-", "read, write"));
  94     }
  95     
  96     /**
  97      * Restore the system property.
  98      */
  99     @AfterGroups (groups = {"readLocalFiles"})
 100     public void restoreFilePermissions() {
 101         setPermissions();
 102     }
 103 
 104     /**
 105      * Transformer.transform on a not well-formed XML throws TransformerException.
 106      * 
 107      * @throws TransformerException If an unrecoverable error occurs during the 
 108      *         course of the transformation. 
 109      */
 110     @Test(groups = {"readLocalFiles"}, expectedExceptions = TransformerException.class)
 111     public void negativeCase1() throws TransformerException {
 112         // No public constructor available: you must always ask
 113         //  a SAXTransformerFactory to give you one
 114         SAXTransformerFactory saxFactory
 115                 = (SAXTransformerFactory) TransformerFactory.newInstance();
 116         try (StringReader sr1 = new StringReader(XSL_STR);
 117                 StringReader sr2 = new StringReader(XML_ERROR_STR)) {
 118             Transformer reusedTransformer = saxFactory.newTransformer(
 119                     new StreamSource(sr1));
 120             reusedTransformer.transform(new StreamSource(sr2),
 121                     new StreamResult(getNextFile(TransformerHandlerTest.class)));
 122         }
 123     }
 124 
 125     /**
 126      * Reader.read on a not well-formed XML throws TransformerException. 
 127      * 
 128      * @throws SAXException for SAX errors.
 129      * @throws TransformerConfigurationException Thrown in case of {@linkplain
 130      * java.util.ServiceConfigurationError service configuration error} or if
 131      * the implementation is not available or cannot be instantiated.
 132      * @throws ParserConfigurationException if  the implementation is not 
 133      *         available or cannot be instantiated.
 134      * @throws IOException if any I/O operation failed. 
 135      */
 136     @Test(groups = {"readLocalFiles"}, expectedExceptions = SAXParseException.class)
 137     public void testCase2() throws SAXException, TransformerConfigurationException,
 138             ParserConfigurationException, IOException {
 139         SAXTransformerFactory saxFactory
 140                 = (SAXTransformerFactory) TransformerFactory.newInstance();
 141         try(StringReader sr1 = new StringReader(XSL_STR);
 142                 StringReader sr2 = new StringReader(XML_ERROR_STR);) {
 143             TransformerHandler thandler = saxFactory.newTransformerHandler(
 144                     new StreamSource(sr1));
 145             SAXParserFactory spf1 = SAXParserFactory.newInstance();
 146             spf1.setNamespaceAware(true);
 147             SAXParser parser1 = spf1.newSAXParser();
 148             org.xml.sax.XMLReader reader = parser1.getXMLReader();
 149             reader.setContentHandler(thandler);
 150             reader.setErrorHandler(new CheckingSAXErrorHandler());
 151             thandler.setResult(new StreamResult(getNextFile(TransformerHandlerTest.class)));
 152             reader.parse(new org.xml.sax.InputSource(sr2));
 153         }
 154     }
 155 
 156     /**
 157      * Re-transform several times with XMLReader and Transformer. No exception 
 158      * should be thrown.
 159      * 
 160      * @throws TransformerException If an unrecoverable error occurs during the
 161      *         course of the transformation.
 162      * @throws ParserConfigurationException  Thrown in case of 
 163      *         ServiceConfigurationError service configuration error or if
 164      *         the implementation is not available or cannot be instantiated.
 165      * @throws SAXException for SAX errors.
 166      * @throws IOException if any I/O operation failed. 
 167      */
 168     @Test(groups = {"readLocalFiles"})
 169     public void testCase3() throws TransformerException, ParserConfigurationException,
 170             SAXException, IOException {
 171         SAXTransformerFactory saxFactory
 172                 = (SAXTransformerFactory) TransformerFactory.newInstance();
 173         String outputFile1 = getNextFile(this.getClass());
 174         String outputFile2 = getNextFile(this.getClass());
 175         try(StringReader sr1 = new StringReader(XSL_STR);
 176                 StringReader sr2 = new StringReader(XML_GOOD_STR);
 177                 StringReader sr3 = new StringReader(XSL_STR);
 178                 StringReader sr4 = new StringReader(XML_GOOD_STR)) {
 179             TransformerHandler thandler = saxFactory.newTransformerHandler(
 180                     new StreamSource(sr1));
 181             SAXParserFactory spf = SAXParserFactory.newInstance();
 182             spf.setNamespaceAware(true);
 183             SAXParser parser = spf.newSAXParser();
 184             org.xml.sax.XMLReader reader = parser.getXMLReader();
 185             thandler.setResult(new StreamResult(outputFile1));
 186             reader.setContentHandler(thandler);
 187             reader.setErrorHandler(new CheckingSAXErrorHandler());
 188             reader.parse(new org.xml.sax.InputSource(sr2));
 189 
 190             Transformer reusedTransformer = TransformerFactory.newInstance()
 191                     .newTransformer(new StreamSource(sr3));
 192             reusedTransformer.transform(new StreamSource(sr4),
 193                     new StreamResult(outputFile2));
 194         }
 195         String outputStr1 = Files.readAllLines(Paths.get(outputFile1)).stream()
 196                 .collect(Collectors.joining(System.getProperty("line.separator")));
 197         String outputStr2 = Files.readAllLines(Paths.get(outputFile1)).stream()
 198                 .collect(Collectors.joining(System.getProperty("line.separator")));
 199         assertEquals(outputStr1, GOLDEN_STR);
 200         assertEquals(outputStr2, GOLDEN_STR);
 201     }
 202 }