Transform EARL result into HTML report using XSLT.

@param outputDir
162662
public void earlHtmlReport( String outputDir ) {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        String resourceDir = cl.getResource( "com/occamlab/te/earl/lib" ).getPath();
        String earlXsl = cl.getResource( "com/occamlab/te/earl_html_report.xsl" ).toString();
        File htmlOutput = new File( outputDir, "result" );
        htmlOutput.mkdir();

        File earlResult = findEarlResultFile( outputDir );
        LOGR.log( FINE, "Try to transform earl result file '" + earlResult + "' to directory " + htmlOutput );

        try {
            if ( earlResult != null && earlResult.exists() ) {
                Transformer transformer = TransformerFactory.newInstance().newTransformer( new StreamSource( earlXsl ) );
                transformer.setParameter( "outputDir", htmlOutput );
                File indexHtml = new File( htmlOutput, "index.html" );
                indexHtml.createNewFile();

                // Fortify Mod: Make sure the FileOutputStream is closed when we are done with it.
                // transformer.transform( new StreamSource( earlResult ),
                // new StreamResult( new FileOutputStream( indexHtml ) ) );
                FileOutputStream fo = new FileOutputStream( indexHtml );
                transformer.transform( new StreamSource( earlResult ), new StreamResult( fo ) );
                fo.close();
                FileUtils.copyDirectory( new File( resourceDir ), htmlOutput );
            }
        } catch ( Exception e ) {
            LOGR.log( SEVERE, "Transformation of EARL to HTML failed.", e );
        }
    }
503806
private void prettyprint(String xmlLogsFile, FileOutputStream htmlReportFile)
            throws Exception {
        TransformerFactory tFactory = TransformerFactory.newInstance();
        // Fortify Mod: prevent external entity injection
        tFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        // Fortify Mod: prevent external entity injection
        factory.setExpandEntityReferences(false);
        factory.setNamespaceAware(true);
        factory.setXIncludeAware(true);
        DocumentBuilder parser = factory.newDocumentBuilder();
        Document document = parser.parse(xmlLogsFile);
        Transformer transformer = tFactory.newTransformer(new StreamSource(
                xsltFileHandler));
        transformer.transform(new DOMSource(document), new StreamResult(
                htmlReportFile));
    }
649257
public void generate(List<File> reportInputDataDirs, File reportOutputDir)
            throws IllegalDataStructureException, IllegalTestScriptException {
        deleteDirIfExists(reportOutputDir); // delete previous execution output
        File htmlExternalResRootDir = CommonPath.htmlExternalResourceRootDir(reportOutputDir);
        SrcTree srcTree = generateSrcTree(reportInputDataDirs);
        List<RunResults> runResultsList = generateRunResultList(reportInputDataDirs, srcTree);

        // generate src-tree-yaml.js
        VelocityContext srcTreeContext = new VelocityContext();
        // don't need HTML encode
        String srcTreeYamlStr = YamlUtils.dumpToString(srcTree.toYamlObject());
        srcTreeContext.put("yamlStr", srcTreeYamlStr);
        File srcTreeYamlJsFile = new File(htmlExternalResRootDir, "js/report/src-tree-yaml.js");
        generateVelocityOutput(srcTreeContext, "/template/src-tree-yaml.js.vm", srcTreeYamlJsFile);

        // set up HTML external files
        // TODO all file paths are hard coded. this is very poor logic..
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/common-utils.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/capture-style.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/yaml/js-yaml.min.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/yaml/yaml-utils.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/code.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/string-code.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/method-argument.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/unknown-code.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/sub-method-invoke.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/local-var.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/field.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/var-assign.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/class-instance.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/test-step.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/test-step-label.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/code/code-line.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/test-class.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/page-class.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/test-field.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/test-field-table.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/test-method.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/test-method-table.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/test-class-table.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/srctree/src-tree.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/share/testdoc-resolver.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/fonts/flexslider-icon.eot");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/fonts/flexslider-icon.svg");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/fonts/flexslider-icon.ttf");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/fonts/flexslider-icon.woff");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/images/bx_loader.gif");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/images/controls.png");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/jquery.bxslider.css");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/jquery.treetable.css");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/jquery.treetable.theme.default.css");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/perfect-scrollbar.min.css");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "css/report.css");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "images/noImage.png");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/report/jquery-1.11.1.min.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/report/jquery.bxslider.min.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/report/jquery.treetable.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/report/perfect-scrollbar.min.js");
        extractHtmlExternalResFromThisJar(htmlExternalResRootDir, "js/report/report.js");

        // copy screen captures to reportOutputDir
        // TODO copying screen capture may be slow action
        File htmlReportCaptureRootDir = CommonPath.htmlReportCaptureRootDir(reportOutputDir);
        for (File reportInputDataDir : reportInputDataDirs) {
            File inputCaptureRootDir = CommonPath.inputCaptureRootDir(reportInputDataDir);
            try {
                if (inputCaptureRootDir.exists()) {
                    // assume runResults for each reportInputDataDir has different root method run results
                    // and the capture files are not overwritten.
                    FileUtils.copyDirectory(inputCaptureRootDir, htmlReportCaptureRootDir);
                }
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        List<TestMethod> testMethods = srcTree.getRootMethodTable().getTestMethods();
        File reportMainDir = CommonPath.htmlReportMainFile(reportOutputDir).getParentFile();
        List<ReportMethodLink> reportLinks = new ArrayList<>(testMethods.size());

        // generate each method report
        for (TestMethod rootMethod : testMethods) {
            TestMethod method = rootMethod;
            // use encoded test class name to avoid various possible file name encoding problem
            // TODO use java.nio.charset.StandardCharsets
            File methodReportParentDir= new File(CommonPath.methodHtmlReportRootDir(reportOutputDir),
                        CommonUtils.encodeToSafeAsciiFileNameString(method.getTestClass().getQualifiedName(), StandardCharsets.UTF_8));
            methodReportParentDir.mkdirs();

            VelocityContext methodContext = new VelocityContext();
            methodContext.put("number", new NumberTool());
            methodContext.put("math", new MathTool());
            if (rootMethod.getTestDoc() == null) {
                escapePut(methodContext, "title", rootMethod.getSimpleName());
            } else {
                escapePut(methodContext, "title", rootMethod.getTestDoc());
            }

            String externalResourceRootDir =  CommonUtils.relativize(
                    CommonPath.htmlExternalResourceRootDir(reportOutputDir), methodReportParentDir).getPath();
            // URL separator is always slash regardless of OS type
            escapePut(methodContext, "externalResourceRootDir",
                    FilenameUtils.separatorsToUnix(externalResourceRootDir));
            if (!(rootMethod instanceof TestMethod)) {
                throw new RuntimeException("not supported yet: " + rootMethod);
            }

            escapePut(methodContext, "className", method.getTestClass().getQualifiedName());
            escapePut(methodContext, "classTestDoc", method.getTestClass().getTestDoc());
            escapePut(methodContext, "methodName", rootMethod.getSimpleName());
            escapePut(methodContext, "methodTestDoc", rootMethod.getTestDoc());
            escapePut(methodContext, "timeUnit", SysMessages.get(SysMessages.REPORT_TIME_UNIT));
            escapePut(methodContext, "msgShowCode", SysMessages.get(SysMessages.REPORT_SHOW_CODE));
            escapePut(methodContext, "msgHideCode", SysMessages.get(SysMessages.REPORT_HIDE_CODE));
            // TODO js logic should construct message according to the user locale
            // without any information passed from the java logic
            escapePut(methodContext, "codeLineWithoutTestDoc",
                    SysMessages.get(SysMessages.CODE_LINE_WITHOUT_TEST_DOC));
            escapePut(methodContext, "jsLocalVar", SysMessages.get(SysMessages.JS_LOCAL_VAR));
            escapePut(methodContext, "jsVarAssign", SysMessages.get(SysMessages.JS_VAR_ASSIGN));
            RootMethodRunResult runResult = null;
            File inputCaptureRootDir = null;
            for (int i = 0; i < runResultsList.size(); i++) {
                runResult = runResultsList.get(i).getRunResultByRootMethod(rootMethod);
                if (runResult != null) {
                    inputCaptureRootDir = CommonPath.inputCaptureRootDir(reportInputDataDirs.get(i));
                    escapePut(methodContext, "executionTime", Integer.toString(runResult.getExecutionTime()));
                    break; // assume results for each runResults are for different root method
                }
            }
            boolean executed = (runResult != null);
            RunFailure runFailure = getRunFailure(runResult);
            if (runFailure == null) {
                escapePut(methodContext, "errMsg", null);
                escapePut(methodContext, "errLineTtId", "");
            } else {
                escapePut(methodContext, "errMsg", runFailure.getMessage().trim());
                escapePut(methodContext, "errLineTtId", generateTtId(runFailure.getStackLines()));
            }

            List<ReportCodeLine> reportCodeBody
            = generateReportCodeBody(rootMethod, runFailure, executed);
            methodContext.put("codeBody", reportCodeBody);

            List<LineScreenCapture> lineScreenCaptures;
            if (runResult == null) {
                lineScreenCaptures = new ArrayList<>(0);
            } else {
                lineScreenCaptures = runResult.getLineScreenCaptures();
                // TODO execution-time tag is used in HTML report now,
                // but should use data-execution-time tag
                addExecutionTimeToCodeBody(lineScreenCaptures, reportCodeBody);
            }
            addLineScreenCaptureForErrorEachStackLine(lineScreenCaptures, runFailure);
            List<ReportScreenCapture> captures = generateReportScreenCaptures(
                    lineScreenCaptures, inputCaptureRootDir, reportOutputDir, methodReportParentDir);
            methodContext.put("captures", captures);

            // use encoded method name to avoid various possible file name encoding problem
            // and to escape invalid file name character (Method name may contain such characters
            // if method is Groovy method, for example).
            File methodReportFile = new File(methodReportParentDir,
                    CommonUtils.encodeToSafeAsciiFileNameString(rootMethod.getSimpleName(), StandardCharsets.UTF_8) + ".html");
            generateVelocityOutput(methodContext, "/template/report.html.vm", methodReportFile);

            // set reportLinks data
            ReportMethodLink reportLink = new ReportMethodLink();
            reportLink.setTitle(method.getQualifiedName());
            String reportLinkPath = CommonUtils.relativize(methodReportFile, reportMainDir).getPath();
            // URL separator is always slash regardless of OS type
            reportLink.setPath(FilenameUtils.separatorsToUnix(reportLinkPath));
            reportLinks.add(reportLink);
        }
        // TODO HTML encode all codeBody, captures, reportLinks values

        // generate main index.html report
        VelocityContext mainContext = new VelocityContext();
        mainContext.put("reportLinks", reportLinks);
        generateVelocityOutput(mainContext, "/template/index.html.vm",
                CommonPath.htmlReportMainFile(reportOutputDir));
    }
227273
public void reportHTML(final Path target) throws IOException {
        
        Files.createDirectories(target.toAbsolutePath().getParent());
        
        LOGGER.info(() -> "Preparing HTML Report '" + title + "' to path: " + target);
        
        String html = UUtils.readResource("net/tuis/ubench/scale/UScale.html");
        Map<String, String> subs = new HashMap<>();
        subs.put("DATA", toJSONString());
        
        subs.put("TITLE", title);
        for (Map.Entry<String, String> me : subs.entrySet()) {
            html = html.replaceAll(Pattern.quote("${" + me.getKey() + "}"), Matcher.quoteReplacement(me.getValue()));
        }
        Files.write(target, html.getBytes(StandardCharsets.UTF_8));
        LOGGER.info(() -> "Completed HTML Report '" + title + "' to path: " + target);
    }
192623
void asPresentationML(XmlPrintStream out) {
    out.openElement(getMessageMLTag(), getAttributes());

    for (Element child : getChildren()) {
      child.asPresentationML(out);
    }

    out.closeElement();
  }
678864
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String sOpDirectory) {
        logger.entering(new Object[] { xmlSuites, suites, sOpDirectory });
        if (ListenerManager.isCurrentMethodSkipped(this)) {
            logger.exiting(ListenerManager.THREAD_EXCLUSION_MSG);
            return;
        }

        if (logger.isLoggable(Level.INFO)) {
            logger.log(Level.INFO, "Generating ExcelReport");
        }

        TestCaseResult.setOutputDirectory(sOpDirectory);

        // Generate data to suit excel report.
        this.generateSummaryData(suites);
        this.generateTCBasedData(allTestsResults);

        // Create the Excel Report
        this.createExcelReport();

        // Render the report
        Path p = Paths.get(sOpDirectory, reportFileName);

        try {
            Path opDirectory = Paths.get(sOpDirectory);
            if (!Files.exists(opDirectory)) {
                Files.createDirectories(Paths.get(sOpDirectory));
            }

            FileOutputStream fOut = new FileOutputStream(p.toFile());
            wb.write(fOut);
            fOut.flush();
        } catch (IOException e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
        }

        if (logger.isLoggable(Level.INFO)) {
            logger.log(Level.INFO, "Excel File Created @ " + p.toAbsolutePath().toString());
        }
    }
639974
void generateMbeanXml(Definition def, String outputDir)
   {
      String mbeanName = def.getDefaultValue().toLowerCase(Locale.US);
      if (def.getRaPackage() != null && !def.getRaPackage().equals(""))
      {
         if (def.getRaPackage().indexOf('.') >= 0)
         {
            mbeanName = def.getRaPackage().substring(def.getRaPackage().lastIndexOf('.') + 1);
         }
         else
            mbeanName = def.getRaPackage();
      }

      try
      {
         outputDir = outputDir + File.separatorChar + "src" + File.separatorChar +
               "main" + File.separatorChar + "resources" + File.separatorChar + "jca";
         FileWriter mbfw = Utils.createFile(mbeanName + ".xml", outputDir);
         MbeanXmlGen mbGen = new MbeanXmlGen();
         mbGen.generate(def, mbfw);
         mbfw.close();
      }
      catch (IOException ioe)
      {
         ioe.printStackTrace();
      }
   }
1360487
public static void writeXHTML(Document htmldoc, OutputStream out) throws IOException {
    javax.xml.transform.Result result = new StreamResult(out);
    // Use a transformer for pretty printing
    Transformer xformer;
    try {
      xformer = TransformerFactory.newInstance().newTransformer();
      xformer.setOutputProperty(OutputKeys.INDENT, "yes");
      // TODO: ensure the "meta" tag doesn't claim a different encoding!
      xformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
      xformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, HTML_XHTML_TRANSITIONAL_DOCTYPE_PUBLIC);
      xformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, HTML_XHTML_TRANSITIONAL_DOCTYPE_SYSTEM);
      xformer.transform(new DOMSource(htmldoc), result);
    }
    catch(TransformerException e1) {
      throw new IOException(e1);
    }
    out.flush();
  }
40392
public void toFolder(Path outputDirectory) {
        Validate.notNull(outputDirectory, "outputDirectory must not be null");

        context.setOutputPath(outputDirectory);

        applyOverviewDocument()
                .writeToFile(outputDirectory.resolve(context.config.getOverviewDocument()), StandardCharsets.UTF_8);
        applyPathsDocument()
                .writeToFile(outputDirectory.resolve(context.config.getPathsDocument()), StandardCharsets.UTF_8);
        applyDefinitionsDocument()
                .writeToFile(outputDirectory.resolve(context.config.getDefinitionsDocument()), StandardCharsets.UTF_8);
        applySecurityDocument()
                .writeToFile(outputDirectory.resolve(context.config.getSecurityDocument()), StandardCharsets.UTF_8);
    }
263807
public void transform(URL stylesheetUrl, Result result) throws IOException {
        transform(TransformerFactory.newInstance(), stylesheetUrl, result);
    }
418077
private void writeHeader(final String dtd) throws IOException {
    if (forHtml){
      wtr.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
      return;
    }
    
    wtr.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");

    if (dtd == null) {
      return;
    }

    wtr.write("<!DOCTYPE properties SYSTEM \"");
    wtr.write(dtd);
    wtr.write("\">\n");
  }
327463
public static void print(PrintStream out, String xpath, Object result){
        out.printf("XPath: %s%n", xpath);
        print(out, result, 2);
    }
1320774
void generateMavenXml(Definition def, String outputDir)
   {
      try
      {
         FileWriter pomfw = Utils.createFile("pom.xml", outputDir);
         PomXmlGen pxGen = new PomXmlGen();
         pxGen.generate(def, pomfw);
         pomfw.close();
      }
      catch (IOException ioe)
      {
         ioe.printStackTrace();
      }
   }
1319642
public static void outputResultTreeFragment(
        SerializationHandler handler,
        XObject obj,
        XPathContext support)
        throws org.xml.sax.SAXException
    {

        int doc = obj.rtf();
        DTM dtm = support.getDTM(doc);

        if (null != dtm)
        {
            for (int n = dtm.getFirstChild(doc);
                DTM.NULL != n;
                n = dtm.getNextSibling(n))
            {
                handler.flushPending();

                // I think. . . . This used to have a (true) arg
                // to flush prefixes, will that cause problems ???
                if (dtm.getNodeType(n) == DTM.ELEMENT_NODE
                        && dtm.getNamespaceURI(n) == null)
                    handler.startPrefixMapping("", "");
                dtm.dispatchToEvents(n, handler);
            }
        }
    }
537204
function output_as_xml($results){
		LogMaster::log("Edit operation finished",$results);
		ob_clean();
		header("Content-type:text/xml");
		echo "<?xml version='1.0' ?>";
		echo "<data>";
		for ($i=0; $i < sizeof($results); $i++)
			echo $results[$i]->to_xml();
		echo "</data>";
	}
345863
public void transformSummaryToHTML(Writer htmlWriter) throws IOException, TransformerException {

        ByteArrayOutputStream summaryOut = new ByteArrayOutputStream(8096);
        reportSummary(summaryOut);

        StreamSource in = new StreamSource(new ByteArrayInputStream(summaryOut.toByteArray()));
        StreamResult out = new StreamResult(htmlWriter);
        InputStream xslInputStream = this.getClass().getClassLoader().getResourceAsStream("summary.xsl");
        if (xslInputStream == null) {
            throw new IOException("Could not load summary stylesheet");
        }
        StreamSource xsl = new StreamSource(xslInputStream);

        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer transformer = tf.newTransformer(xsl);
        transformer.transform(in, out);

        Reader rdr = in.getReader();
        if (rdr != null) {
            rdr.close();
        }
        htmlWriter.close();
        InputStream is = xsl.getInputStream();
        if (is != null) {
            is.close();
        }
    }
470890
public static void format(final Source input, final Result output) {
        try {
            // Use an identity transformation to write the source to the result.
            final Transformer transformer = createTransformer(null);
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");

            transformer.transform(input, output);
        } catch (final Exception ex) {
            LOGGER.error("Problem formatting DOM representation.", ex);
        }
    }