All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sourceforge.cobertura.reporting.html.JavaToHtml Maven / Gradle / Ivy

Go to download

Cobertura is a free Java tool that calculates the percentage of code accessed by tests. It can be used to identify which parts of your Java program are lacking test coverage. It is based on jcoverage.

There is a newer version: 2.1.1
Show newest version
/*
 * Cobertura - http://cobertura.sourceforge.net/
 *
 * Copyright (C) 2005 Mark Doliner
 *
 * Cobertura is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * Cobertura 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cobertura; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA
 */

package net.sourceforge.cobertura.reporting.html;

import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;

public class JavaToHtml {

	// Could use a J2SE 5.0 enum instead of this.
	public abstract static class State {
		public final static int COMMENT_JAVADOC = 0;
		public final static int COMMENT_MULTI = 1;
		public final static int COMMENT_SINGLE = 2;
		public final static int DEFAULT = 3;
		public final static int KEYWORD = 4;
		public final static int IMPORT_NAME = 5;
		public final static int PACKAGE_NAME = 6;
		public final static int QUOTE_DOUBLE = 8;
		public final static int QUOTE_SINGLE = 9;
	}

	// TODO: Set a style for JavaDoc tags
	//private static final Collection javaJavaDocTags;
	private static final Collection javaKeywords;
	private static final Collection javaPrimitiveLiterals;
	private static final Collection javaPrimitiveTypes;

	static {
		// TODO: Probably need to add anything new in J2SE 5.0
		//final String javaJavaDocTagsArray[] = { "see", "author", "version", "param", "return", "exception",
		//		"deprecated", "throws", "link", "since", "serial", "serialField", "serialData", "beaninfo" };
		final String[] javaKeywordsArray = {"abstract", "assert", "break",
				"case", "catch", "class", "const", "continue", "default", "do",
				"else", "extends", "final", "finally", "for", "goto", "if",
				"interface", "implements", "import", "instanceof", "native",
				"new", "package", "private", "protected", "public", "return",
				"static", "strictfp", "super", "switch", "synchronized",
				"this", "throw", "throws", "transient", "try", "volatile",
				"while"};
		final String javaPrimitiveTypesArray[] = {"boolean", "byte", "char",
				"double", "float", "int", "long", "short", "void"};
		final String javaPrimitiveLiteralsArray[] = {"false", "null", "true"};

		//javaJavaDocTags = new HashSet(Arrays.asList(javaJavaDocTagsArray));
		javaKeywords = new HashSet(Arrays.asList(javaKeywordsArray));
		javaPrimitiveTypes = new HashSet(Arrays.asList(javaPrimitiveTypesArray));
		javaPrimitiveLiterals = new HashSet(Arrays
				.asList(javaPrimitiveLiteralsArray));
	}

	private int state = State.DEFAULT;

	private static String escapeEntity(final char character) {
		if (character == '&')
			return "&";
		else if (character == '<')
			return "<";
		else if (character == '>')
			return ">";
		else if (character == '\t')
			return "        ";
		else
			return new Character(character).toString();
	}

	/**
	 * Add HTML colorization to a block of Java code.
	 *
	 * @param text The block of Java code.
	 *
	 * @return The same block of Java code with added span tags.
	 *         Newlines are preserved.
	 */
	public String process(final String text) {
		if (text == null)
			throw new IllegalArgumentException("\"text\" can not be null.");

		StringBuffer ret = new StringBuffer();

		// This look is really complicated because it preserves all
		// combinations of \r, \n, \r\n, and \n\r
		int begin, end, nextCR;
		begin = 0;
		end = text.indexOf('\n', begin);
		nextCR = text.indexOf('\r', begin);
		if ((nextCR != -1) && ((end == -1) || (nextCR < end)))
			end = nextCR;
		while (end != -1) {
			ret.append(processLine(text.substring(begin, end)) + "
"); if ((end + 1 < text.length()) && ((text.charAt(end + 1) == '\n') || (text.charAt(end + 1) == '\r'))) { ret.append(text.substring(end, end + 1)); begin = end + 2; } else { ret.append(text.charAt(end)); begin = end + 1; } end = text.indexOf('\n', begin); nextCR = text.indexOf('\r', begin); if ((nextCR != -1) && ((end == -1) || (nextCR < end))) end = nextCR; } ret.append(processLine(text.substring(begin))); return ret.toString(); } /** * Add HTML colorization to a single line of Java code. * * @param line One line of Java code. * * @return The same line of Java code with added span tags. */ private String processLine(final String line) { if (line == null) throw new IllegalArgumentException("\"line\" can not be null."); if ((line.indexOf('\n') != -1) || (line.indexOf('\r') != -1)) throw new IllegalArgumentException( "\"line\" can not contain newline or carriage return characters."); StringBuffer ret = new StringBuffer(); int currentIndex = 0; while (currentIndex != line.length()) { if (state == State.DEFAULT) { if ((currentIndex + 2 < line.length()) && line.substring(currentIndex, currentIndex + 3) .equals("/**")) { state = State.COMMENT_JAVADOC; } else if ((currentIndex + 1 < line.length()) && line.substring(currentIndex, currentIndex + 2) .equals("/*")) { state = State.COMMENT_MULTI; } else if ((currentIndex + 1 < line.length()) && (line.substring(currentIndex, currentIndex + 2) .equals("//"))) { state = State.COMMENT_SINGLE; } else if (Character.isJavaIdentifierStart(line .charAt(currentIndex))) { state = State.KEYWORD; } else if (line.charAt(currentIndex) == '\'') { state = State.QUOTE_SINGLE; } else if (line.charAt(currentIndex) == '"') { state = State.QUOTE_DOUBLE; } else { // Default: No highlighting. ret.append(escapeEntity(line.charAt(currentIndex++))); } } // End of State.DEFAULT else if ((state == State.COMMENT_MULTI) || (state == State.COMMENT_JAVADOC)) { // Print everything from the current character until the // closing */ No exceptions. ret.append(""); while ((currentIndex != line.length()) && !((currentIndex + 1 < line.length()) && (line .substring(currentIndex, currentIndex + 2) .equals("*/")))) { ret.append(escapeEntity(line.charAt(currentIndex++))); } if (currentIndex == line.length()) { ret.append(""); } else { ret.append("*/"); state = State.DEFAULT; currentIndex += 2; } } // End of State.COMMENT_MULTI else if (state == State.COMMENT_SINGLE) { // Print everything from the current character until the // end of the line ret.append(""); while (currentIndex != line.length()) { ret.append(escapeEntity(line.charAt(currentIndex++))); } ret.append(""); state = State.DEFAULT; } // End of State.COMMENT_SINGLE else if (state == State.KEYWORD) { StringBuffer tmp = new StringBuffer(); do { tmp.append(line.charAt(currentIndex++)); } while ((currentIndex != line.length()) && (Character.isJavaIdentifierPart(line .charAt(currentIndex)))); if (javaKeywords.contains(tmp.toString())) ret.append("" + tmp + ""); else if (javaPrimitiveLiterals.contains(tmp.toString())) ret.append("" + tmp + ""); else if (javaPrimitiveTypes.contains(tmp.toString())) ret.append("" + tmp + ""); else ret.append(tmp); if (tmp.toString().equals("import")) state = State.IMPORT_NAME; else if (tmp.toString().equals("package")) state = State.PACKAGE_NAME; else state = State.DEFAULT; } // End of State.KEYWORD else if (state == State.IMPORT_NAME) { ret.append(escapeEntity(line.charAt(currentIndex++))); state = State.DEFAULT; } // End of State.IMPORT_NAME else if (state == State.PACKAGE_NAME) { ret.append(escapeEntity(line.charAt(currentIndex++))); state = State.DEFAULT; } // End of State.PACKAGE_NAME else if (state == State.QUOTE_DOUBLE) { // Print everything from the current character until the // closing ", checking for \" ret.append(""); do { ret.append(escapeEntity(line.charAt(currentIndex++))); } while ((currentIndex != line.length()) && (!(line.charAt(currentIndex) == '"') || ((line .charAt(currentIndex - 1) == '\\') && (line .charAt(currentIndex - 2) != '\\')))); if (currentIndex == line.length()) { ret.append(""); } else { ret.append("\""); state = State.DEFAULT; currentIndex++; } } // End of State.QUOTE_DOUBLE else if (state == State.QUOTE_SINGLE) { // Print everything from the current character until the // closing ', checking for \' ret.append(""); do { ret.append(escapeEntity(line.charAt(currentIndex++))); } while ((currentIndex != line.length()) && (!(line.charAt(currentIndex) == '\'') || ((line .charAt(currentIndex - 1) == '\\') && (line .charAt(currentIndex - 2) != '\\')))); if (currentIndex == line.length()) { ret.append(""); } else { ret.append("\'"); state = State.DEFAULT; currentIndex++; } } // End of State.QUOTE_SINGLE else { // Default: No highlighting. ret.append(escapeEntity(line.charAt(currentIndex++))); } // End of unknown state } return ret.toString(); } /** * Reset the state of this Java parser. Call this if you have * been parsing one Java file and you want to begin parsing * another Java file. */ public void reset() { state = State.DEFAULT; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy