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 *******************************************************************************/
12package org.jacoco.report.html;
13
14import java.io.IOException;
15
16import org.jacoco.core.JaCoCo;
17import org.jacoco.report.ReportOutputFolder;
18import org.jacoco.report.html.resources.Resources;
19import org.jacoco.report.html.resources.Styles;
20
21/**
22 * Base class for HTML page generators. It renders the page skeleton with the
23 * breadcrumb, the title and the footer. Every report page is part of a
24 * hierarchy and has a parent page (except the root page).
25 *
26 * @author Marc R. Hoffmann
27 * @version 0.4.1.20101007204400
28 */
29public abstract class ReportPage implements ILinkable {
30
31 private final ReportPage parent;
32
33 /** output folder for this node */
34 protected final ReportOutputFolder folder;
35
36 /** context for this report */
37 protected final IHTMLReportContext context;
38
39 /**
40 * Creates a new report page.
41 *
42 * @param parent
43 * optional hierarchical parent
44 * @param folder
45 * base folder to create this report in
46 * @param context
47 * settings context
48 */
49 protected ReportPage(final ReportPage parent,
50 final ReportOutputFolder folder, final IHTMLReportContext context) {
51 this.parent = parent;
52 this.context = context;
53 this.folder = folder;
54 }
55
56 /**
57 * Renders the page content. This method must be called at most once.
58 *
59 * @throws IOException
60 */
61 public final void renderDocument() throws IOException {
62 final HTMLDocument doc = new HTMLDocument(
63 folder.createFile(getFileName()), context.getOutputEncoding());
64 head(doc.head());
65 body(doc.body());
66 doc.close();
67 }
68
69 private void head(final HTMLElement head) throws IOException {
70 head.meta("Content-Type", "text/html;charset=UTF-8");
71 head.link("stylesheet",
72 context.getResources().getLink(folder, Resources.STYLESHEET),
73 "text/css");
74 head.link("shortcut icon",
75 context.getResources().getLink(folder, "report.gif"),
76 "image/gif");
77 head.title().text(getLinkLabel());
78 headExtra(head);
79 }
80
81 private void body(final HTMLElement body) throws IOException {
82 body.attr("onload", getOnload());
83 final HTMLElement navigation = body.div(Styles.BREADCRUMB);
84 navigation.attr("id", "breadcrumb");
85 infoLinks(navigation.span(Styles.RIGHT));
86 breadcrumb(navigation, folder);
87 body.h1().text(getLinkLabel());
88 content(body);
89 footer(body);
90 }
91
92 /**
93 * Hook to add extra content into the head tag.
94 *
95 * @param head
96 * enclosing head element
97 * @throws IOException
98 * in case of IO problems with the report writer
99 */
100 protected void headExtra(final HTMLElement head) throws IOException {
101 }
102
103 /**
104 * Returns the onload handler for this page.
105 *
106 * @return handler or <code>null</code>
107 */
108 protected String getOnload() {
109 return null;
110 }
111
112 private void infoLinks(final HTMLElement span) throws IOException {
113 span.a(context.getSessionsPage(), folder);
114 }
115
116 private void breadcrumb(final HTMLElement div, final ReportOutputFolder base)
117 throws IOException {
118 breadcrumbParent(parent, div, base);
119 div.span(getLinkStyle()).text(getLinkLabel());
120 }
121
122 private static void breadcrumbParent(final ReportPage page,
123 final HTMLElement div, final ReportOutputFolder base)
124 throws IOException {
125 if (page != null) {
126 breadcrumbParent(page.parent, div, base);
127 div.a(page, base);
128 div.text(" > ");
129 }
130 }
131
132 private void footer(final HTMLElement body) throws IOException {
133 final HTMLElement footer = body.div(Styles.FOOTER);
134 final HTMLElement versioninfo = footer.span(Styles.RIGHT);
135 versioninfo.text("Created with ");
136 versioninfo.a(JaCoCo.HOMEURL).text("JaCoCo");
137 versioninfo.text(" ").text(JaCoCo.VERSION);
138 footer.text(context.getFooterText());
139 }
140
141 /**
142 * Specifies the local file name of this page.
143 *
144 * @return local file name
145 */
146 protected abstract String getFileName();
147
148 /**
149 * Creates the actual content of the page.
150 *
151 * @param body
152 * body tag of the page
153 * @throws IOException
154 * in case of IO problems with the report writer
155 */
156 protected abstract void content(final HTMLElement body) throws IOException;
157
158 // === ILinkable ===
159
160 public final String getLink(final ReportOutputFolder base) {
161 return folder.getLink(base, getFileName());
162 }
163
164}