com.technophobia.substeps.report.DetailedJsonBuilder.java Source code

Java tutorial

Introduction

Here is the source code for com.technophobia.substeps.report.DetailedJsonBuilder.java

Source

/*
 *   Copyright Technophobia Ltd 2012
 *
 *   This file is part of Substeps.
 *
 *    Substeps is free software: you can redistribute it and/or modify
 *    it under the terms of the GNU Lesser General Public License as published by
 *    the Free Software Foundation, either version 3 of the License, or
 *    (at your option) any later version.
 *
 *    Substeps 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 Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public License
 *    along with Substeps.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.technophobia.substeps.report;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.commons.lang3.StringEscapeUtils;
import org.joda.time.Duration;
import org.joda.time.format.PeriodFormat;
import org.joda.time.format.PeriodFormatter;

import com.google.common.io.Files;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.technophobia.substeps.execution.AbstractExecutionNodeVisitor;
import com.technophobia.substeps.execution.ExecutionNodeResult;
import com.technophobia.substeps.execution.node.ExecutionNode;
import com.technophobia.substeps.execution.node.IExecutionNode;
import com.technophobia.substeps.execution.node.NodeWithChildren;
import com.technophobia.substeps.execution.node.StepImplementationNode;
import com.technophobia.substeps.model.exception.SubstepsRuntimeException;

public final class DetailedJsonBuilder extends AbstractExecutionNodeVisitor<JsonObject> {

    private final ReportData reportData;
    private final String screenshotFolder;
    private BufferedWriter writer;

    public static void writeDetailJson(ReportData reportData, String screenshotFolder, File jsonFile) {

        new DetailedJsonBuilder(reportData, screenshotFolder).writeFile(jsonFile);

    }

    private DetailedJsonBuilder(ReportData reportData, String screenshotFolder) {

        this.reportData = reportData;
        this.screenshotFolder = screenshotFolder;
    }

    private void writeFile(File jsonFile) {
        try {

            writer = Files.newWriter(jsonFile, Charset.defaultCharset());
            writer.append("var detail = new Array();");

            for (ExecutionNode rootNode : reportData.getRootNodes()) {

                for (JsonObject nodeAsJson : rootNode.accept(this)) {

                    writer.append("\ndetail[" + nodeAsJson.get("id") + "]=" + nodeAsJson.toString() + ";");
                }

            }

        } catch (IOException e) {

            throw new SubstepsRuntimeException("Failed writing to detail json file");
        } finally {

            if (writer != null) {
                try {
                    writer.flush();
                    writer.close();
                } catch (IOException e) {
                    throw new SubstepsRuntimeException("Failed writing to detail json file");
                }
            }

        }

    }

    @Override
    public JsonObject visit(NodeWithChildren<?> node) {

        return createBasicDetailsWithChildDetails(node.getClass().getSimpleName().toString(), node,
                node.getChildren());
    }

    @Override
    public JsonObject visit(StepImplementationNode stepImplementationNode) {

        JsonObject json = createBasicDetails("Step", stepImplementationNode);
        addLinkToScreenshot(stepImplementationNode.getResult(), json);

        String methodInfo = createMethodInfo(stepImplementationNode);

        json.addProperty("method", methodInfo);

        return json;
    }

    private JsonObject createBasicDetailsWithChildDetails(String nodeType, IExecutionNode node,
            List<? extends IExecutionNode> childNodes) {

        JsonObject json = createBasicDetails(nodeType, node);
        addDetailsForChildren(json, childNodes);

        return json;
    }

    public JsonObject createBasicDetails(String nodeType, IExecutionNode node) {

        JsonObject thisNode = new JsonObject();

        thisNode.addProperty("nodetype", nodeType);
        thisNode.addProperty("filename", node.getFilename());
        thisNode.addProperty("result", node.getResult().getResult().toString());
        thisNode.addProperty("id", node.getId());
        thisNode.addProperty("emessage", getExceptionMessage(node));
        thisNode.addProperty("stacktrace", getStackTrace(node));

        thisNode.addProperty("runningDurationMillis", node.getResult().getRunningDuration());
        thisNode.addProperty("runningDurationString", convert(node.getResult().getRunningDuration()));

        String description = node.getDescription() == null ? null : node.getDescription().trim();
        String descriptionEscaped = replaceNewLines(StringEscapeUtils.escapeHtml4(description));

        thisNode.addProperty("description", descriptionEscaped);

        return thisNode;
    }

    private void addLinkToScreenshot(ExecutionNodeResult result, JsonObject thisNode) {

        if (result.getScreenshot() != null) {
            thisNode.addProperty("screenshot", screenshotFolder + File.separator + result.getExecutionNodeId()
                    + ScreenshotWriter.SCREENSHOT_SUFFIX);
        }
    }

    private String convert(Long runningDurationMillis) {

        return runningDurationMillis == null ? "No duration recorded" : convert(runningDurationMillis.longValue());
    }

    private String convert(long runningDurationMillis) {
        Duration duration = new Duration(runningDurationMillis);
        PeriodFormatter formatter = PeriodFormat.getDefault();
        return formatter.print(duration.toPeriod());
    }

    private void addDetailsForChildren(JsonObject json, List<? extends IExecutionNode> childNodes) {

        JsonArray children = new JsonArray();
        json.add("children", children);

        for (IExecutionNode childNode : childNodes) {

            JsonObject childObject = new JsonObject();
            childObject.addProperty("result", childNode.getResult().getResult().toString());
            childObject.addProperty("description", StringEscapeUtils.escapeHtml4(childNode.getDescription()));
            children.add(childObject);
        }
    }

    private String createMethodInfo(StepImplementationNode node) {

        final StringBuilder methodInfoBuffer = new StringBuilder();
        node.appendMethodInfo(methodInfoBuffer);

        String methodInfo = methodInfoBuffer.toString();
        if (methodInfo.contains("\"")) {
            methodInfo = methodInfo.replace("\"", "\\\"");
        }

        return replaceNewLines(methodInfo);
    }

    private String getExceptionMessage(IExecutionNode node) {
        String exceptionMessage = "";

        if (node.getResult().getThrown() != null) {

            final String exceptionMsg = StringEscapeUtils.escapeHtml4(node.getResult().getThrown().getMessage());

            exceptionMessage = replaceNewLines(exceptionMsg);

        }

        return exceptionMessage;
    }

    private String getStackTrace(IExecutionNode node) {
        String stackTrace = "";

        if (node.getResult().getThrown() != null) {

            final StackTraceElement[] stackTraceElements = node.getResult().getThrown().getStackTrace();

            final StringBuilder buf = new StringBuilder();

            for (final StackTraceElement e : stackTraceElements) {

                buf.append(StringEscapeUtils.escapeHtml4(e.toString().trim())).append("<br/>");
            }
            stackTrace = buf.toString();
        }

        return stackTrace;
    }

    private String replaceNewLines(final String s) {

        if (s != null && s.contains("\n")) {

            return s.replaceAll("\n", "<br/>");
        } else {
            return s;
        }
    }

}