SourceHighlighter.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.BufferedReader;
15import java.io.IOException;
16import java.io.Reader;
17import java.util.Arrays;
18
19import org.jacoco.core.analysis.ILines;
20import org.jacoco.report.html.resources.Styles;
21
22/**
23 * Creates a highlighted output of a source file.
24 *
25 * @author Marc R. Hoffmann
26 * @version 0.4.1.20101007204400
27 */
28public class SourceHighlighter {
29
30 /** Number of characters reserved for the line number column */
31 private static final int LINENR_WIDTH = 5;
32
33 private String tabReplacement;
34
35 private String lang = "java";
36
37 /**
38 * Creates a new highlighter with default settings.
39 */
40 public SourceHighlighter() {
41 setTabWidth(4);
42 }
43
44 /**
45 * Specifies the number of spaces that are represented by a single tab.
46 * Default is 4.
47 *
48 * @param width
49 * spaces per tab
50 */
51 public void setTabWidth(final int width) {
52 final char[] blanks = new char[width];
53 Arrays.fill(blanks, ' ');
54 tabReplacement = new String(blanks);
55 }
56
57 /**
58 * Specifies the source language. This value might be used for syntax
59 * highlighting. Default is "java".
60 *
61 * @param lang
62 * source language identifier
63 */
64 public void setLanguage(final String lang) {
65 this.lang = lang;
66 }
67
68 /**
69 * Highlights the given source file.
70 *
71 * @param parent
72 * parent HTML element
73 * @param lines
74 * highlighting information
75 * @param contents
76 * contents of the source file
77 * @throws IOException
78 * problems while reading the source file or writing the output
79 */
80 public void render(final HTMLElement parent, final ILines lines,
81 final Reader contents) throws IOException {
82 final HTMLElement pre = parent.pre(Styles.SOURCE + " lang-" + lang);
83 final BufferedReader lineBuffer = new BufferedReader(contents);
84 String line;
85 int nr = 0;
86 while ((line = lineBuffer.readLine()) != null) {
87 nr++;
88 renderLineNr(pre, nr);
89 renderCodeLine(pre, line, lines.getStatus(nr));
90 }
91 }
92
93 private void renderLineNr(final HTMLElement pre, final int nr)
94 throws IOException {
95 final String linestr = String.valueOf(nr);
96 final HTMLElement linespan = pre.span(Styles.NR, "L" + linestr);
97 for (int i = linestr.length(); i < LINENR_WIDTH; i++) {
98 linespan.text("\u00A0"); // non-breaking space
99 }
100 linespan.text(linestr);
101 }
102
103 private void renderCodeLine(final HTMLElement pre, final String line,
104 final int status) throws IOException {
105 highlight(pre, status).text(line.replace("\t", tabReplacement));
106 pre.text("\n");
107 }
108
109 private HTMLElement highlight(final HTMLElement pre, final int status)
110 throws IOException {
111 switch (status) {
112 case ILines.NOT_COVERED:
113 return pre.span(Styles.NOT_COVERED);
114 case ILines.FULLY_COVERED:
115 return pre.span(Styles.FULLY_COVERED);
116 case ILines.PARTLY_COVERED:
117 return pre.span(Styles.PARTLY_COVERED);
118 default:
119 return pre;
120 }
121 }
122
123}