| /* |
| * 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. |
| */ |
| /* |
| * $Id$ |
| */ |
| |
| /* |
| * |
| * ProgrammaticDOMTest.java |
| * |
| */ |
| package org.apache.qetest.xalanj2; |
| |
| import java.io.File; |
| import java.util.Properties; |
| |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.transform.Templates; |
| import javax.xml.transform.Transformer; |
| import javax.xml.transform.TransformerFactory; |
| import javax.xml.transform.dom.DOMResult; |
| import javax.xml.transform.dom.DOMSource; |
| import javax.xml.transform.stream.StreamResult; |
| |
| import org.apache.qetest.FileBasedTest; |
| import org.apache.qetest.Logger; |
| import org.apache.qetest.OutputNameManager; |
| import org.apache.qetest.QetestUtils; |
| import org.apache.qetest.xsl.XSLTestfileInfo; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.DocumentFragment; |
| import org.w3c.dom.Element; |
| import org.w3c.dom.Node; |
| import org.xml.sax.InputSource; |
| |
| //------------------------------------------------------------------------- |
| |
| /** |
| * Functionality/system/integration tests for DOMSource. |
| * Various kinds of DOM elements, documents used. |
| * @author shane_curcuru@lotus.com |
| * @version $Id$ |
| */ |
| public class ProgrammaticDOMTest extends FileBasedTest |
| { |
| |
| /** Provides nextName(), currentName() functionality. */ |
| protected OutputNameManager outNames; |
| |
| /** Simple DOMTest.xml/xsl file pair. */ |
| protected XSLTestfileInfo testFileInfo = new XSLTestfileInfo(); |
| |
| /** Subdirectory under test\tests\api for our xsl/xml files. */ |
| public static final String TRAX_SUBDIR = File.separator + "trax" + File.separator; |
| |
| private static final String xslNamespace = "http://www.w3.org/1999/XSL/Transform"; |
| private static final String nsNamespace = "http://www.w3.org/XML/1998/namespace"; |
| |
| /** Just initialize test name, comment, numTestCases. */ |
| public ProgrammaticDOMTest() |
| { |
| numTestCases = 2; // REPLACE_num |
| testName = "ProgrammaticDOMTest"; |
| testComment = "Functionality/system/integration tests for DOMSource"; |
| } |
| |
| |
| /** |
| * Initialize this test - Set names of xml/xsl test files. |
| * |
| * @param p Properties to initialize from (if needed) |
| * @return false if we should abort the test; true otherwise |
| */ |
| public boolean doTestFileInit(Properties p) |
| { |
| // Used for all tests; just dump files in trax subdir |
| File outSubDir = new File(outputDir + TRAX_SUBDIR); |
| if (!outSubDir.mkdirs()) |
| reporter.logWarningMsg("Could not create output dir: " + outSubDir); |
| // Initialize an output name manager to that dir with .out extension |
| outNames = new OutputNameManager(outputDir + TRAX_SUBDIR |
| + testName, ".out"); |
| |
| testFileInfo.inputName = QetestUtils.filenameToURL(inputDir |
| + TRAX_SUBDIR + "identity.xsl"); |
| testFileInfo.xmlName = QetestUtils.filenameToURL(inputDir |
| + TRAX_SUBDIR + "identity.xml"); |
| testFileInfo.goldName = goldDir + TRAX_SUBDIR + "identity.out"; |
| |
| try |
| { |
| TransformerFactory tf = TransformerFactory.newInstance(); |
| if (!(tf.getFeature(DOMSource.FEATURE) |
| && tf.getFeature(DOMResult.FEATURE))) |
| { // The rest of this test relies on DOM |
| reporter.logErrorMsg("DOM*.FEATURE not supported! Some tests may be invalid!"); |
| } |
| } |
| catch (Throwable t) |
| { |
| reporter.checkFail( |
| "Problem creating factory; Some tests may be invalid!"); |
| reporter.logThrowable(reporter.ERRORMSG, t, |
| "Problem creating factory; Some tests may be invalid!"); |
| } |
| |
| return true; |
| } |
| |
| |
| /** |
| * Pass various forms of XML DOM's to a transform. |
| * Reproduce Bugzilla 1361. |
| * http://nagoya.apache.org/bugzilla/show_bug.cgi?id=1361 |
| * |
| * @return false if we should abort the test; true otherwise |
| */ |
| public boolean testCase1() |
| { |
| reporter.testCaseInit("Pass various forms of XML DOM's to a transform"); |
| |
| try |
| { |
| // Startup a factory and docbuilder, create some nodes/DOMs |
| DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); |
| dfactory.setNamespaceAware(true); |
| DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); |
| |
| reporter.logTraceMsg("parsing xml, xsl files"); |
| Document xslDoc = docBuilder.parse(new InputSource(testFileInfo.inputName)); |
| Document xmlDoc = docBuilder.parse(new InputSource(testFileInfo.xmlName)); |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| |
| // Try a transform with XSL Document and XML Document (common usage) |
| Templates templates = factory.newTemplates(new DOMSource(xslDoc)); |
| Transformer transformer = templates.newTransformer(); |
| reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xmlDoc,...) into " + outNames.currentName()); |
| |
| // Programmatically build the XML file into a Document and transform |
| Document xmlBuiltDoc = docBuilder.newDocument(); |
| appendIdentityDOMXML(xmlBuiltDoc, xmlBuiltDoc, true); |
| transformer = templates.newTransformer(); |
| reporter.logInfoMsg("About to transform(xmlBuiltDoc, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlBuiltDoc), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xmlBuiltDoc,...) into " + outNames.currentName()); |
| |
| // Again, with identity transformer |
| transformer = factory.newTransformer(); |
| reporter.logInfoMsg("About to identityTransform(xmlBuiltDoc, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlBuiltDoc), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "identityTransform(xmlBuiltDoc,...) into " + outNames.currentName()); |
| |
| |
| // Programmatically build the XML file into a DocFrag and transform |
| xmlBuiltDoc = docBuilder.newDocument(); |
| DocumentFragment xmlBuiltDocFrag = xmlBuiltDoc.createDocumentFragment(); |
| appendIdentityDOMXML(xmlBuiltDocFrag, xmlBuiltDoc, true); |
| transformer = templates.newTransformer(); |
| reporter.logInfoMsg("About to transform(xmlBuiltDocFrag, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlBuiltDocFrag), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xmlBuiltDocFrag,...) into " + outNames.currentName()); |
| |
| // Again, with identity transformer |
| transformer = factory.newTransformer(); |
| reporter.logInfoMsg("About to identityTransform(xmlBuiltDocFrag, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlBuiltDocFrag), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "identityTransform(xmlBuiltDocFrag,...) into " + outNames.currentName()); |
| |
| |
| // Programmatically build the XML file into an Element and transform |
| xmlBuiltDoc = docBuilder.newDocument(); |
| // Note: Here, we implicitly already have the outer list |
| // element, so ensure the worker method doesn't add again |
| Element xmlBuiltElem = xmlBuiltDoc.createElement("list"); |
| appendIdentityDOMXML(xmlBuiltElem, xmlBuiltDoc, false); |
| transformer = templates.newTransformer(); |
| reporter.logInfoMsg("About to transform(xmlBuiltElem, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlBuiltElem), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xmlBuiltElem,...) into " + outNames.currentName()); |
| |
| // Again, with identity transformer |
| transformer = factory.newTransformer(); |
| reporter.logInfoMsg("About to identityTransform(xmlBuiltElem, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlBuiltElem), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "identityTransform(xmlBuiltElem,...) into " + outNames.currentName()); |
| } |
| catch (Throwable t) |
| { |
| reporter.checkFail("Problem with various XML elems/documents"); |
| reporter.logThrowable(reporter.ERRORMSG, t, "Problem with various XML elems/documents"); |
| } |
| |
| reporter.testCaseClose(); |
| return true; |
| } |
| |
| |
| /** |
| * Build a stylesheet DOM programmatically and use it. |
| * |
| * @return false if we should abort the test; true otherwise |
| */ |
| public boolean testCase2() |
| { |
| reporter.testCaseInit("Build a stylesheet DOM programmatically and use it"); |
| |
| try |
| { |
| // Startup a factory and docbuilder, create some nodes/DOMs |
| DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); |
| dfactory.setNamespaceAware(true); |
| DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); |
| |
| reporter.logTraceMsg("parsing xml file"); |
| Document xmlDoc = docBuilder.parse(new InputSource(testFileInfo.xmlName)); |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| Transformer transformer = null; |
| |
| // Programmatically build the XSL file into a Document and transform |
| Document xslBuiltDoc = docBuilder.newDocument(); |
| appendIdentityDOMXSL(xslBuiltDoc, xslBuiltDoc, true); |
| // For debugging, write the generated stylesheet out |
| // Note this will not textually exactly match the identity.xsl file |
| reporter.logInfoMsg("Writing out xslBuiltDoc to "+ outNames.nextName()); |
| transformer = factory.newTransformer(); |
| transformer.transform(new DOMSource(xslBuiltDoc), new StreamResult(outNames.currentName())); |
| |
| reporter.logInfoMsg("About to newTransformer(xslBuiltDoc)"); |
| transformer = factory.newTransformer(new DOMSource(xslBuiltDoc)); |
| reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xslBuiltDoc,...) into " + outNames.currentName()); |
| |
| |
| // Programmatically build the XSL file into a DocFrag and transform |
| xslBuiltDoc = docBuilder.newDocument(); |
| DocumentFragment xslBuiltDocFrag = xslBuiltDoc.createDocumentFragment(); |
| appendIdentityDOMXSL(xslBuiltDocFrag, xslBuiltDoc, true); |
| // For debugging, write the generated stylesheet out |
| reporter.logInfoMsg("Writing out xslBuiltDocFrag to "+ outNames.nextName()); |
| transformer = factory.newTransformer(); |
| transformer.transform(new DOMSource(xslBuiltDocFrag), new StreamResult(outNames.currentName())); |
| |
| reporter.logCriticalMsg("//@todo Verify that this is even a valid operation!"); |
| reporter.logCriticalMsg("Bugzilla#5133 NPE below MOVED to SmoketestOuttakes.java 27-Nov-01 -sc"); |
| /* @todo Bugzilla#5133 NPE below MOVED to SmoketestOuttakes.java 27-Nov-01 -sc |
| // Check that the DOM is actually correct, esp namespace nodes on top level |
| // java.lang.NullPointerException |
| // at org.apache.xalan.transformer.TransformerImpl.createResultContentHandler(TransformerImpl.java, Compiled Code) |
| |
| |
| reporter.logInfoMsg("About to newTransformer(xslBuiltDocFrag)"); |
| transformer = factory.newTransformer(new DOMSource(xslBuiltDocFrag)); |
| reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xslBuiltDocFrag,...) into " + outNames.currentName()); |
| ** @todo Bugzilla#5133 NPE above MOVED to SmoketestOuttakes.java 27-Nov-01 -sc */ |
| } |
| catch (Throwable t) |
| { |
| reporter.checkFail("Problem with various XSL1 elems/documents"); |
| reporter.logThrowable(reporter.ERRORMSG, t, "Problem with various XSL1 elems/documents"); |
| } |
| |
| /* @todo Bugzilla#5133 DOM003 Namespace error below MOVED to SmoketestOuttakes.java 27-Nov-01 -sc |
| //org.w3c.dom.DOMException: DOM003 Namespace error |
| // at org.apache.xerces.dom.AttrNSImpl.<init>(AttrNSImpl.java:134) |
| // at org.apache.xerces.dom.CoreDocumentImpl.createAttributeNS(CoreDocumentImpl.java:1363) |
| // at org.apache.xerces.dom.ElementImpl.setAttributeNS(ElementImpl.java:596) |
| // at org.apache.qetest.xalanj2.ProgrammaticDOMTest.testCase2(ProgrammaticDOMTest.java:355) |
| |
| try |
| { |
| // Startup a factory and docbuilder, create some nodes/DOMs |
| DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance(); |
| dfactory.setNamespaceAware(true); |
| DocumentBuilder docBuilder = dfactory.newDocumentBuilder(); |
| |
| reporter.logTraceMsg("parsing xml file"); |
| Document xmlDoc = docBuilder.parse(new InputSource(testFileInfo.xmlName)); |
| TransformerFactory factory = TransformerFactory.newInstance(); |
| Transformer transformer = null; |
| |
| // Programmatically build the XSL file into an Element and transform |
| Document xslBuiltDoc = docBuilder.newDocument(); |
| // Note: Here, we implicitly already have the outer list |
| // element, so ensure the worker method doesn't add again |
| Element xslBuiltElem = xslBuiltDoc.createElementNS(xslNamespace, "xsl:stylesheet"); |
| xslBuiltElem.setAttributeNS(null, "version", "1.0"); |
| xslBuiltElem.setAttributeNS(nsNamespace, "xmlns:xsl", xslNamespace); |
| appendIdentityDOMXSL(xslBuiltElem, xslBuiltDoc, false); |
| // For debugging, write the generated stylesheet out |
| reporter.logInfoMsg("Writing out xslBuiltElem to "+ outNames.nextName()); |
| transformer = factory.newTransformer(); |
| transformer.transform(new DOMSource(xslBuiltElem), new StreamResult(outNames.currentName())); |
| |
| reporter.logCriticalMsg("//@todo Verify that this is even a valid operation!"); |
| reporter.logInfoMsg("About to newTransformer(xslBuiltElem)"); |
| transformer = factory.newTransformer(new DOMSource(xslBuiltElem)); |
| reporter.logInfoMsg("About to transform(xmlDoc, StreamResult(" + outNames.nextName() + "))"); |
| transformer.transform(new DOMSource(xmlDoc), new StreamResult(outNames.currentName())); |
| fileChecker.check(reporter, |
| new File(outNames.currentName()), |
| new File(testFileInfo.goldName), |
| "transform(xslBuiltElem,...) into " + outNames.currentName()); |
| } |
| catch (Throwable t) |
| { |
| reporter.checkFail("Problem with various XSL2 elems/documents"); |
| reporter.logThrowable(reporter.ERRORMSG, t, "Problem with various XSL2 elems/documents"); |
| } |
| ** @todo Bugzilla#5133 DOM003 Namespace error above MOVED to SmoketestOuttakes.java 27-Nov-01 -sc */ |
| |
| reporter.testCaseClose(); |
| return true; |
| } |
| |
| |
| /** |
| * Adds identity.xml elems to Node passed in. |
| * Subject to change; hackish for now |
| * @author curcuru |
| * @param n Node to append DOM elems to |
| * @param factory Document providing createElement, etc. services |
| * @param useOuterElem if we should append the top-level <list> elem |
| */ |
| public void appendIdentityDOMXML(Node n, Document factory, boolean useOuterElem) |
| { |
| try |
| { |
| Node container = null; |
| if (useOuterElem) |
| { |
| // If asked to, create and append top-level <list> |
| container = factory.createElement("list"); |
| n.appendChild(container); |
| } |
| else |
| { |
| // Otherwise, just use their Node |
| container = n; |
| } |
| container.appendChild(factory.createTextNode("\n ")); |
| |
| Element elemItem = factory.createElement("item"); |
| elemItem.appendChild(factory.createTextNode("Xalan-J 1.x")); |
| container.appendChild(elemItem); |
| container.appendChild(factory.createTextNode("\n ")); |
| |
| elemItem = factory.createElement("item"); |
| elemItem.appendChild(factory.createTextNode("Xalan-J 2.x")); |
| container.appendChild(elemItem); |
| container.appendChild(factory.createTextNode("\n ")); |
| |
| elemItem = factory.createElement("item"); |
| elemItem.appendChild(factory.createTextNode("Xalan-C 1.x")); |
| container.appendChild(elemItem); |
| container.appendChild(factory.createTextNode("\n ")); |
| |
| Element elemInnerList = factory.createElement("list"); |
| container.appendChild(elemInnerList); |
| elemInnerList.appendChild(factory.createTextNode("\n ")); |
| |
| elemItem = factory.createElement("item"); |
| elemItem.appendChild(factory.createTextNode("Xalan documentation")); |
| elemInnerList.appendChild(elemItem); |
| elemInnerList.appendChild(factory.createTextNode("\n ")); |
| |
| elemItem = factory.createElement("item"); |
| elemItem.appendChild(factory.createTextNode("Xalan tests")); |
| elemInnerList.appendChild(elemItem); |
| elemInnerList.appendChild(factory.createTextNode("\n ")); |
| |
| container.appendChild(factory.createTextNode("\n")); |
| } |
| catch (Exception e) |
| { |
| reporter.logErrorMsg("appendDOMTestXML threw: " + e.toString()); |
| reporter.logThrowable(Logger.ERRORMSG, e, "appendDOMTestXML threw"); |
| } |
| } |
| |
| |
| /** |
| * Adds identity.xsl elems to Node passed in. |
| * Subject to change; hackish for now |
| * @author curcuru |
| * @param n Node to append DOM elems to |
| * @param factory Document providing createElement, etc. services |
| * @param useOuterElem if we should append the top-level <stylesheet> elem |
| */ |
| public void appendIdentityDOMXSL(Node n, Document factory, boolean useOuterElem) |
| { |
| try |
| { |
| /// <xsl:template match="@*|node()"> |
| Element template = factory.createElementNS(xslNamespace, "xsl:template"); |
| template.setAttributeNS(null, "match", "@*|node()"); |
| |
| /// <xsl:copy> |
| Element copyElem = factory.createElementNS(xslNamespace, "xsl:copy"); |
| |
| /// <xsl:apply-templates select="@*|node()"/> |
| Element applyTemplatesElem = factory.createElementNS(xslNamespace, "xsl:apply-templates"); |
| applyTemplatesElem.setAttributeNS(null, "select", "@*|node()"); |
| |
| // Stick it all together with faked-up newlines for readability |
| copyElem.appendChild(factory.createTextNode("\n ")); |
| copyElem.appendChild(applyTemplatesElem); |
| copyElem.appendChild(factory.createTextNode("\n ")); |
| |
| template.appendChild(factory.createTextNode("\n ")); |
| template.appendChild(copyElem); |
| template.appendChild(factory.createTextNode("\n")); |
| |
| |
| if (useOuterElem) |
| { |
| // If asked to, create and append top-level <stylesheet> elem |
| /// <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> |
| Element stylesheetElem = factory.createElementNS(xslNamespace, "xsl:stylesheet"); |
| stylesheetElem.setAttributeNS(null, "version", "1.0"); |
| |
| // Following is not officially needed by the DOM, but may help |
| // less-sophisticated DOM readers downstream |
| // Removed due to DOM003 Namespace error |
| // stylesheetElem.setAttributeNS(nsNamespace, "xmlns:xsl", xslNamespace); |
| stylesheetElem.appendChild(template); |
| n.appendChild(stylesheetElem); |
| } |
| else |
| { |
| // Otherwise, just use their Node |
| n.appendChild(template); |
| } |
| |
| } |
| catch (Exception e) |
| { |
| reporter.logErrorMsg("appendIdentityDOMXSL threw: " + e.toString()); |
| reporter.logThrowable(Logger.ERRORMSG, e, "appendIdentityDOMXSL threw"); |
| } |
| } |
| |
| |
| /** |
| * Convenience method to print out usage information - update if needed. |
| * @return String denoting usage of this test class |
| */ |
| public String usage() |
| { |
| return ("Common [optional] options supported by ProgrammaticDOMTest:\n" |
| + "(Note: assumes inputDir=.\\tests\\api)\n" |
| + "REPLACE_any_new_test_arguments\n" |
| + super.usage()); // Grab our parent classes usage as well |
| } |
| |
| |
| /** |
| * Main method to run test from the command line - can be left alone. |
| * @param args command line argument array |
| */ |
| public static void main(String[] args) |
| { |
| ProgrammaticDOMTest app = new ProgrammaticDOMTest(); |
| app.doMain(args); |
| } |
| } |