/*
* 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 java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import jaxp.library.JAXPFileBaseTest;
import static jaxp.library.JAXPTestUtilities.filenameToURL;
import static org.apache.qetest.trax.TraxConst.XML_DIR;
import static jaxp.library.JAXPTestUtilities.getNextFile;
import static org.testng.Assert.assertTrue;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
/**
* Functional test of various usages of parameters in transforms.
*/
public class ParameterTest extends JAXPFileBaseTest {
/**
* Test XSL file.
*/
private static final String XSLT_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest.xsl");
/**
* Test XML file.
*/
private static final String XML_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest.xml");
/**
* Test XSL file.
*/
private static final String SIMPLE_XSLT_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest2.xsl");
/**
* Test XML file.
*/
private static final String SIMPLE_XML_TEST_FILE = filenameToURL(XML_DIR + "ParameterTest2.xml");
/**
* Test Parameters.
*/
private static final String[][] PARAMETERS
= {
{
"t1",
"'a'",
"false-notset,false-blank,false-a,false-1,'a'",
"(10)Select expr of a 'param' string"
},
{
"t1",
"a",
"false-notset,false-blank,true-a,false-1,a",
"(10a)Select expr of a param string"
},
{
"t1",
"'1'",
"false-notset,false-blank,false-a,false-1,'1'",
"(11)Select expr of a 'param' number"
},
{
"t1",
"1",
"false-notset,false-blank,false-a,true-1,1",
"(11a)Select expr of a param number"
},
{
"t1",
"''",
"false-notset,false-blank,false-a,false-1,''",
"(12)Select expr of a param 'blank' string"
},
{
"t1",
"",
"false-notset,true-blank,false-a,false-1,",
"(12a)Select expr of a param blank string"
},
{
"p1",
"'foo'",
"'foo','foo';",
"(13)Stylesheet with literal 'param' value"
},
{
"p1",
"foo",
"foo,foo;",
"(13a)Stylesheet with literal param value"
},
{
"p1",
"'bar'",
"'bar','bar';",
"(14)Stylesheet with replaced/another literal 'param' value"
},
{
"p1",
"bar",
"bar,bar;",
"(14a)Stylesheet with replaced/another literal param value"
},
{
"p2",
"'<item>bar</item>'",
"'<item>bar</item>','<item>bar</item>'; GHI,GHI; ",
"(15)Stylesheet with 'param' value with nodes"
},
{
"p2",
"<item>bar</item>",
"<item>bar</item>,<item>bar</item>;",
"(15a)Stylesheet with param value with nodes"
},
{
"p3",
"'foo3'",
"DEF,DEF;",
"(16)Stylesheet with literal 'param' value in a template, is not passed"
},
{
"p3",
"foo3",
"DEF,DEF;",
"(16a)Stylesheet with literal param value in a template, is not passed"
},
{
"s1",
"'foos'",
"'foos','foos';",
"(17)Stylesheet with literal 'param' select"
},
{
"s1",
"foos",
"foos,foos;",
"(17a)Stylesheet with literal param select"
},
{
"s1",
"'bars'",
"'bars','bars'; s2val,s2val; s3val,s3val; ",
"(18)Stylesheet with replaced/another literal 'param' select"
},
{
"s1",
"bars",
"bars,bars; s2val,s2val; s3val,s3val; ",
"(18a)Stylesheet with replaced/another literal param select"
},
{
"s2",
"'<item/>'",
"'<item/>','<item/>'; s3val,s3val; ",
"(19)Stylesheet with nodes(?) 'param' select"
},
{
"s2",
"<item/>",
"<item/>,<item/>; s3val,s3val; ",
"(19a)Stylesheet with nodes(?) param select"
}
};
@DataProvider
public Object[][] parameters() {
return Arrays.stream(PARAMETERS).map(ps -> new Object[]{
ps[0], ps[1], new StreamSource(XML_TEST_FILE),
new StreamSource(XSLT_TEST_FILE), ps[2]
}).toArray(Object[][]::new);
}
/**
* Reuse the same transformer multiple times with parameters set.
* @throws TransformerException If an unrecoverable error occurs during the
* course of the transformation.
* @throws IOException if any I/O operation error.
*/
@Test
public void reuseParametersTest() throws TransformerException, IOException {
Transformer transformer = TransformerFactory.newInstance()
.newTemplates(new StreamSource(SIMPLE_XSLT_TEST_FILE))
.newTransformer();
String outputFile1 = getNextFile(this.getClass());
transformer.transform(new StreamSource(XML_TEST_FILE),
new StreamResult(outputFile1));
// Verify the values are correct for no params set
checkFileContains(outputFile1, "ParameterTest.xml:");
String outputFile2 = getNextFile(this.getClass());
transformer.transform(new StreamSource(SIMPLE_XML_TEST_FILE),
new StreamResult(outputFile2));
// Do NOT call clear Parameters here; reuse the transformer
checkFileContains(outputFile2, "ParameterTest.xml:");
String outputFile3 = getNextFile(this.getClass());
transformer.transform(new StreamSource(XML_TEST_FILE),
new StreamResult(outputFile3));
// Do NOT call clearParameters here; reuse the transformer
transformer.transform(new StreamSource(XML_TEST_FILE),
new StreamResult(outputFile3));
}
/**
* Test setting a single string-valued parameter.
* Uses the supplied Transformer and calls setParameter()
* then transform(Source, Source), then uses the worker
* method checkFileContains() to validate and output results.
*
* @param paramName simple name of parameter
* @param paramVal String value of parameter
* @param transformer object to use
* @param xmlSource object to use in transform
* @param checkString to look for in output file (logged)
*/
private void testSetParam(String paramName, String paramVal,
Transformer transformer, Source xmlSource, String checkString)
throws TransformerException, IOException {
String outputFile = getNextFile(this.getClass());
transformer.setParameter(paramName, paramVal);
transformer.transform(xmlSource, new StreamResult(outputFile));
assertTrue(checkFileContains(outputFile, checkString));
}
/**
* Test setting a single string-valued parameter.
* Creates a Transformer and calls setParameter()
* then transform(Source, Source), then uses the worker
* method checkFileContains() to validate and output results.
*
* @param paramName simple name of parameter
* @param paramVal String value of parameter
* @param xmlSource object to use in transform
* @param xslStylesheet object to use in transform
* @param checkString to look for in output file (logged)
* @throws javax.xml.transform.TransformerConfigurationException
* @throws IOException if any I/O operation error.
*/
@Test(dataProvider = "parameters")
public void testSetParam(String paramName, String paramVal,
Source xmlSource, Source xslStylesheet, String checkString)
throws TransformerException, IOException {
testSetParam(paramName, paramVal,
TransformerFactory.newInstance().newTransformer(xslStylesheet),
xmlSource, checkString);
}
/**
* Setting various string-valued parameters and reusing transformers.
* Creates one transformer first, then loops through array
* of simple test data re-using 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 reuseTestParams() throws IOException, TransformerException {
Transformer transformer = TransformerFactory.newInstance()
.newTemplates(new StreamSource(XSLT_TEST_FILE))
.newTransformer();
String outputFile = getNextFile(this.getClass());
transformer.transform(new StreamSource(XML_TEST_FILE),
new StreamResult(outputFile));
transformer.clearParameters();
// Verify each of the three kinds of params are correct
assertTrue(checkFileContains(outputFile, "ABC,ABC; DEF,DEF; GHI,GHI; "));
assertTrue(checkFileContains(outputFile, "s1val,s1val; s2val,s2val; s3val,s3val; "));
assertTrue(checkFileContains(outputFile, "true-notset,false-blank,false-a,false-1,notset"));
Arrays.stream(PARAMETERS).forEach(ps -> {
try {
testSetParam(ps[0], ps[1], new StreamSource(XML_TEST_FILE),
new StreamSource(XSLT_TEST_FILE), ps[2]);
} catch (TransformerException | IOException ex) {
throw new RuntimeException(ex);
}
});
}
/**
* Checks if a file contains a certain string (all within one line).
* We should really consider validating the entire output file, but
* this is the important functionality, and it makes maintaining the
* test and gold data easier (since it's all in this file).
*
* @param file local path/name of file to check.
* @param checkStr String to look for in the file.
* @return true if file contain checkStr
* false if file doesn't contain checkStr.
* @throws IOException if any wrong with I/O operation.
*/
protected boolean checkFileContains(String file, String checkStr) throws IOException {
return Files.readAllLines(Paths.get(file)).stream()
.anyMatch(s -> s.contains(checkStr));
}
}