ReportPage.java

    1/*******************************************************************************
    2 * Copyright (c) 2009, 2010 Mountainminds GmbH & Co. KG and Contributors
    3 * All rights reserved. This program and the accompanying materials
    4 * are made available under the terms of the Eclipse Public License v1.0
    5 * which accompanies this distribution, and is available at
    6 * http://www.eclipse.org/legal/epl-v10.html
    7 *
    8 * Contributors:
    9 *    Marc R. Hoffmann - initial API and implementation
   10 *    
   11 * $Id: $
   12 *******************************************************************************/
   13package org.jacoco.report.html;
   14
   15import java.io.IOException;
   16
   17import org.jacoco.core.JaCoCo;
   18import org.jacoco.core.analysis.ICoverageNode;
   19import org.jacoco.report.IReportVisitor;
   20import org.jacoco.report.ISourceFileLocator;
   21import org.jacoco.report.ReportOutputFolder;
   22import org.jacoco.report.html.resources.Resources;
   23import org.jacoco.report.html.resources.Styles;
   24
   25/**
   26 * Base class for HTML page generators. It renders the page skeleton with the
   27 * breadcrumb, the title and the footer.
   28 * 
   29 * @author Marc R. Hoffmann
   30 * @version $Revision: $
   31 */
   32public abstract class ReportPage implements IReportVisitor, ICoverageTableItem {
   33
   34    private final ReportPage parent;
   35
   36    /** output folder for this node */
   37    protected final ReportOutputFolder outputFolder;
   38
   39    /** context for this report */
   40    protected final IHTMLReportContext context;
   41
   42    private ICoverageNode node;
   43
   44    /**
   45     * Creates a new report page.
   46     * 
   47     * @param node
   48     *            corresponding node
   49     * @param parent
   50     *            optional hierarchical parent
   51     * @param baseFolder
   52     *            base folder to create this report page relative to
   53     * @param context
   54     *            settings context
   55     */
   56    protected ReportPage(final ICoverageNode node, final ReportPage parent,
   57            final ReportOutputFolder baseFolder,
   58            final IHTMLReportContext context) {
   59        this.node = node;
   60        this.parent = parent;
   61        this.context = context;
   62        this.outputFolder = getFolder(baseFolder);
   63    }
   64
   65    public void visitEnd(final ISourceFileLocator sourceFileLocator)
   66            throws IOException {
   67        renderDocument(sourceFileLocator);
   68        this.node = node.getPlainCopy();
   69    }
   70
   71    private void renderDocument(final ISourceFileLocator sourceFileLocator)
   72            throws IOException {
   73        final HTMLDocument doc = new HTMLDocument(outputFolder
   74                .createFile(getFileName()), context.getOutputEncoding());
   75        head(doc.head());
   76        body(doc.body(), sourceFileLocator);
   77        doc.close();
   78    }
   79
   80    /**
   81     * Fills the content of the 'head' element.
   82     * 
   83     * @param head
   84     *            enclosing head element
   85     * @throws IOException
   86     *             in case of IO problems with the report writer
   87     */
   88    protected void head(final HTMLElement head) throws IOException {
   89        head.meta("Content-Type", "text/html;charset=UTF-8");
   90        head.link("stylesheet", context.getResources().getLink(outputFolder,
   91                Resources.STYLESHEET), "text/css");
   92        head.link("shortcut icon", context.getResources().getLink(outputFolder,
   93                "session.gif"), "image/gif");
   94        head.title().text(getLabel());
   95    }
   96
   97    /**
   98     * Renders the content of the body element.
   99     * 
  100     * @param body
  101     *            enclosing body element
  102     * @param sourceFileLocator
  103     *            locator for source file content in this context
  104     * @throws IOException
  105     *             in case of IO problems with the report writer
  106     */
  107    protected void body(final HTMLElement body,
  108            final ISourceFileLocator sourceFileLocator) throws IOException {
  109        breadcrumb(body.div(Styles.BREADCRUMB), outputFolder, this);
  110        body.h1().text(getLabel());
  111        content(body, sourceFileLocator);
  112        footer(body);
  113    }
  114
  115    private void breadcrumb(final HTMLElement body,
  116            final ReportOutputFolder base, final ReportPage current)
  117            throws IOException {
  118        if (parent != null) {
  119            parent.breadcrumb(body, base, current);
  120            body.text(" > ");
  121        }
  122        final String style = Resources.getElementStyle(node.getElementType());
  123        if (this == current) {
  124            body.span(style).text(getLabel());
  125        } else {
  126            body.a(getLink(base), style).text(getLabel());
  127        }
  128    }
  129
  130    /**
  131     * Creates the actual content of the page.
  132     * 
  133     * @param body
  134     *            body tag of the page
  135     * @param sourceFileLocator
  136     *            locator for source file content in this context
  137     * @throws IOException
  138     *             in case of IO problems with the report writer
  139     */
  140    protected abstract void content(final HTMLElement body,
  141            final ISourceFileLocator sourceFileLocator) throws IOException;
  142
  143    /**
  144     * Renders the page footer.
  145     * 
  146     * @param body
  147     *            enclosing body element
  148     * @throws IOException
  149     *             in case of IO problems with the report writer
  150     */
  151    protected void footer(final HTMLElement body) throws IOException {
  152        final HTMLElement footer = body.div(Styles.FOOTER);
  153        final HTMLElement versioninfo = footer.div(Styles.VERSIONINFO);
  154        versioninfo.text("Created with ");
  155        versioninfo.a(JaCoCo.HOMEURL).text("JaCoCo");
  156        versioninfo.text(" ").text(JaCoCo.VERSION);
  157        footer.text(context.getFooterText());
  158    }
  159
  160    /**
  161     * Specifies the local file name of this page.
  162     * 
  163     * @return local file name
  164     */
  165    protected abstract String getFileName();
  166
  167    /**
  168     * Creates the output folder relative to the given base for this report
  169     * page. The method may decide to simply return the base folder itself.
  170     * 
  171     * @param base
  172     *            base folder
  173     * @return folder to create this page in
  174     */
  175    protected abstract ReportOutputFolder getFolder(ReportOutputFolder base);
  176
  177    // === ICoverageTableItem ===
  178
  179    public String getLabel() {
  180        return node.getName();
  181    }
  182
  183    public ICoverageNode getNode() {
  184        return node;
  185    }
  186
  187    public final String getLink(final ReportOutputFolder base) {
  188        return outputFolder.getLink(base, getFileName());
  189    }
  190
  191}