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.FileInputStream;
  23 import java.io.FileOutputStream;
  24 import java.io.FilePermission;
  25 import java.io.IOException;
  26 import javax.xml.parsers.DocumentBuilderFactory;
  27 import javax.xml.parsers.ParserConfigurationException;
  28 import javax.xml.transform.Source;
  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.TransformerFactoryConfigurationError;
  34 import javax.xml.transform.dom.DOMSource;
  35 import javax.xml.transform.stream.StreamResult;
  36 import javax.xml.transform.stream.StreamSource;
  37 import jaxp.library.JAXPBaseTest;
  38 import static jaxp.library.JAXPTestUtilities.CLASS_DIR;
  39 import static jaxp.library.JAXPTestUtilities.compareWithGold;
  40 import static jaxp.library.JAXPTestUtilities.filenameToURL;
  41 import static org.apache.qetest.trax.TraxConst.GOLDEN_DIR;
  42 import static org.apache.qetest.trax.TraxConst.XML_DIR;
  43 import static jaxp.library.JAXPTestUtilities.getNextFile;
  44 import static org.testng.Assert.assertEquals;
  45 import static org.testng.Assert.assertFalse;
  46 import static org.testng.Assert.assertNotNull;
  47 import static org.testng.Assert.assertNull;
  48 import static org.testng.Assert.assertTrue;
  49 import org.testng.annotations.AfterGroups;
  50 import org.testng.annotations.BeforeGroups;
  51 import org.testng.annotations.Test;
  52 import org.xml.sax.SAXException;
  53 
  54 /**
  55  * API Coverage test for TransformerFactory class of TRAX.
  56  */
  57 public class TransformerFactoryAPITest extends JAXPBaseTest {
  58     /**
  59      * Cached system property.
  60      */
  61     private final String cachedSysProp = null;
  62 
  63     /**
  64      * System property name, from TransformerFactory.
  65      */
  66     private static final String DEFAULT_PROP_NAME = "javax.xml.transform.TransformerFactory";
  67     
  68     /**
  69      * Stored system property name for TransformerFactory. 
  70      */
  71     private String factory_prop_value;
  72 
  73     /**
  74      * System property name for Xalan-J 2.x impl.
  75      */
  76     private static final String XALAN_CLASSNAME = "org.apache.xalan.processor.TransformerFactoryImpl";
  77     
  78     /**
  79      * Test XSLT file name.
  80      */
  81     private static final String XSL_URI = filenameToURL(XML_DIR + "identity.xsl");
  82 
  83     /**
  84      * Test XML file name.
  85      */
  86     private static final String EMBEDDED_XML = XML_DIR + "embeddedIdentity.xml"; 
  87 
  88     /**
  89      * Test XML uri.
  90      */
  91     private static final String EMBEDDED_XML_URI = filenameToURL(EMBEDDED_XML);
  92     
  93     /**
  94      * Golden file name.
  95      */
  96     private static final String EMBEDDED_GOLD_FILE = GOLDEN_DIR + "embeddedIdentity.out";
  97     
  98     /**
  99      * invalid feature/attribute name for negative test. 
 100      */
 101     private static final String BOGUS_NAME = "fnord:this/feature/does/not/exist";
 102 
 103     /**
 104      * Coverage tests for factory pattern API's.
 105      */
 106     @Test
 107     public void testCase1() {
 108         // Reset the system property to what was cached previously
 109         // test when system property is null
 110         setSystemProperty(DEFAULT_PROP_NAME, null);
 111         assertNotNull(TransformerFactory.newInstance());
 112         // This should come last so it will stay set for the rest of the test
 113         // Note: this needs review, since in the future we may
 114         //  not guaruntee order of testCase execution!
 115         setSystemProperty(DEFAULT_PROP_NAME, cachedSysProp);
 116         assertNotNull(TransformerFactory.newInstance());
 117     }
 118     
 119     /**
 120      * Save system property for restoring.
 121      */
 122     @BeforeGroups (groups = {"systemProp"})
 123     public void saveProp() {
 124         factory_prop_value = getSystemProperty(DEFAULT_PROP_NAME);
 125     }
 126     
 127     /**
 128      * Restore the system property.
 129      */
 130     @AfterGroups (groups = {"systemProp"})
 131     public void restoreProp() {
 132         setSystemProperty(DEFAULT_PROP_NAME, factory_prop_value);
 133     }
 134 
 135     /**
 136      * TransformerFactoryConfigurationError is thrown when system property is a
 137      * bogus name.
 138      */
 139     @Test(groups = {"systemProp"}, expectedExceptions = TransformerFactoryConfigurationError.class)
 140     public void negativeTestCase1() {
 141         setSystemProperty(DEFAULT_PROP_NAME, "this.class.does.not.exist");
 142         TransformerFactory.newInstance();
 143     }
 144 
 145     /**
 146      * TransformerFactoryConfigurationError is thrown when system property is
 147      * another kind of class name.
 148      */
 149     @Test(groups = {"systemProp"}, expectedExceptions = TransformerFactoryConfigurationError.class)
 150     public void negativeTestCase2() {
 151         setSystemProperty(DEFAULT_PROP_NAME, "java.lang.String");
 152         TransformerFactory.newInstance();
 153     }
 154     
 155     
 156 
 157     /**
 158      * Coverage tests for newTransformer() API's.
 159      * 
 160      * @throws TransformerConfigurationException Thrown in case of 
 161      *         ServiceConfigurationError service configuration error or if the
 162      *         implementation is not available or cannot be instantiated.
 163      */
 164     @Test
 165     public void testCase2() throws TransformerConfigurationException {
 166         setPermissions(new FilePermission(XML_DIR + "/-", "read"));
 167         TransformerFactory factory = TransformerFactory.newInstance();
 168         Transformer identityTransformer = factory.newTransformer();
 169         assertNotNull(identityTransformer);
 170 
 171         assertTrue(factory.getFeature(StreamSource.FEATURE));
 172         assertNotNull(factory.newTransformer(new StreamSource(XSL_URI)));
 173         setPermissions();
 174     }
 175 
 176     /**
 177      * Coverage tests for newTemplates() API's.
 178      * 
 179      * @throws TransformerConfigurationException Thrown in case of 
 180      *         ServiceConfigurationError service configuration error or if the
 181      *         implementation is not available or cannot be instantiated.
 182      */
 183     @Test
 184     public void testCase3() throws TransformerConfigurationException {
 185         setPermissions(new FilePermission(XML_DIR + "/-", "read"));
 186         TransformerFactory factory = TransformerFactory.newInstance();
 187         assertNotNull(factory.getFeature(StreamSource.FEATURE));
 188         assertNotNull(factory.newTemplates(new StreamSource(XSL_URI)));
 189         setPermissions();
 190     }
 191 
 192     /**
 193      * Coverage tests for getAssociatedStylesheet() API's.
 194      * 
 195      * @throws IOException if any I/O operation error.
 196      * @throws TransformerException If an unrecoverable error occurs during the 
 197      *         course of the transformation.
 198      */
 199     @Test
 200     public void testCase4() throws IOException, TransformerException{   
 201         setPermissions(new FilePermission(XML_DIR + "/-", "read"),
 202                 new FilePermission(GOLDEN_DIR + "/-", "read"),
 203                 new FilePermission(CLASS_DIR + "-", "read, write"));
 204         String outputFile = getNextFile(this.getClass());
 205         try (FileOutputStream resultStream = new FileOutputStream(getNextFile(this.getClass()))){
 206             TransformerFactory factory = TransformerFactory.newInstance();
 207             // Get the xml-stylesheet and process it
 208             Source stylesheet = factory.getAssociatedStylesheet(
 209                     new StreamSource(EMBEDDED_XML_URI), null, null, null);
 210             assertTrue(stylesheet instanceof Source);
 211             assertNotNull(stylesheet);
 212 
 213             Transformer transformer = factory.newTransformer(stylesheet);
 214             transformer.transform(new StreamSource(EMBEDDED_XML_URI), 
 215                     new StreamResult(resultStream));
 216         }
 217         assert(compareWithGold(EMBEDDED_GOLD_FILE, outputFile));
 218         setPermissions();
 219     }
 220 
 221     /**
 222      * Coverage tests for get/setURIResolver(), get/setErrorListener() API's.
 223      */
 224     @Test
 225     public void testCase5() {
 226         TransformerFactory factory = TransformerFactory.newInstance();
 227         assertNull(factory.getURIResolver());
 228         CheckingURIResolver loggingURIRes = new CheckingURIResolver();
 229         factory.setURIResolver(loggingURIRes);
 230         assertEquals(factory.getURIResolver(), loggingURIRes);
 231         factory.setURIResolver(null);
 232         assertNull(factory.getURIResolver());
 233         assertNotNull(factory.getErrorListener());
 234         CheckingErrorListener loggingErrListener = new CheckingErrorListener();
 235         factory.setErrorListener(loggingErrListener);
 236         assertEquals(factory.getErrorListener(), loggingErrListener);
 237     }
 238 
 239     /**
 240      * IAE is thrown when setErrorListener(null).
 241      */
 242     @Test(expectedExceptions = IllegalArgumentException.class)
 243     public void testNegativeCase5() {
 244         TransformerFactory factory = TransformerFactory.newInstance();
 245         factory.setErrorListener(null);
 246     }
 247     
 248     /**
 249      * Miscellaneous tests.
 250      * @throws TransformerConfigurationException An Exception is thrown if an 
 251      *         error occurs during parsing of the source. 
 252      * @throws ParserConfigurationException if the implementation is not 
 253      *         available or cannot be instantiated. 
 254      * @throws SAXException If any parse errors occur. 
 255      * @throws IOException If any I/O errors occur. 
 256      */
 257     @Test
 258     public void associateSourceTest() throws ParserConfigurationException, SAXException, 
 259             IOException, TransformerConfigurationException {
 260         setPermissions(new FilePermission(XML_DIR + "/-", "read"));
 261         TransformerFactory factory = TransformerFactory.newInstance();
 262         DOMSource domsource = new DOMSource(DocumentBuilderFactory.
 263                 newInstance().newDocumentBuilder().parse(EMBEDDED_XML));
 264         assertNull(factory.getAssociatedStylesheet(domsource,"screen","Modern",null));
 265        
 266         try(FileInputStream fis = new FileInputStream(EMBEDDED_XML)) {
 267             StreamSource ss = new StreamSource(fis);
 268             assertNull(factory.getAssociatedStylesheet(ss,"screen","Modern",null));
 269         }
 270        
 271         try(FileInputStream fis = new FileInputStream(EMBEDDED_XML)) {
 272             StreamSource ss = new StreamSource(fis);
 273             ss.setSystemId(EMBEDDED_XML_URI);
 274             assertNull(factory.getAssociatedStylesheet(ss,"screen","Modern",null));
 275         }
 276         setPermissions();
 277     }
 278     
 279     /**
 280      * Test if factory supports valid features and doesn't support invalid 
 281      * features.
 282      */
 283     @Test
 284     public void getFeaturesTest() {
 285         TransformerFactory factory = TransformerFactory.newInstance();
 286         // Expected no NPE here.
 287         assertFalse(factory.getFeature(BOGUS_NAME));
 288         
 289         assertTrue(factory.getFeature(StreamSource.FEATURE));
 290         assertTrue(factory.getFeature(StreamResult.FEATURE));
 291     }
 292 
 293     /**
 294      * IllegalArgumentException is thrown when implementation does not recognize
 295      * the attribute.
 296      */
 297     @Test(expectedExceptions = IllegalArgumentException.class)
 298     public void bogusSetFeatures() {
 299         TransformerFactory factory = TransformerFactory.newInstance();
 300         factory.setAttribute(BOGUS_NAME, "on");
 301     }
 302 }