/* * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.qetest.trax; import com.sun.org.apache.xml.internal.serializer.OutputPropertiesFactory; import com.sun.org.apache.xml.internal.serializer.Serializer; import com.sun.org.apache.xml.internal.serializer.SerializerFactory; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.Properties; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import javax.xml.transform.OutputKeys; import javax.xml.transform.Result; import javax.xml.transform.Templates; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMResult; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.sax.SAXResult; import javax.xml.transform.sax.SAXSource; import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; import jaxp.library.JAXPFileBaseTest; import static jaxp.library.JAXPTestUtilities.compareWithGold; import static jaxp.library.JAXPTestUtilities.filenameToURL; import static org.apache.qetest.trax.TraxConst.GOLDEN_DIR; import static org.apache.qetest.trax.TraxConst.XML_DIR; import static jaxp.library.JAXPTestUtilities.getNextFile; import static org.testng.Assert.*; import org.testng.annotations.Test; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLFilter; import org.xml.sax.XMLReader; /** * Test version of xml-xalan/java/samples/trax/Examples.java. * This file is essentially copied from the Examples for TRAX, or * javax.xml.transform; however this file actually validates most output and * behavior for correctness. */ public class ExamplesTest extends JAXPFileBaseTest { /** * Test XML file 1 name. */ private static final String SOURCE_ID = XML_DIR + "xml/foo.xml"; /** * Test XML file 2 name. */ private static final String SOURCE_ID2 = XML_DIR + "xml/baz.xml"; /** * Test stylesheet file name. */ private static final String XSL_ID = XML_DIR + "xsl/foo.xsl"; /** * Show the Transformer as a simple XMLFilter. This is pretty similar to * exampleXMLReader, except that here the parent XMLReader is created by the * caller, instead of automatically within the XMLFilter. This gives the * caller more direct control over the parent reader. * * @throws ParserConfigurationException if the implementation is not * available or cannot be instantiated. * @throws SAXException for SAX error. * @throws IOException if any I/O operation error. * @throws TransformerConfigurationException Thrown in case of * ServiceConfigurationError service configuration error or if the * implementation is not available or cannot be instantiated. */ @Test public void exampleXMLFilter() throws IOException, SAXException, ParserConfigurationException, TransformerConfigurationException { String outputFile = getNextFile(this.getClass()); try (FileOutputStream fos = new FileOutputStream(outputFile)) { TransformerFactory tfactory = TransformerFactory.newInstance(); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); SAXParser jaxpParser = factory.newSAXParser(); XMLReader reader = jaxpParser.getXMLReader(); // Set the result handling to be a serialization to the file output stream. Serializer serializer = SerializerFactory.getSerializer( OutputPropertiesFactory.getDefaultMethodProperties("xml")); serializer.setOutputStream(fos); reader.setContentHandler(serializer.asContentHandler()); reader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); reader.setFeature("http://apache.org/xml/features/validation/dynamic", true); XMLFilter filter = ((SAXTransformerFactory) tfactory) .newXMLFilter(new StreamSource(filenameToURL(XSL_ID))); filter.setParent(reader); // Now, when you call transformer.parse, it will set itself as // the content handler for the parser object (it's "parent"), and // will then call the parse method on the parser. filter.parse(new InputSource(filenameToURL(SOURCE_ID))); } assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_14.out", outputFile)); } /** * Show simple transformation from reader to output stream. In general this * use case is discouraged, since the XML encoding can not be processed. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleFromReader() throws IOException, TransformerException { String outputFile = getNextFile(this.getClass()); // Create a transform factory instance. TransformerFactory tfactory = TransformerFactory.newInstance(); // Note that in this case the XML encoding can not be processed! Reader xslReader = new BufferedReader(new InputStreamReader(new FileInputStream(XSL_ID), "UTF-8")); StreamSource xslSource = new StreamSource(xslReader); // Note that if we don't do this, relative URLs can not be resolved correctly! xslSource.setSystemId(filenameToURL(XSL_ID)); // Create a transformer for the stylesheet. Transformer transformer = tfactory.newTransformer(xslSource); Reader xmlReader = new BufferedReader(new InputStreamReader(new FileInputStream(SOURCE_ID), "UTF-8")); StreamSource xmlSource = new StreamSource(xmlReader); // Note that if we don't do this, relative URLs can not be resolved correctly! xmlSource.setSystemId(filenameToURL(SOURCE_ID)); // Transform the source XML to output file. transformer.transform(xmlSource, new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_5.out", outputFile)); } /** * Show the Transformer using SAX events in and SAX events out. * * @throws ParserConfigurationException if the implementation is not * available or cannot be instantiated. * @throws SAXException for SAX error. * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleContentHandlerToContentHandler() throws TransformerException, IOException, SAXException, ParserConfigurationException { TransformerFactory tfactory = TransformerFactory.newInstance(); String outputFile = getNextFile(this.getClass()); try (FileOutputStream fos = new FileOutputStream(outputFile)) { // Does this factory support SAX features? if (!tfactory.getFeature(SAXSource.FEATURE)) { return; } // If so, we can safely cast. SAXTransformerFactory stfactory = (SAXTransformerFactory) tfactory; // A TransformerHandler is a ContentHandler that will listen for // SAX events, and transform them to the result. TransformerHandler handler = stfactory.newTransformerHandler(new StreamSource(filenameToURL(XSL_ID))); // Set the result handling to be a serialization to the file output stream. Serializer serializer = SerializerFactory.getSerializer( OutputPropertiesFactory.getDefaultMethodProperties("xml")); serializer.setOutputStream(fos); Result result = new SAXResult(serializer.asContentHandler()); handler.setResult(result); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); XMLReader reader = factory.newSAXParser().getXMLReader(); reader.setContentHandler(handler); // It's a good idea for the parser to send lexical events. // The TransformerHandler is also a LexicalHandler. reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); // Parse the source XML, and send the parse events to the TransformerHandler. reader.parse(filenameToURL(SOURCE_ID)); } assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_3.out", outputFile)); } /** * Show the Transformer using SAX events in and DOM nodes out. * * @throws ParserConfigurationException if the implementation is not * available or cannot be instantiated. * @throws SAXException for SAX error. * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleContentHandler2DOM() throws ParserConfigurationException, TransformerException, SAXException, IOException { String outputFile = getNextFile(this.getClass()); TransformerFactory tfactory = TransformerFactory.newInstance(); // Make sure the transformer factory we obtained supports both // DOM and SAX. if (!(tfactory.getFeature(SAXSource.FEATURE) && tfactory.getFeature(DOMSource.FEATURE))) { return; } // We can now safely cast to a SAXTransformerFactory. SAXTransformerFactory sfactory = (SAXTransformerFactory) tfactory; // Create an Document node as the root for the output. DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); org.w3c.dom.Document outNode = docBuilder.newDocument(); // Create a ContentHandler that can liston to SAX events // and transform the output to DOM nodes. TransformerHandler handler = sfactory.newTransformerHandler(new StreamSource(filenameToURL(XSL_ID))); handler.setResult(new DOMResult(outNode)); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware(true); XMLReader reader = factory.newSAXParser().getXMLReader(); reader.setContentHandler(handler); reader.setProperty("http://xml.org/sax/properties/lexical-handler", handler); // Send the SAX events from the parser to the transformer, // and thus to the DOM tree. reader.parse(filenameToURL(SOURCE_ID)); // Serialize the node for diagnosis. // This serializes to outNames.nextName() Transformer serializer = tfactory.newTransformer(); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); serializer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); serializer.transform(new DOMSource(outNode), new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_2.out", outputFile)); } /** * A fuller example showing how the TrAX interface can be used to serialize * a DOM tree. * * @throws ParserConfigurationException if the implementation is not * available or cannot be instantiated. * @throws SAXException for SAX error. * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleAsSerializer() throws ParserConfigurationException, SAXException, IOException, TransformerException { String outputFile = getNextFile(this.getClass()); DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); org.w3c.dom.Document outNode = docBuilder.newDocument(); Node doc = docBuilder.parse(new InputSource(filenameToURL(SOURCE_ID))); TransformerFactory tfactory = TransformerFactory.newInstance(); // This creates a transformer that does a simple identity transform, // and thus can be used for all intents and purposes as a serializer. Transformer serializer = tfactory.newTransformer(); Properties oprops = new Properties(); oprops.put("method", "html"); oprops.put("{http://xml.apache.org/xslt}indent-amount", "2"); serializer.setOutputProperties(oprops); serializer.transform(new DOMSource(doc), new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_1.out", outputFile)); } /** * Show simple transformation from input stream to output stream. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleFromStream() throws IOException, TransformerException { String outputFile = getNextFile(this.getClass()); try (InputStream xslIS = new BufferedInputStream(new FileInputStream(XSL_ID)); InputStream xmlIS = new BufferedInputStream(new FileInputStream(SOURCE_ID))) { // Create a transform factory instance. TransformerFactory tfactory = TransformerFactory.newInstance(); StreamSource xslSource = new StreamSource(xslIS); // Note that if we don't do this, relative URLs can not be resolved correctly! xslSource.setSystemId(filenameToURL(XSL_ID)); // Create a transformer for the stylesheet. Transformer transformer = tfactory.newTransformer(xslSource); StreamSource xmlSource = new StreamSource(xmlIS); // Note that if we don't do this, relative URLs can not be resolved correctly! xmlSource.setSystemId(filenameToURL(SOURCE_ID)); // Transform the source XML to output file. transformer.transform(xmlSource, new StreamResult(outputFile)); } assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_6.out", outputFile)); } /** * Show how to override output properties. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleOutputProperties() throws IOException, TransformerException { String outputFile = getNextFile(this.getClass()); TransformerFactory tfactory = TransformerFactory.newInstance(); Templates templates = tfactory.newTemplates(new StreamSource(filenameToURL(XSL_ID))); Properties oprops = templates.getOutputProperties(); oprops.put(OutputKeys.INDENT, "yes"); Transformer transformer = templates.newTransformer(); transformer.setOutputProperties(oprops); transformer.transform(new StreamSource(filenameToURL(SOURCE_ID)), new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_7.out", outputFile)); } /** * Show how to transform a DOM tree into another DOM tree. This uses the * javax.xml.parsers to parse an XML file into a DOM, and create an output * DOM. * * @throws ParserConfigurationException if the implementation is not * available or cannot be instantiated. * @throws SAXException for SAX error. * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ public void exampleDOM2DOM() throws IOException, SAXException, TransformerException, ParserConfigurationException { String outputFile = getNextFile(this.getClass()); TransformerFactory tfactory = TransformerFactory.newInstance(); DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); dfactory.setNamespaceAware(true); DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); org.w3c.dom.Document outNode = docBuilder.newDocument(); Node xslDoc = docBuilder.parse(new InputSource(filenameToURL(XSL_ID))); DOMSource dsource = new DOMSource(xslDoc); // If we don't do this, the transformer won't know how to // resolve relative URLs in the stylesheet. dsource.setSystemId(filenameToURL(XSL_ID)); Templates templates = tfactory.newTemplates(dsource); Transformer transformer = templates.newTransformer(); Node xmlDoc = docBuilder.parse(new InputSource(filenameToURL(SOURCE_ID))); transformer.transform(new DOMSource(xmlDoc), new DOMResult(outNode)); Transformer serializer = tfactory.newTransformer(); serializer.transform(new DOMSource(outNode), new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_4.out", outputFile)); } /** * Show the Transformer using SAX events in and DOM nodes out. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleSimple1() throws IOException, TransformerException { String outputFile = getNextFile(this.getClass()); // Create a transform factory instance. TransformerFactory tfactory = TransformerFactory.newInstance(); // Create a transformer for the stylesheet. Transformer transformer = tfactory.newTransformer(new StreamSource(filenameToURL(XSL_ID))); // No need to setSystemId, the transformer can get it from the URL transformer.transform(new StreamSource(filenameToURL(SOURCE_ID)), new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_8.out", outputFile)); } /** * Show the simplest possible transformation from File to a File. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleSimple2() throws IOException, TransformerException { String outputFile = getNextFile(this.getClass()); TransformerFactory tfactory = TransformerFactory.newInstance(); // Create a transformer for the stylesheet. Transformer transformer = tfactory.newTransformer(new StreamSource(new File(XSL_ID))); // No need to setSystemId, the transformer can get it from the File transformer.transform(new StreamSource(new File(SOURCE_ID)), new StreamResult(new File(outputFile))); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_9.out", outputFile)); } /** * Show the that a transformer can be reused, and show resetting a parameter * on the transformer. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleTransformerReuse() throws IOException, TransformerException { String outputFile = getNextFile(this.getClass()); // Create a transform factory instance. TransformerFactory tfactory = TransformerFactory.newInstance(); // Create a transformer for the stylesheet. Transformer transformer = tfactory.newTransformer(new StreamSource(filenameToURL(XSL_ID))); transformer.setParameter("a-param", "hello to you!"); transformer.transform(new StreamSource(filenameToURL(SOURCE_ID)), new StreamResult(outputFile)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_10.out", outputFile)); transformer.setParameter("a-param", "hello to me!"); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); String outputFile2 = getNextFile(this.getClass()); transformer.transform(new StreamSource(filenameToURL(SOURCE_ID)), new StreamResult(outputFile2)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_11.out", outputFile)); } /** * Show the simplest possible transformation from system id to output * stream. * * @throws IOException if any I/O operation error. * @throws TransformerException If an unrecoverable error occurs during the * course of the transformation. */ @Test public void exampleUseTemplatesObj() throws IOException, TransformerException { String outputFile1 = getNextFile(this.getClass()); String outputFile2 = getNextFile(this.getClass()); TransformerFactory tfactory = TransformerFactory.newInstance(); // Create a templates object, which is the processed, // thread-safe representation of the stylesheet. Templates templates = tfactory.newTemplates(new StreamSource(filenameToURL(XSL_ID))); // Illustrate the fact that you can make multiple transformers // from the same template. Transformer transformer1 = templates.newTransformer(); Transformer transformer2 = templates.newTransformer(); transformer1.transform(new StreamSource(filenameToURL(SOURCE_ID)), new StreamResult(outputFile1)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_12.out", outputFile1)); transformer2.transform(new StreamSource(filenameToURL(SOURCE_ID2)), new StreamResult(outputFile2)); assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_13.out", outputFile2)); } /** * Show the Transformer as a SAX2 XMLReader. An XMLFilter obtained from * newXMLFilter should act as a transforming XMLReader if setParent is not * called. Internally, an XMLReader is created as the parent for the * XMLFilter. * * @throws SAXException for SAX error. * @throws IOException if any I/O operation error. * @throws TransformerConfigurationException Thrown in case of * ServiceConfigurationError service configuration error or if the * implementation is not available or cannot be instantiated. */ @Test public void exampleXMLReader() throws IOException, SAXException, TransformerConfigurationException { String outputFile = getNextFile(this.getClass()); try (FileOutputStream fos = new FileOutputStream(outputFile)) { TransformerFactory tfactory = TransformerFactory.newInstance(); XMLReader reader = ((SAXTransformerFactory) tfactory) .newXMLFilter(new StreamSource(filenameToURL(XSL_ID))); // Set the result handling to be a serialization to the file output stream. Serializer serializer = SerializerFactory.getSerializer(OutputPropertiesFactory.getDefaultMethodProperties("xml")); serializer.setOutputStream(fos); reader.setContentHandler(serializer.asContentHandler()); reader.parse(new InputSource(filenameToURL(SOURCE_ID))); } assertTrue(compareWithGold(GOLDEN_DIR + "ExamplesTest_15.out", outputFile)); } }