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