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.IOException;
  23 import java.nio.file.Files;
  24 import java.nio.file.Paths;
  25 import java.util.Arrays;
  26 import javax.xml.transform.Source;
  27 import javax.xml.transform.Transformer;
  28 import javax.xml.transform.TransformerException;
  29 import javax.xml.transform.TransformerFactory;
  30 import javax.xml.transform.stream.StreamResult;
  31 import javax.xml.transform.stream.StreamSource;
  32 import jaxp.library.JAXPFileBaseTest;
  33 import static jaxp.library.JAXPTestUtilities.filenameToURL;
  34 import static org.apache.qetest.trax.TraxConst.XML_DIR;
  35 import static jaxp.library.JAXPTestUtilities.getNextFile;
  36 import static org.testng.Assert.assertTrue;
  37 import org.testng.annotations.DataProvider;
  38 import org.testng.annotations.Test;
  39 
  40 /**
  41  * Functional test of various usages of parameters in transforms.
  42  */
  43 public class ParameterTest extends JAXPFileBaseTest {
  44     /**
  45      * Test XSL file.
  46      */
  47     private static final String XSLT_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest.xsl");
  48 
  49     /**
  50      * Test XML file.
  51      */
  52     private static final String XML_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest.xml");
  53 
  54     /**
  55      * Test XSL file.
  56      */
  57     private static final String SIMPLE_XSLT_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest2.xsl");
  58 
  59     /**
  60      * Test XML file.
  61      */
  62     private static final String SIMPLE_XML_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest2.xml");
  63 
  64     /**
  65      * Test Parameters.
  66      */
  67     private static final String[][] PARAMETERS
  68         = {
  69             {
  70                 "t1",
  71                 "'a'",
  72                 "<outt>false-notset,false-blank,false-a,false-1,'a'</outt>",
  73                 "(10)Select expr of a 'param' string"
  74             },
  75             {
  76                 "t1",
  77                 "a",
  78                 "<outt>false-notset,false-blank,true-a,false-1,a</outt>",
  79                 "(10a)Select expr of a param string"
  80             },
  81             {
  82                 "t1",
  83                 "'1'",
  84                 "<outt>false-notset,false-blank,false-a,false-1,'1'</outt>",
  85                 "(11)Select expr of a 'param' number"
  86             },
  87             {
  88                 "t1",
  89                 "1",
  90                 "<outt>false-notset,false-blank,false-a,true-1,1</outt>",
  91                 "(11a)Select expr of a param number"
  92             },
  93             {
  94                 "t1",
  95                 "''",
  96                 "<outt>false-notset,false-blank,false-a,false-1,''</outt>",
  97                 "(12)Select expr of a param 'blank' string"
  98             },
  99             {
 100                 "t1",
 101                 "",
 102                 "<outt>false-notset,true-blank,false-a,false-1,</outt>",
 103                 "(12a)Select expr of a param blank string"
 104             },
 105             {
 106                 "p1",
 107                 "'foo'",
 108                 "'foo','foo';",
 109                 "(13)Stylesheet with literal 'param' value"
 110             },
 111             {
 112                 "p1",
 113                 "foo",
 114                 "foo,foo;",
 115                 "(13a)Stylesheet with literal param value"
 116             },
 117             {
 118                 "p1",
 119                 "'bar'",
 120                 "'bar','bar';",
 121                 "(14)Stylesheet with replaced/another literal 'param' value"
 122             },
 123             {
 124                 "p1",
 125                 "bar",
 126                 "bar,bar;",
 127                 "(14a)Stylesheet with replaced/another literal param value"
 128             },
 129             {
 130                 "p2",
 131                 "'&lt;item&gt;bar&lt;/item&gt;'",
 132                 "'&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;','&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;'; GHI,<B>GHI</B>; </outp>",
 133                 "(15)Stylesheet with 'param' value with nodes"
 134             },
 135             {
 136                 "p2",
 137                 "&lt;item&gt;bar&lt;/item&gt;",
 138                 "&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;,&amp;lt;item&amp;gt;bar&amp;lt;/item&amp;gt;;",
 139                 "(15a)Stylesheet with param value with nodes"
 140             },
 141             {
 142                 "p3",
 143                 "'foo3'",
 144                 "DEF,<B>DEF</B>;",
 145                 "(16)Stylesheet with literal 'param' value in a template, is not passed"
 146             },
 147             {
 148                 "p3",
 149                 "foo3",
 150                 "DEF,<B>DEF</B>;",
 151                 "(16a)Stylesheet with literal param value in a template, is not passed"
 152             },
 153             {
 154                 "s1",
 155                 "'foos'",
 156                 "'foos','foos';",
 157                 "(17)Stylesheet with literal 'param' select"
 158             },
 159             {
 160                 "s1",
 161                 "foos",
 162                 "foos,foos;",
 163                 "(17a)Stylesheet with literal param select"
 164             },
 165             {
 166                 "s1",
 167                 "'bars'",
 168                 "<outs>'bars','bars'; s2val,s2val; s3val,s3val; </outs>",
 169                 "(18)Stylesheet with replaced/another literal 'param' select"
 170             },
 171             {
 172                 "s1",
 173                 "bars",
 174                 "<outs>bars,bars; s2val,s2val; s3val,s3val; </outs>",
 175                 "(18a)Stylesheet with replaced/another literal param select"
 176             },
 177             {
 178                 "s2",
 179                 "'&lt;item/&gt;'",
 180                 "'&amp;lt;item/&amp;gt;','&amp;lt;item/&amp;gt;'; s3val,s3val; </outs>",
 181                 "(19)Stylesheet with nodes(?) 'param' select"
 182             },
 183             {
 184                 "s2",
 185                 "&lt;item/&gt;",
 186                 "&amp;lt;item/&amp;gt;,&amp;lt;item/&amp;gt;; s3val,s3val; </outs>",
 187                 "(19a)Stylesheet with nodes(?) param select"
 188             }
 189     };
 190     
 191     @DataProvider
 192     public Object[][] parameters() {
 193         return Arrays.stream(PARAMETERS).map(ps -> new Object[]{
 194             ps[0], ps[1], new StreamSource(XML_TEST_FILE), 
 195             new StreamSource(XSLT_TEST_FILE), ps[2]
 196         }).toArray(Object[][]::new);
 197     }
 198 
 199     /**
 200      * Reuse the same transformer multiple times with parameters set.
 201      * @throws Exception If any errors occur.
 202      */
 203     @Test
 204     public void reuseParametersTest() throws Exception {
 205         Transformer transformer = TransformerFactory.newInstance()
 206                 .newTemplates(new StreamSource(SIMPLE_XSLT_TEST_FILE))
 207                 .newTransformer();
 208         String outputFile1 = getNextFile(this.getClass());
 209         transformer.transform(new StreamSource(XML_TEST_FILE),
 210                 new StreamResult(outputFile1));
 211         // Verify the values are correct for no params set
 212         checkFileContains(outputFile1, "<globalVarAttr>ParameterTest.xml:</globalVarAttr>");
 213         String outputFile2 = getNextFile(this.getClass());
 214         transformer.transform(new StreamSource(SIMPLE_XML_TEST_FILE),
 215                 new StreamResult(outputFile2));
 216         // Do NOT call clear Parameters here; reuse the transformer
 217         checkFileContains(outputFile2, "<globalVarAttr>ParameterTest.xml:</globalVarAttr>");
 218         String outputFile3 = getNextFile(this.getClass());
 219         transformer.transform(new StreamSource(XML_TEST_FILE),
 220                 new StreamResult(outputFile3));
 221         // Do NOT call clearParameters here; reuse the transformer
 222         transformer.transform(new StreamSource(XML_TEST_FILE),
 223                 new StreamResult(outputFile3));
 224     }
 225 
 226     /**
 227      * Test setting a single string-valued parameter.
 228      * Uses the supplied Transformer and calls setParameter()
 229      * then transform(Source, Source), then uses the worker
 230      * method checkFileContains() to validate and output results.
 231      *
 232      * @param paramName simple name of parameter
 233      * @param paramVal String value of parameter
 234      * @param transformer object to use
 235      * @param xmlSource object to use in transform
 236      * @param checkString to look for in output file (logged)
 237      */
 238     private void testSetParam(String paramName, String paramVal,
 239             Transformer transformer, Source xmlSource, String checkString) 
 240             throws TransformerException, IOException {
 241         String outputFile = getNextFile(this.getClass());
 242 
 243         transformer.setParameter(paramName, paramVal);
 244         transformer.transform(xmlSource, new StreamResult(outputFile));
 245         assertTrue(checkFileContains(outputFile, checkString));
 246     }
 247 
 248     /**
 249      * Test setting a single string-valued parameter.
 250      * Creates a Transformer and calls setParameter()
 251      * then transform(Source, Source), then uses the worker
 252      * method checkFileContains() to validate and output results.
 253      *
 254      * @param paramName simple name of parameter
 255      * @param paramVal String value of parameter
 256      * @param xmlSource object to use in transform
 257      * @param xslStylesheet object to use in transform
 258      * @param checkString to look for in output file (logged)
 259      * @throws Exception If any errors occur.
 260      */
 261     @Test(dataProvider = "parameters")
 262     public void testSetParam(String paramName, String paramVal, 
 263             Source xmlSource, Source xslStylesheet, String checkString) 
 264             throws Exception {
 265         testSetParam(paramName, paramVal,
 266             TransformerFactory.newInstance().newTransformer(xslStylesheet),
 267                 xmlSource, checkString);
 268     }
 269     
 270     /**
 271      * Setting various string-valued parameters and reusing transformers.
 272      * Creates one transformer first, then loops through array
 273      * of simple test data re-using transformer.
 274      * @throws IOException if any I/O operation error.
 275      * @throws TransformerException If an unrecoverable error occurs during the 
 276      *         course of the transformation.
 277      */
 278     @Test
 279     public void reuseTestParams() throws IOException, TransformerException {
 280         Transformer transformer = TransformerFactory.newInstance()
 281                 .newTemplates(new StreamSource(XSLT_TEST_FILE))
 282                 .newTransformer();
 283         String outputFile = getNextFile(this.getClass());
 284         transformer.transform(new StreamSource(XML_TEST_FILE),
 285                 new StreamResult(outputFile));
 286         transformer.clearParameters();
 287         // Verify each of the three kinds of params are correct
 288         assertTrue(checkFileContains(outputFile, "<outp>ABC,<B>ABC</B>; DEF,<B>DEF</B>; GHI,<B>GHI</B>; </outp>"));
 289         assertTrue(checkFileContains(outputFile, "<outs>s1val,s1val; s2val,s2val; s3val,s3val; </outs>"));
 290         assertTrue(checkFileContains(outputFile, "<outt>true-notset,false-blank,false-a,false-1,notset</outt>"));
 291         Arrays.stream(PARAMETERS).forEach(ps -> {
 292             try {
 293                 testSetParam(ps[0], ps[1], new StreamSource(XML_TEST_FILE),
 294                         new StreamSource(XSLT_TEST_FILE), ps[2]);
 295             } catch (Exception ex) {
 296                 throw new RuntimeException(ex);
 297             }
 298         });
 299     }
 300     
 301 
 302     
 303     /**
 304      * Checks if a file contains a certain string (all within one line).
 305      * We should really consider validating the entire output file, but
 306      * this is the important functionality, and it makes maintaining the
 307      * test and gold data easier (since it's all in this file).
 308      *
 309      * @param file local path/name of file to check.
 310      * @param checkStr String to look for in the file.
 311      * @return true if file contain checkStr
 312      *         false if file doesn't contain checkStr.
 313      * @throws IOException if any wrong with I/O operation.
 314      */
 315     protected boolean checkFileContains(String file, String checkStr) throws IOException {
 316         return Files.readAllLines(Paths.get(file)).stream()
 317                 .anyMatch(s -> s.contains(checkStr));
 318     }
 319 }