com.crawljax.plugins.adi.Report.java Source code

Java tutorial

Introduction

Here is the source code for com.crawljax.plugins.adi.Report.java

Source

/*
Automatic DOM Invariants is a plugin for Crawljax that can be used to
derive DOM invariants automatically and use them for regressions
testing.
Copyright (C) 2010  crawljax.com
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
*/
package com.crawljax.plugins.adi;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringEscapeUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.crawljax.util.Helper;
import com.crawljax.util.PrettyHTML;
import com.crawljax.util.XPathHelper;

/**
 * Class used by DomInvariantTester to report errors.
 * 
 * @author Frank Groeneveld
 */
public class Report {

    private Document controlDom;
    private Document testDom;
    private List<String[]> failures = new ArrayList<String[]>();

    public static final String[] COLORS = { "#ff0000", "#00ff00", "#0000ff", "#ffff00", "#00ffff", "#ff00ff",
            "#c0c0c0", "#ff6600", "#99ff00", "#663300", "#336600", "#6633cc", "#ff99ff", "#ff0066", };

    /**
     * Loads contents of a resource, works also in JARs.
     * 
     * @param filename
     *            The name of the resource.
     * @return The text inside the file.
     */
    private String loadTextFromResource(String filename) {
        InputStream is = getClass().getClassLoader().getResourceAsStream(filename);
        StringBuilder sb = new StringBuilder();
        String line;

        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            while ((line = reader.readLine()) != null) {
                sb.append(line).append("\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    /**
     * Save the report as filename.
     * 
     * @param filename
     *            The file to save the report in.
     */
    public void saveAs(String filename) {

        File stateFile = new File(filename);
        try {
            FileWriter writer = new FileWriter(stateFile, false);

            writer.write(loadTextFromResource("head.html"));
            writer.write(addFailuresToDom(controlDom));
            writer.write(loadTextFromResource("middle.html"));
            writer.write(addFailuresToDom(testDom));
            writer.write(loadTextFromResource("tail.html"));
            writer.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        /* reset failures */
        failures = new ArrayList<String[]>();
    }

    private String addFailuresToDom(Document dom) {

        /* TOOD: this modifies the DOM, it should create a copy */

        for (int i = 0; i < failures.size(); i++) {
            String[] failure = failures.get(i);
            if (failure[1] != null) {
                dom = addMarker("" + i, dom, failure[1]);
            }
            dom = addMarker("" + i, dom, failure[0]);
        }
        String formattedDom = Helper.getDocumentToString(dom);
        formattedDom = PrettyHTML.prettyHTML(formattedDom, "  ");
        formattedDom = StringEscapeUtils.escapeHtml(formattedDom);
        formattedDom = replaceMarkers(formattedDom);

        return formattedDom;
    }

    /**
     * Add a failure.
     * 
     * @param xPathExpression
     *            First expression.
     * @param secondXPathExpression
     *            Second expression.
     * @param message
     *            Failure message shown in the report.
     */
    public void addFailure(String xPathExpression, String secondXPathExpression, String message) {
        failures.add(new String[] { xPathExpression, secondXPathExpression, message });
        System.err.println(message);
    }

    /**
     * Taken from ErrorReport.
     */
    private Document addMarker(String id, Document doc, String xpath) {
        try {

            String prefixMarker = "###BEGINMARKER" + id + "###";
            String suffixMarker = "###ENDMARKER###";

            NodeList nodeList = XPathHelper.evaluateXpathExpression(doc, xpath);

            if (nodeList.getLength() == 0 || nodeList.item(0) == null) {
                return doc;
            }

            Node element = nodeList.item(0);

            if (element.getNodeType() == Node.ELEMENT_NODE) {
                Node beginNode = doc.createTextNode(prefixMarker);
                Node endNode = doc.createTextNode(suffixMarker);

                element.getParentNode().insertBefore(beginNode, element);
                if (element.getNextSibling() == null) {
                    element.getParentNode().appendChild(endNode);
                } else {
                    element.getParentNode().insertBefore(endNode, element.getNextSibling());
                }
            } else if (element.getNodeType() == Node.TEXT_NODE && element.getTextContent() != null) {
                element.setTextContent(prefixMarker + element.getTextContent() + suffixMarker);
            } else if (element.getNodeType() == Node.ATTRIBUTE_NODE) {
                element.setNodeValue(prefixMarker + element.getTextContent() + suffixMarker);
            }

            return doc;
        } catch (Exception e) {
            return doc;
        }
    }

    /**
     * Taken from ErrorReport.
     */
    private String replaceMarkers(String dom) {
        for (int i = 0; i < failures.size(); i++) {
            String[] failure = failures.get(i);
            String regexSearch = "\\s*" + "###BEGINMARKER" + i + "###";
            String replace = "<div class=\"difference\" title=\"" + StringEscapeUtils.escapeHtml(failure[2])
                    + "\" style=\"background: " + COLORS[i % COLORS.length] + ";\">";
            dom = dom.replaceAll(regexSearch, replace);
        }

        dom = dom.replaceAll("(\\s)*###ENDMARKER###", "</div>");

        return dom;
    }

    /**
     * Set control DOM to use.
     * 
     * @param document
     *            The control DOM.
     */
    public void setControlDom(Document document) {
        controlDom = document;
    }

    /**
     * Set test DOM to use.
     * 
     * @param document
     *            The test DOM.
     */
    public void setTestDom(Document document) {
        testDom = document;
    }

}