1 /*
   2  * Copyright (c) 2015, 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;
  21 
  22 import javax.xml.parsers.DocumentBuilder;
  23 import javax.xml.parsers.DocumentBuilderFactory;
  24 import javax.xml.parsers.SAXParserFactory;
  25 import javax.xml.transform.Result;
  26 import javax.xml.transform.Templates;
  27 import javax.xml.transform.Transformer;
  28 import javax.xml.transform.TransformerFactory;
  29 import javax.xml.transform.dom.DOMSource;
  30 import javax.xml.transform.sax.SAXSource;
  31 import javax.xml.transform.sax.SAXTransformerFactory;
  32 import javax.xml.transform.sax.TransformerHandler;
  33 import javax.xml.transform.stream.StreamResult;
  34 import javax.xml.transform.stream.StreamSource;
  35 import jaxp.library.JAXPFileBaseTest;
  36 import static jaxp.library.JAXPTestUtilities.compareWithGold;
  37 import static jaxp.library.JAXPTestUtilities.filenameToURL;
  38 import static jaxp.library.JAXPTestUtilities.getNextFile;
  39 import static org.apache.qetest.CheckingHandler.Expectation.ITEM_CHECKFAIL;
  40 import static org.apache.qetest.trax.CheckingErrorListener.THROW_NEVER;
  41 import static org.apache.qetest.trax.CheckingErrorListener.TYPE_FATALERROR;
  42 import static org.apache.qetest.trax.CheckingErrorListener.TYPE_WARNING;
  43 import static org.apache.qetest.trax.TraxConst.GOLDEN_DIR;
  44 import static org.apache.qetest.trax.TraxConst.XML_DIR;
  45 import org.apache.qetest.xsl.CheckingSAXErrorHandler;
  46 import org.testng.annotations.DataProvider;
  47 import org.testng.annotations.Test;
  48 import org.w3c.dom.Node;
  49 import org.xml.sax.InputSource;
  50 import org.xml.sax.XMLReader;
  51 
  52 /**
  53  * Verify that ErrorListeners are called properly from Transformers. Also
  54  * verifies basic Transformer behavior after a stylesheet with errors has been
  55  * built. Note: parts of this test may rely on specific Xalan functionality, in
  56  * that with the specific errors I've chosen, Xalan can actually continue to
  57  * process the stylesheet, even though it had an error. XSLTC mode may either
  58  * throw slighly different kinds of errors, or may not be able to continue after
  59  * the error (we should investigate changing this test to just verify common
  60  * things, and then check the rest into the xalanj2 directory).
  61  */
  62 public class ErrorListenerTest extends JAXPFileBaseTest {
  63     /**
  64      * Expect fatal when transformation by default.
  65      */
  66     private static final int TEMPLATES_EXPECTED_TYPE = TYPE_FATALERROR;
  67 
  68     /**
  69      * Expect warning when transformation by default.
  70      */
  71     private static final int TRANSFORM_EXPECTED_TYPE = TYPE_WARNING;
  72 
  73     /**
  74      * Data provide provides test XML, stylesheet and output files name.
  75      * @return an array has XML, stylesheet and output files name.
  76      */
  77     @DataProvider
  78     public Object[][] testFiles(){
  79         return new Object[][]{
  80             {XML_DIR + "ErrorListenerTest.xml", 
  81                 XML_DIR + "ErrorListenerTest.xsl",
  82                 GOLDEN_DIR + "ErrorListenerTest.out"}
  83         };
  84     }
  85 
  86     /**
  87      * TransformerFactory Set/Get ErrorListener test.
  88      * 
  89      * @param xmlFile XML test file name.
  90      * @param xslFile XSLT test file name.
  91      * @param goldFile golden file name.
  92      * @throws Exception If any errors occur. 
  93      */
  94     @Test(dataProvider = "testFiles")
  95     public void testCase1(String xmlFile, String xslFile, String goldFile) 
  96             throws Exception {
  97         String outputFile = getNextFile(this.getClass());
  98  
  99         CheckingErrorListener chkErrorListener = new CheckingErrorListener(THROW_NEVER);
 100 
 101         TransformerFactory factory = TransformerFactory.newInstance();
 102         // Set the errorListener and validate it
 103         factory.setErrorListener(chkErrorListener);
 104 
 105         // Attempt to build templates from known-bad stylesheet
 106         // Validate known errors in stylesheet building
 107         chkErrorListener.setExpected(TEMPLATES_EXPECTED_TYPE,
 108                 ITEM_CHECKFAIL);
 109         Templates templates = factory.newTemplates(new StreamSource(filenameToURL(xslFile)));
 110         // Clear out any setExpected or counters
 111         chkErrorListener.reset();
 112 
 113         // This stylesheet will still work, even though errors
 114         //  were detected during it's building.  Note that
 115         //  future versions of Xalan or other processors may
 116         //  not be able to continue here...
 117         Transformer transformer = templates.newTransformer();
 118 
 119         // Set the errorListener and validate it
 120         transformer.setErrorListener(chkErrorListener);
 121 
 122         // Validate the first xsl:message call in the stylesheet
 123         chkErrorListener.setExpected(TRANSFORM_EXPECTED_TYPE,
 124                 ITEM_CHECKFAIL);
 125         transformer.transform(new StreamSource(filenameToURL(xmlFile)),
 126                 new StreamResult(outputFile));
 127         // Clear out any setExpected or counters
 128         chkErrorListener.reset();
 129         compareWithGold(goldFile, outputFile);
 130     }
 131 
 132     /**
 133      * Build a bad style-sheet/do a transform with DOMs. Verify that the 
 134      * ErrorListener is called properly. Primarily using SAXSources.
 135      * 
 136      * @param xmlFile test XML filename.
 137      * @param xslFile test style-sheet filename.
 138      * @param goldFile golden verification filename.
 139      *  
 140      * @throws Exception If any errors occur.
 141      */
 142     @Test(dataProvider = "testFiles")
 143     public void testCase2(String xmlFile, String xslFile, String goldFile) 
 144             throws Exception {
 145         String outputFile = getNextFile(this.getClass());
 146 
 147         CheckingErrorListener loggingErrorListener = new CheckingErrorListener(THROW_NEVER);
 148         // assumes SAXSource.feature!
 149         SAXTransformerFactory saxFactory = (SAXTransformerFactory)TransformerFactory.newInstance();
 150 
 151         // Set the errorListener and validate it
 152         saxFactory.setErrorListener(loggingErrorListener);
 153 
 154         // Use the JAXP way to get an XMLReader
 155         XMLReader reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
 156         InputSource is = new InputSource(filenameToURL(xslFile));
 157 
 158         // Attempt to build templates from known-bad stylesheet
 159         // Validate known errors in stylesheet building
 160         loggingErrorListener.setExpected(TEMPLATES_EXPECTED_TYPE,
 161                 ITEM_CHECKFAIL);
 162         TransformerHandler handler = saxFactory.newTransformerHandler(new SAXSource(is));
 163         // Clear out any setExpected or counters
 164         loggingErrorListener.reset();
 165 
 166         // This stylesheet will still work, even though errors
 167         //  were detected during it's building.  Note that
 168         //  future versions of Xalan or other processors may
 169         //  not be able to continue here...
 170 
 171         // Create a result and setup SAX parsing 'tree'
 172         Result result = new StreamResult(outputFile);
 173         handler.setResult(result);
 174         reader.setContentHandler(handler);
 175 
 176         CheckingSAXErrorHandler loggingSAXErrorHandler 
 177                 = new CheckingSAXErrorHandler(CheckingSAXErrorHandler.THROW_NEVER);
 178         reader.setErrorHandler(loggingSAXErrorHandler);
 179 
 180         // Validate the first xsl:message call in the stylesheet
 181         loggingErrorListener.setExpected(TRANSFORM_EXPECTED_TYPE,
 182                 ITEM_CHECKFAIL);
 183         reader.parse(filenameToURL(xmlFile));
 184         // Clear out any setExpected or counters
 185         loggingErrorListener.reset();
 186         loggingSAXErrorHandler.reset();
 187         compareWithGold(goldFile, outputFile);
 188     }
 189     
 190     /**
 191      * Build a bad style-sheet/do a transform with DOMs. Verify that the 
 192      * ErrorListener is called properly. Primarily using DOMSources.
 193      * 
 194      * @param xmlFile test XML filename.
 195      * @param xslFile test style-sheet filename.
 196      * @param goldFile golden verification filename. 
 197      * @throws Exception If any errors occur. 
 198      */
 199     @Test(dataProvider = "testFiles")
 200     public void testCase3(String xmlFile, String xslFile, String goldFile) 
 201             throws Exception {
 202         String outputFile = getNextFile(this.getClass());
 203         CheckingErrorListener chkErrorListener = new CheckingErrorListener(THROW_NEVER);
 204         // Startup a DOM factory, create some nodes/DOMs
 205         DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
 206         dfactory.setNamespaceAware(true);
 207         DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
 208         Node xslNode = docBuilder.parse(new InputSource(filenameToURL(xslFile)));
 209         Node xmlNode = docBuilder.parse(new InputSource(filenameToURL(xmlFile)));
 210 
 211         // Create a transformer factory with an error listener
 212         TransformerFactory factory = TransformerFactory.newInstance();
 213         factory.setErrorListener(chkErrorListener);
 214 
 215         // Attempt to build templates from known-bad stylesheet
 216         // Validate known errors in stylesheet building
 217         Templates templates = factory.newTemplates(new DOMSource(xslNode));
 218         // Clear out any setExpected or counters 
 219         Transformer transformer = templates.newTransformer();
 220         transformer.setErrorListener(chkErrorListener);
 221         transformer.transform(new DOMSource(xmlNode), new StreamResult(outputFile));
 222         compareWithGold(goldFile, outputFile);
 223     }
 224 }