1 package org.apache.qetest.xsl; 2 3 import org.apache.tools.ant.BuildException; 4 import org.apache.tools.ant.Task; 5 import org.apache.tools.ant.types.Commandline; 6 import org.apache.tools.ant.types.CommandlineJava; 7 import org.apache.tools.ant.types.Reference; 8 import org.apache.tools.ant.types.Path; 9 10 import javax.xml.transform.Transformer; 11 import javax.xml.transform.TransformerFactory; 12 import javax.xml.transform.stream.StreamSource; 13 import javax.xml.transform.TransformerConfigurationException; 14 import javax.xml.parsers.DocumentBuilder; 15 import javax.xml.parsers.DocumentBuilderFactory; 16 import javax.xml.xpath.XPath; 17 import javax.xml.xpath.XPathConstants; 18 import javax.xml.xpath.XPathFactory; 19 20 import org.w3c.dom.Document; 21 import org.w3c.dom.Element; 22 import org.w3c.dom.ls.DOMImplementationLS; 23 import org.w3c.dom.ls.LSSerializer; 24 25 import java.io.File; 26 import java.io.IOException; 27 import java.nio.file.Files; 28 import java.nio.file.Paths; 29 import java.util.Map; 30 import java.util.HashMap; 31 import java.util.Set; 32 import java.util.Iterator; 33 34 /* 35 This ant task can, check whether XalanJ's XSLTC processor 36 can compile XSLT stylesheets correctly. 37 38 @author <a href="mailto:mukulg@apache.org">Mukul Gandhi</a> 39 */ 40 public class XsltcTestsTask extends Task { 41 42 private String inputDir; 43 44 private String resultDir; 45 46 private static final String XSLT_FILE_EXT = ".xsl"; 47 48 private static final String expectedTestResultsDoc = "expected_test_results.xml"; 49 50 private static final String testResultsDoc = "actual_test_results.xml"; 51 52 private static final String STYLESHEET_COMPILATION_ERR_MESG = "Could not compile stylesheet"; 53 54 private static final String PASS = "pass"; 55 56 private static final String FAIL = "fail"; 57 58 private CommandlineJava commandLineJava = new CommandlineJava(); 59 60 // method to run this, ant build task execute()61 public void execute() throws BuildException { 62 63 System.setProperty("javax.xml.transform.TransformerFactory", 64 "org.apache.xalan.xsltc.trax.TransformerFactoryImpl"); 65 66 Document expectedTestResultsDocument = getExpectedTestResultsDocument(); 67 68 Map<String, Boolean> testResults = new HashMap<String, Boolean>(); 69 70 File dirObj = new File(this.inputDir); 71 File[] fileList = dirObj.listFiles(); 72 73 boolean isXsltcTestsPassed = true; 74 75 try { 76 for (int idx = 0; idx < fileList.length; idx++) { 77 String fileName = fileList[idx].getName(); 78 if (fileName.endsWith(XSLT_FILE_EXT)) { 79 XsltcTestsErrorListener xsltcTestsErrorListener = new XsltcTestsErrorListener(); 80 compileXslDocument(fileName, xsltcTestsErrorListener); 81 boolean isCompileErrorOccured = STYLESHEET_COMPILATION_ERR_MESG. 82 equals(xsltcTestsErrorListener.getErrListenerMesg()); 83 boolean hasTestPassed = isTestPassed(expectedTestResultsDocument, 84 fileName, isCompileErrorOccured); 85 if (hasTestPassed) { 86 testResults.put(fileName, Boolean.TRUE); 87 } 88 else { 89 testResults.put(fileName, Boolean.FALSE); 90 isXsltcTestsPassed = false; 91 } 92 } 93 } 94 95 serializeTestResultsToXmlDocument(testResults); 96 } 97 catch (Exception ex) { 98 throw new BuildException(ex.getMessage(), location); 99 } 100 101 if (!isXsltcTestsPassed) { 102 throw new BuildException("One or more XSLTC tests have failed. Please fix any XSLTC tests problems, " + 103 "before checking in! XSLTC test results are available at " + resultDir + "/" + 104 testResultsDoc , location); 105 } 106 } 107 setInputDir(String inputDir)108 public void setInputDir(String inputDir) { 109 this.inputDir = inputDir; 110 } 111 setResultDir(String resultDir)112 public void setResultDir(String resultDir) { 113 this.resultDir = resultDir; 114 } 115 116 /** 117 * Set the bootclasspathref to be used for this test. 118 * 119 * @param bootclasspathref used for running the test 120 */ setBootclasspathref(Reference ref)121 public void setBootclasspathref(Reference ref) 122 { 123 String jdkRelease = 124 System.getProperty("java.version", "0.0").substring(0,3); 125 if (!jdkRelease.equals("1.1") 126 && !jdkRelease.equals("1.2") 127 && !jdkRelease.equals("1.3")) { 128 Path p = (Path)ref.getReferencedObject(this.getProject()); 129 createJvmarg().setValue("-Xbootclasspath/p:" + p); 130 } 131 } 132 133 /** 134 * Creates a nested jvmarg element. 135 * 136 * @return Argument to send to our JVM if forking 137 */ createJvmarg()138 public Commandline.Argument createJvmarg() 139 { 140 return commandLineJava.createVmArgument(); 141 } 142 143 /* 144 This method, attempts to compile an XSLT stylesheet. If the stylesheet 145 cannot be compiled, the registered error listener sets the resulting 146 error message within a variable. 147 */ compileXslDocument(String xslName, XsltcTestsErrorListener xsltcTestsErrorListener)148 private void compileXslDocument(String xslName, XsltcTestsErrorListener 149 xsltcTestsErrorListener) { 150 try { 151 TransformerFactory trfFactory = TransformerFactory.newInstance(); 152 trfFactory.setErrorListener(xsltcTestsErrorListener); 153 Transformer transformer = trfFactory.newTransformer( 154 new StreamSource(this.inputDir + "/" + xslName)); 155 } 156 catch (Exception ex) { 157 // NO OP 158 } 159 } 160 161 /* 162 An expected tests results document, is already available before running 163 this ant task. This method, returns an XML DOM representation of that 164 XML document. 165 */ getExpectedTestResultsDocument()166 private Document getExpectedTestResultsDocument() { 167 Document xmlResultDocument = null; 168 169 try { 170 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 171 DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 172 xmlResultDocument = docBuilder.parse(this.inputDir + "/" + expectedTestResultsDoc); 173 } 174 catch (Exception ex) { 175 throw new BuildException(ex.getMessage(), location); 176 } 177 178 return xmlResultDocument; 179 } 180 181 /* 182 This method, checks whether an XSLTC test that has been run, 183 has passed or not. 184 */ isTestPassed(Document expectedTestResultsDoc, String xslFileName, boolean isCompileErrorOccured)185 private boolean isTestPassed(Document expectedTestResultsDoc, 186 String xslFileName, boolean isCompileErrorOccured) 187 throws Exception { 188 XPath xPath = XPathFactory.newInstance().newXPath(); 189 String isCompileErrorOccuredStr = (new Boolean(isCompileErrorOccured)).toString(); 190 String xpathExprStr = "/expectedResults/file[@name = '" + xslFileName + "' and " + 191 "compileError = '" + isCompileErrorOccuredStr + "']/expected"; 192 String xpathNodeStrValue = (String)((xPath.compile(xpathExprStr)). 193 evaluate(expectedTestResultsDoc, 194 XPathConstants.STRING)); 195 return PASS.equals(xpathNodeStrValue) ? true : false; 196 } 197 198 /* 199 Given XSLTC overall test results, produced by this class (available as Map object), 200 this method serializes those results to an XML document. 201 */ serializeTestResultsToXmlDocument(Map testResultsMap)202 private void serializeTestResultsToXmlDocument(Map testResultsMap) 203 throws Exception { 204 Set<Map.Entry<String,Boolean>> mapEntries = testResultsMap.entrySet(); 205 Iterator<Map.Entry<String,Boolean>> iter = mapEntries.iterator(); 206 207 DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance(); 208 DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder(); 209 Document resultDocument = docBuilder.newDocument(); 210 211 Element testResultsElem = resultDocument.createElement("testResults"); 212 while (iter.hasNext()) { 213 Map.Entry<String,Boolean> mapEntry = iter.next(); 214 String fileName = mapEntry.getKey(); 215 Boolean passStatus = mapEntry.getValue(); 216 217 Element resultElem = resultDocument.createElement("result"); 218 Element fileNameElem = resultDocument.createElement("fileName"); 219 fileNameElem.appendChild(resultDocument.createTextNode(fileName)); 220 resultElem.appendChild(fileNameElem); 221 Element statusElem = resultDocument.createElement("status"); 222 statusElem.appendChild(resultDocument.createTextNode(passStatus == 223 Boolean.TRUE ? "pass" : "fail")); 224 resultElem.appendChild(statusElem); 225 226 testResultsElem.appendChild(resultElem); 227 } 228 229 resultDocument.appendChild(testResultsElem); 230 231 DOMImplementationLS domImplementation = (DOMImplementationLS) 232 resultDocument.getImplementation(); 233 LSSerializer lsSerializer = domImplementation.createLSSerializer(); 234 (lsSerializer.getDomConfig()).setParameter("format-pretty-print", Boolean.TRUE); 235 String resultDocumentXmlStr = lsSerializer.writeToString(resultDocument); 236 237 Files.write(Paths.get(resultDir + "/" + testResultsDoc), 238 resultDocumentXmlStr.getBytes()); 239 } 240 241 } 242