info.novatec.testit.livingdoc.report.XmlReport.java Source code

Java tutorial

Introduction

Here is the source code for info.novatec.testit.livingdoc.report.XmlReport.java

Source

/* Copyright (c) 2006 Pyxis Technologies inc.
 * 
 * This 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 2 of the License, or (at your option) any later
 * version.
 * 
 * This software 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, write to the Free Software Foundation, Inc., 51
 * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF site:
 * http://www.fsf.org. */

package info.novatec.testit.livingdoc.report;

import static info.novatec.testit.livingdoc.util.LoggerConstants.LOG_ERROR;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import info.novatec.testit.livingdoc.Statistics;
import info.novatec.testit.livingdoc.TimeStatistics;
import info.novatec.testit.livingdoc.util.ExceptionImposter;
import info.novatec.testit.livingdoc.util.ExceptionUtils;

public class XmlReport implements Report {
    private static final Logger LOG = LoggerFactory.getLogger(XmlReport.class);

    private static final String DOCUMENTS = "documents";
    private static final String GLOBAL_EXCEPTION = "global-exception";
    private static final String DOCUMENT = "document";
    private static final String DOCUMENT_NAME = "name";
    private static final String DOCUMENT_EXTERNAL_LINK = "external-link";
    private static final String STATISTICS = "statistics";
    private static final String TIME = "time-statistics";
    private static final String EXECUTION_TIME = "execution";
    private static final String TOTAL_TIME = "total";
    private static final String RESULTS = "results";
    private static final String SUCCESS = "success";
    private static final String FAILURE = "failure";
    private static final String ERROR = "error";
    private static final String IGNORED = "ignored";
    private static final String SECTIONS = "sections";
    private static final String SECTION = "section";

    private static final String ANNOTATION = "annotation";

    private static final DocumentBuilderFactory documentFactoryBuilder = DocumentBuilderFactory.newInstance();
    private static final TransformerFactory transformerFactory = TransformerFactory.newInstance();

    private Document dom;
    private Element root;
    private String name;

    public static XmlReport newInstance(String name) {
        return new XmlReport(name);
    }

    public XmlReport(String name) {
        this.name = name;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public String getType() {
        return "xml";
    }

    private DocumentBuilder newDocumentBuilder() {
        try {
            return documentFactoryBuilder.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            LOG.error(LOG_ERROR, e);
            throw ExceptionImposter.imposterize(e);
        }
    }

    private XmlReport(InputSource source) throws SAXException, IOException {
        source.setEncoding("UTF-8");
        dom = newDocumentBuilder().parse(source);
        root = dom.getDocumentElement();
    }

    public static XmlReport parse(String content) throws SAXException, IOException {
        return parse(new StringReader(content));
    }

    public static XmlReport parse(Reader in) throws SAXException, IOException {
        return parse(new InputSource(in));
    }

    public static XmlReport parse(InputStream is) throws SAXException, IOException {
        return parse(new InputSource(is));
    }

    public static XmlReport parse(File file) throws SAXException, IOException {
        FileInputStream fileInputStream = new FileInputStream(file);
        Reader reader = new InputStreamReader(fileInputStream, "UTF-8");

        try {
            return parse(reader);
        } finally {
            IOUtils.closeQuietly(reader);
        }
    }

    @Override
    public void renderException(Throwable throwable) {
        createEmptyDocument();
        String msg = ExceptionUtils.stackTrace(throwable, "\n", 10);
        addTextValue(root, GLOBAL_EXCEPTION, msg, true);
    }

    private void createEmptyDocument() {
        dom = newDocumentBuilder().newDocument();
        root = dom.createElement(DOCUMENTS);
        dom.appendChild(root);
    }

    @Override
    public void generate(info.novatec.testit.livingdoc.document.Document document) {
        createEmptyDocument();
        Statistics compiler = document.getStatistics();
        Element element = dom.createElement(DOCUMENT);
        root.appendChild(element);

        if (!StringUtils.isEmpty(document.getName())) {
            addTextValue(element, DOCUMENT_NAME, document.getName(), true);
        }

        if (!StringUtils.isEmpty(document.getExternalLink())) {
            addTextValue(element, DOCUMENT_EXTERNAL_LINK, document.getExternalLink(), true);
        }

        if (document.getSections() != null && document.getSections().length > 0) {
            Element sections = dom.createElement(SECTIONS);
            root.appendChild(sections);

            for (String section : document.getSections()) {
                addTextValue(sections, SECTION, section, true);
            }
        }

        Element time = dom.createElement(TIME);
        element.appendChild(time);

        Element stats = dom.createElement(STATISTICS);
        element.appendChild(stats);

        StringWriter buffer = new StringWriter();
        PrintWriter writer = new PrintWriter(buffer);
        document.print(writer);
        writer.flush();

        addNumberValue(time, EXECUTION_TIME, document.getTimeStatistics().getExecution());
        addNumberValue(time, TOTAL_TIME, document.getTimeStatistics().getTotal());
        addTextValue(element, RESULTS, buffer.toString(), true);
        addNumberValue(stats, SUCCESS, compiler.rightCount());
        addNumberValue(stats, FAILURE, compiler.wrongCount());
        addNumberValue(stats, ERROR, compiler.exceptionCount());
        addNumberValue(stats, IGNORED, compiler.ignoredCount());
    }

    public String getResults(int index) {
        return getTextValue(RESULTS, index);
    }

    public String getGlobalException() {
        return getTextValue(GLOBAL_EXCEPTION, 0);
    }

    public int getSuccess(int index) {
        return getIntValue(SUCCESS, index);
    }

    public int getFailure(int index) {
        return getIntValue(FAILURE, index);
    }

    public int getError(int index) {
        return getIntValue(ERROR, index);
    }

    public int getIgnored(int index) {
        return getIntValue(IGNORED, index);
    }

    public int getAnnotation(int index) {
        return getIntValue(ANNOTATION, index);
    }

    public String getSections(int index) {
        return getTextValue(SECTION, index);
    }

    public long getExecutionTime(int index) {
        return getLongValue(EXECUTION_TIME, index);
    }

    public long getTotalTime(int index) {
        return getLongValue(TOTAL_TIME, index);
    }

    public String getDocumentName(int index) {
        return getTextValue(DOCUMENT_NAME, index);
    }

    public String getDocumentExternalLink(int index) {
        return getTextValue(DOCUMENT_EXTERNAL_LINK, index);
    }

    @Override
    public void printTo(Writer out) throws IOException {
        try {
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
            transformer.transform(new DOMSource(dom), new StreamResult(out));
        } catch (TransformerException ex) {
            LOG.error(LOG_ERROR, ex);
            throw new IOException(ex.getMessage());
        }
    }

    public static XmlReport parse(InputSource source) throws SAXException, IOException {
        return new XmlReport(source);
    }

    public static String toXml(info.novatec.testit.livingdoc.document.Document document) throws IOException {
        StringWriter sw = new StringWriter();

        XmlReport xmlReport = XmlReport.newInstance("");
        xmlReport.generate(document);
        xmlReport.printTo(sw);

        return sw.toString();
    }

    public Statistics toStatistics() {
        return new Statistics(getSuccess(0), getFailure(0), getError(0), getIgnored(0));
    }

    public TimeStatistics toTimeStatistics() {
        return new TimeStatistics(getTotalTime(0), getExecutionTime(0));
    }

    private String getTextValue(String tagName, int index) {
        String textVal = null;
        NodeList nl = root.getElementsByTagName(tagName);
        if (nl != null && nl.getLength() > 0 && index < nl.getLength()) {
            Element el = (Element) nl.item(index);
            Node node = el.getFirstChild();
            if (node != null) {
                textVal = node.getNodeValue();
            }
        }

        return textVal;
    }

    private void addTextValue(Element parent, String tagName, String value, boolean cdata) {
        Element element = dom.createElement(tagName);
        Text eleValue = cdata ? dom.createCDATASection(value) : dom.createTextNode(value);
        element.appendChild(eleValue);
        parent.appendChild(element);
    }

    private int getIntValue(String tagName, int index) {
        return Integer.parseInt(getTextValue(tagName, index));
    }

    private long getLongValue(String tagName, int index) {
        String value = getTextValue(tagName, index);
        return value == null ? 0 : Long.parseLong(value);
    }

    private void addNumberValue(Element parent, String tagName, Number value) {
        Element element = dom.createElement(tagName);
        Text eleValue = dom.createTextNode(String.valueOf(value));
        element.appendChild(eleValue);
        parent.appendChild(element);
    }
}