• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright (c) 2009, 2018 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  *******************************************************************************/
12 package org.jacoco.report.internal.html.page;
13 
14 import java.io.IOException;
15 
16 import org.jacoco.core.JaCoCo;
17 import org.jacoco.report.internal.ReportOutputFolder;
18 import org.jacoco.report.internal.html.HTMLDocument;
19 import org.jacoco.report.internal.html.HTMLElement;
20 import org.jacoco.report.internal.html.IHTMLReportContext;
21 import org.jacoco.report.internal.html.ILinkable;
22 import org.jacoco.report.internal.html.resources.Resources;
23 import org.jacoco.report.internal.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. Every report page is part of a
28  * hierarchy and has a parent page (except the root page).
29  */
30 public abstract class ReportPage implements ILinkable {
31 
32 	private final ReportPage parent;
33 
34 	/** output folder for this node */
35 	protected final ReportOutputFolder folder;
36 
37 	/** context for this report */
38 	protected final IHTMLReportContext context;
39 
40 	/**
41 	 * Creates a new report page.
42 	 *
43 	 * @param parent
44 	 *            optional hierarchical parent
45 	 * @param folder
46 	 *            base folder to create this report in
47 	 * @param context
48 	 *            settings context
49 	 */
ReportPage(final ReportPage parent, final ReportOutputFolder folder, final IHTMLReportContext context)50 	protected ReportPage(final ReportPage parent,
51 			final ReportOutputFolder folder, final IHTMLReportContext context) {
52 		this.parent = parent;
53 		this.context = context;
54 		this.folder = folder;
55 	}
56 
57 	/**
58 	 * Checks whether this is the root page of the report.
59 	 *
60 	 * @return <code>true</code> if this is the root page
61 	 */
isRootPage()62 	protected final boolean isRootPage() {
63 		return parent == null;
64 	}
65 
66 	/**
67 	 * Renders this page's content and optionally additional pages. This method
68 	 * must be called at most once.
69 	 *
70 	 * @throws IOException
71 	 *             if the page can't be written
72 	 */
render()73 	public void render() throws IOException {
74 		final HTMLDocument doc = new HTMLDocument(
75 				folder.createFile(getFileName()), context.getOutputEncoding());
76 		doc.attr("lang", context.getLocale().getLanguage());
77 		head(doc.head());
78 		body(doc.body());
79 		doc.close();
80 	}
81 
82 	/**
83 	 * Creates the elements within the head element.
84 	 *
85 	 * @param head
86 	 *            head tag of the page
87 	 * @throws IOException
88 	 *             in case of IO problems with the report writer
89 	 */
head(final HTMLElement head)90 	protected void head(final HTMLElement head) throws IOException {
91 		head.meta("Content-Type", "text/html;charset=UTF-8");
92 		head.link("stylesheet",
93 				context.getResources().getLink(folder, Resources.STYLESHEET),
94 				"text/css");
95 		head.link("shortcut icon",
96 				context.getResources().getLink(folder, "report.gif"),
97 				"image/gif");
98 		head.title().text(getLinkLabel());
99 	}
100 
body(final HTMLElement body)101 	private void body(final HTMLElement body) throws IOException {
102 		body.attr("onload", getOnload());
103 		final HTMLElement navigation = body.div(Styles.BREADCRUMB);
104 		navigation.attr("id", "breadcrumb");
105 		infoLinks(navigation.span(Styles.INFO));
106 		breadcrumb(navigation, folder);
107 		body.h1().text(getLinkLabel());
108 		content(body);
109 		footer(body);
110 	}
111 
112 	/**
113 	 * Returns the onload handler for this page.
114 	 *
115 	 * @return handler or <code>null</code>
116 	 */
getOnload()117 	protected String getOnload() {
118 		return null;
119 	}
120 
121 	/**
122 	 * Inserts additional links on the top right corner.
123 	 *
124 	 * @param span
125 	 *            parent element
126 	 * @throws IOException
127 	 *             in case of IO problems with the report writer
128 	 */
infoLinks(final HTMLElement span)129 	protected void infoLinks(final HTMLElement span) throws IOException {
130 		span.a(context.getSessionsPage(), folder);
131 	}
132 
breadcrumb(final HTMLElement div, final ReportOutputFolder base)133 	private void breadcrumb(final HTMLElement div, final ReportOutputFolder base)
134 			throws IOException {
135 		breadcrumbParent(parent, div, base);
136 		div.span(getLinkStyle()).text(getLinkLabel());
137 	}
138 
breadcrumbParent(final ReportPage page, final HTMLElement div, final ReportOutputFolder base)139 	private static void breadcrumbParent(final ReportPage page,
140 			final HTMLElement div, final ReportOutputFolder base)
141 			throws IOException {
142 		if (page != null) {
143 			breadcrumbParent(page.parent, div, base);
144 			div.a(page, base);
145 			div.text(" > ");
146 		}
147 	}
148 
footer(final HTMLElement body)149 	private void footer(final HTMLElement body) throws IOException {
150 		final HTMLElement footer = body.div(Styles.FOOTER);
151 		final HTMLElement versioninfo = footer.span(Styles.RIGHT);
152 		versioninfo.text("Created with ");
153 		versioninfo.a(JaCoCo.HOMEURL).text("JaCoCo");
154 		versioninfo.text(" ").text(JaCoCo.VERSION);
155 		footer.text(context.getFooterText());
156 	}
157 
158 	/**
159 	 * Specifies the local file name of this page.
160 	 *
161 	 * @return local file name
162 	 */
getFileName()163 	protected abstract String getFileName();
164 
165 	/**
166 	 * Creates the actual content of the page.
167 	 *
168 	 * @param body
169 	 *            body tag of the page
170 	 * @throws IOException
171 	 *             in case of IO problems with the report writer
172 	 */
content(final HTMLElement body)173 	protected abstract void content(final HTMLElement body) throws IOException;
174 
175 	// === ILinkable ===
176 
getLink(final ReportOutputFolder base)177 	public final String getLink(final ReportOutputFolder base) {
178 		return folder.getLink(base, getFileName());
179 	}
180 
181 }
182