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