/* * $Id$ * * Copyright 2006, The jCoderZ.org Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * Neither the name of the jCoderZ.org Project nor the names of * its contributors may be used to endorse or promote products * derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.jcoderz.phoenix.report; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; import org.jcoderz.phoenix.checkstyle.message.jaxb.CheckstyleMessages; import org.jcoderz.phoenix.checkstyle.message.jaxb.FindingData; /** * Enumeration type for checkstyle findings. * It also holds a method to get the finding type from the message * received. This is needed due to the fact that there is no reliable * enumeration of checkstyle findings delivered with checkstyle. * <p>New patterns might be needed with each checkstyle update.</p> * <p>Once assigned the symbols should not be changed without a urgent * need. The symbols are used to generate wiki page link.</p> * * @author Andreas Mandel */ public final class CheckstyleFindingType extends FindingType { private static final List<CheckstyleFindingType> CHECKSTYLE_FINDING_TYPES; private static final String CHECKSTYLE_MESSAGE_JAXB_CONTEXT = "org.jcoderz.phoenix.checkstyle.message.jaxb"; private static final String CHECKSTYLE_MESSAGE_FILE = "org/jcoderz/phoenix/checkstyle/checkstyle-messages.xml"; private final String mMessagePattern; private final Severity mSeverity; static { CHECKSTYLE_FINDING_TYPES = new ArrayList<CheckstyleFindingType>(); } /** * Checkstyle finding type that relates to: * <i>Interfaces should describe a type and hence have methods</i>. */ public static final CheckstyleFindingType CS_INTERFACE_TYPE = new CheckstyleFindingType("CS_INTERFACE_TYPE", "Interface type.", "Interfaces should describe a type and hence have methods.", "interfaces should describe a type and hence have methods.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>Line is longer than the allowed number of characters</i>. */ public static final CheckstyleFindingType CS_LINE_TO_LONG = new CheckstyleFindingType("CS_LINE_TO_LONG", "Line too long.", "Line is longer than the allowed number of characters.", "Line is longer than [0-9]+ characters."); /** * Checkstyle finding type that relates to: * <i>Line does not match expected header line</i>. */ public static final CheckstyleFindingType CS_HEADER_MISMATCH = new CheckstyleFindingType("CS_HEADER_MISMATCH", "Header does not match.", "Line does not match expected header line. " + "Please use the global header.", "Line does not match expected header line of .*\\."); /** * Checkstyle finding type that relates to: * <i>Missing a Javadoc comment</i>. */ public static final CheckstyleFindingType CS_JAVADOC_MISSING = new CheckstyleFindingType("CS_JAVADOC_MISSING", "Missing a Javadoc comment.", "Missing a Javadoc comment.", "Missing a Javadoc comment\\."); /** * Checkstyle finding type that relates to: * <i>Missing a Javadoc comment</i>. */ public static final CheckstyleFindingType CS_JAVADOC_EMPTY_DESC = new CheckstyleFindingType("CS_JAVADOC_EMPTY_DESC", "Javadoc has empty description section.", "Javadoc has empty description section.", "Javadoc has empty description section\\."); /** * Checkstyle finding type that relates to: * <i>Unused Javadoc tag</i>. */ public static final CheckstyleFindingType CS_JAVADOC_UNUSED_TAG = new CheckstyleFindingType("CS_JAVADOC_UNUSED_TAG", "Unused Javadoc tag.", "Unused Javadoc tag.", "Unused .* tag for '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Expected an @return tag</i>. */ public static final CheckstyleFindingType CS_JAVADOC_RETURN_EXPECTED = new CheckstyleFindingType("CS_JAVADOC_RETURN_EXPECTED", "Expected an @return tag.", "Expected an @return tag.", "Expected an @return tag."); /** * Checkstyle finding type that relates to: * <i>Missing Javadoc tag</i>. */ public static final CheckstyleFindingType CS_JAVADOC_EXPECTED_TAG = new CheckstyleFindingType("CS_JAVADOC_EXPECTED_TAG", "Missing Javadoc tag.", "Missing Javadoc tag.", "Expected .* tag for '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Unable to get class information for something</i>. */ public static final CheckstyleFindingType CS_JAVADOC_CLASS_INFO = new CheckstyleFindingType("CS_JAVADOC_CLASS_INFO", "Unable to get class information for something.", "Unable to get class information for something.", "Unable to get class information for .* tag '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Incomplete/Unclosed HTML tag</i>. */ public static final CheckstyleFindingType CS_JAVADOC_HTML_UNCLOSED = new CheckstyleFindingType("CS_JAVADOC_HTML_UNCLOSED", "Incomplete HTML tag.", "Incomplete/Unclosed HTML tag.", "Incomplete HTML tag found: .*"); /** * Checkstyle finding type that relates to: * <i>Name does not match given pattern</i>. */ public static final CheckstyleFindingType CS_INVALID_PATTERN = new CheckstyleFindingType("CS_INVALID_PATTERN", "Name does not match given pattern.", "Name does not match given pattern.", "Name '.*' must match pattern '.*'\\."); /** * Checkstyle finding type that relates to: * <i>After the method declaration there should be a ' '</i>. */ public static final CheckstyleFindingType CS_NO_WHITESPACE_AFTER_MSG_DECL = new CheckstyleFindingType("CS_NO_WHITESPACE_AFTER_MSG_DECL", "Missing whitespace.", "After the method declaration there should be a ' '.", "No whitespace \\( \\(\\) after method declaration\\."); /** * Checkstyle finding type that relates to: * <i>Comment matches to-do format</i>. */ public static final CheckstyleFindingType CS_TODO = new CheckstyleFindingType("CS_TODO", "Comment matches to-do format.", "Comment matches to-do format.", "Comment matches to-do format '.*'\\.", Severity.INFO); /** * Checkstyle finding type that relates to: * <i>Dont use magics in the code</i>. */ public static final CheckstyleFindingType CS_MAGIC = new CheckstyleFindingType("CS_MAGIC", "Dont use magics in the code.", "Magics make the code hard to maintain and understand. " + " Define appropriate constant instead.", "Dont use magic .* in the code\\."); /** * Checkstyle finding type that relates to: * <i>Whitespace not allowed</i>. */ public static final CheckstyleFindingType CS_WHITESPACE_AFTER = new CheckstyleFindingType("CS_WHITESPACE_AFTER", "Whitespace not allowed.", "Whitespace not allowed.", "'.*' is followed by whitespace\\."); /** * Checkstyle finding type that relates to: * <i>Whitespace expected</i>. */ public static final CheckstyleFindingType CS_NO_WHITESPACE_AFTER = new CheckstyleFindingType("CS_NO_WHITESPACE_AFTER", "Whitespace expected.", "Whitespace expected.", "'.*' is not followed by whitespace\\."); /** * Checkstyle finding type that relates to: * <i>Whitespace not allowed</i>. */ public static final CheckstyleFindingType CS_WHITESPACE_BEFORE = new CheckstyleFindingType("CS_WHITESPACE_BEFORE", "Whitespace not allowed.", "Whitespace not allowed.", "'.*' is preceeded with whitespace\\."); /** * Checkstyle finding type that relates to: * <i>Whitespace expected</i>. */ public static final CheckstyleFindingType CS_NO_WHITESPACE_BEFORE = new CheckstyleFindingType("CS_NO_WHITESPACE_AFTER", "Whitespace expected.", "Whitespace expected.", "'.*' is not preceeded with whitespace\\."); /** * Checkstyle finding type that relates to: * <i>A required javadoc tag is missing</i>. */ public static final CheckstyleFindingType CS_MISSING_TAG = new CheckstyleFindingType("CS_MISSING_TAG", "A required javadoc tag is missing.", "A required javadoc tag is missing.", "Type Javadoc comment is missing an .* tag\\."); /** * Checkstyle finding type that relates to: * <i>A field is hidden</i>. */ public static final CheckstyleFindingType CS_HIDDEN_FIELD = new CheckstyleFindingType("CS_HIDDEN_FIELD", "A field is hidden.", "A field is hidden.", "'.*' hides a field\\.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>Line contains a tab character</i>. */ public static final CheckstyleFindingType CS_CONTAINS_TAB = new CheckstyleFindingType("CS_CONTAINS_TAB", "Line contains a tab character.", "Line contains a tab character. You should use spaces for " + "indentation.", "Line contains a tab character\\."); /** * Checkstyle finding type that relates to: * <i>File does not end with a newline</i>. */ public static final CheckstyleFindingType CS_NO_NEWLINE = new CheckstyleFindingType("CS_NO_NEWLINE", "File does not end with a newline.", "File does not end with a newline.", "File does not end with a newline\\."); /** * Checkstyle finding type that relates to: * <i>Method length exceeds the maximum allowed length</i>. */ public static final CheckstyleFindingType CS_MAX_LEN_METHOD = new CheckstyleFindingType("CS_MAX_LEN_METHOD", "Method length exceeds the maximum allowed length.", "A Method should have a moderate length...", "Method length is [\\.,0-9]+ lines \\(max allowed is [\\.,0-9]+\\)\\.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>Length of anonymous inner class exceeds the maximum allowed length</i>. */ public static final CheckstyleFindingType CS_MAX_LEN_ANON_CLASS = new CheckstyleFindingType("CS_MAX_LEN_ANON_CLASS", "Length of anonymous inner class exceeds the maximum allowed length.", "A anonymous inner class should have a moderate length...", "Anonymous inner class length is [0-9]+ lines " + "\\(max allowed is [0-9]+\\)\\.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>Empty block detected</i>. */ public static final CheckstyleFindingType CS_EMPTY_BLOCK = new CheckstyleFindingType("CS_EMPTY_BLOCK", "Empty block detected.", "If you think this is ok you must at least put a comment inside " + "this block, describing why it is ok.", "Empty .* block\\."); /** * Checkstyle finding type that relates to: * <i>Unused import</i>. */ public static final CheckstyleFindingType CS_IMPORT_UNUSED = new CheckstyleFindingType("CS_IMPORT_UNUSED", "Unused import.", "Unused import.", "Unused import - .*\\."); /** * Checkstyle finding type that relates to: * <i>Indentation violation</i>. */ public static final CheckstyleFindingType CS_SPECIAL_INDENT = new CheckstyleFindingType("CS_SPECIAL_INDENT", "Indentation violation.", "Several keywords require a special indentation.", "Expected indentation for '.*' is '.*' but was at '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Deeply nested tries</i>. */ public static final CheckstyleFindingType CS_NESTED_TRY_DEPTH = new CheckstyleFindingType("CS_NESTED_TRY_DEPTH", "Deeply nested tries.", "The nesting level for the try/catches is to deep.", "Nested try depth is [0-9]+ \\(max allowed is [0-9]+\\)\\.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>Too many parameters</i>. */ public static final CheckstyleFindingType CS_NUMBER_OF_PARAMETERS = new CheckstyleFindingType("CS_NUMBER_OF_PARAMETERS", "Too many parameters.", "Too many parameters.", "More than [0-9]+ parameters\\.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>Method unused</i>. */ public static final CheckstyleFindingType CS_METHOD_UNUSED = new CheckstyleFindingType("CS_METHOD_UNUSED", "Method unused.", "Method is never used.", "Unused private method '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Local variable unused</i>. */ public static final CheckstyleFindingType CS_LOCAL_VARIABLE_UNUSED = new CheckstyleFindingType("CS_LOCAL_VARIABLE_UNUSED", "Local variable unused.", "Local variable is never used.", "Unused local variable '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Indentation must be a multiple of 4</i>. */ public static final CheckstyleFindingType CS_ILLEGAL_INDENTATION = new CheckstyleFindingType("CS_ILLEGAL_INDENTATION", "Indentation must be a multiple of 4.", "Indentation must be a multiple of 4.", "Indentation must be a multiple of 4\\."); /** * Checkstyle finding type that relates to: * <i>Field is never used</i>. */ public static final CheckstyleFindingType CS_FIELD_UNUSED = new CheckstyleFindingType("CS_FIELD_UNUSED", "Field unused.", "Field is never used.", "Unused private field '.*'\\."); /** * Checkstyle finding type that relates to: * <i>The equals operator should be on a new line</i>. */ public static final CheckstyleFindingType CS_EQUALS_NEWLINE = new CheckstyleFindingType("CS_EQUALS_NEWLINE", "The equals operator should be on a new line.", "The equals operator should be on a new line.", "The equals operator should be on a new line\\."); /** * Checkstyle finding type that relates to: * <i>Line matches a illegal pattern</i>. */ public static final CheckstyleFindingType CS_ILLEGAL_LINE = new CheckstyleFindingType("CS_ILLEGAL_PATTERN", "Line matches a illegal pattern.", "Line matches a illegal pattern.", "Line matches the illegal pattern '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Long constants should use a uppercase L</i>. */ public static final CheckstyleFindingType CS_UPPER_CASE_L = new CheckstyleFindingType("CS_UPPER_CASE_L", "Use uppercase L.", "Long constants should use a uppercase L the lower case L looks " + "a lot like 1. 123L vs. 123l.", "Should use uppercase 'L'\\."); /** * Checkstyle finding type that relates to: * <i>Invalid log level for trace log</i>. */ public static final CheckstyleFindingType CS_NO_LOG_LEVEL_INFO = new CheckstyleFindingType("CS_NO_LOG_LEVEL_INFO", "Invalid log level for trace log.", "Trace log messages should have log level smaller than info, for " + "higher severity use predefined log messages.", "Maximum allowed log level for trace log is '.*' but was '.*'\\.", Severity.DESIGN); /** * Checkstyle finding type that relates to: * <i>The brace should not be on a new line</i>. */ public static final CheckstyleFindingType CS_BRACE_ON_NEW_LINE = new CheckstyleFindingType("CS_BRACE_ON_NEW_LINE", "The brace should not be on a new line.", "The brace should not be on a new line.", "'[\\{\\}\\(\\)]' should be on the (previous|same) line\\."); /** * Checkstyle finding type that relates to: * <i>Avoid inline conditionals</i>. */ public static final CheckstyleFindingType CS_INLINE_CONDITIONAL = new CheckstyleFindingType("CS_INLINE_CONDITIONAL", "Avoid inline conditionals.", "Avoid inline conditionals.", "Avoid inline conditionals\\."); /** * Checkstyle finding type that relates to: * <i>Avoid redundant code</i>. */ public static final CheckstyleFindingType CS_REDUNDANT_MODIFIER = new CheckstyleFindingType("CS_REDUNDANT_MODIFIER", "Avoid redundant code.", "Avoid redundant code.", "Redundant '.*' modifier\\."); /** * Checkstyle finding type that relates to: * <i>Javadoc Pattern</i>. */ public static final CheckstyleFindingType CS_JAVADOC_PATTERN = new CheckstyleFindingType("CS_JAVADOC_PATTERN", "Javadoc pattern violation.", "The javadoc tag does not comply to the required pattern.", "Type Javadoc tag .* must match pattern '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Redundant throws with subclass.</i>. */ public static final CheckstyleFindingType CS_REDUNDANT_THROWS_SUBCLASS = new CheckstyleFindingType("CS_REDUNDANT_THROWS_SUBCLASS", "Redundant throws declaration of a subclass.", "The throws statement already contains the superclass and so" + "declaring a subclass is redundant.", "Redundant throws: '.*' is subclass of '.*'\\."); /** * Checkstyle finding type that relates to: * <i>Redundant throws with unchecked exception.</i>. */ public static final CheckstyleFindingType CS_REDUNDANT_THROWS_UNCHECKED = new CheckstyleFindingType("CS_REDUNDANT_THROWS_UNCHECKED", "Throws declaration of a unchecked exception is not needed.", "Throws declaration of a unchecked exception is not needed.", "Redundant throws: '.*' is unchecked exception\\."); /** * Checkstyle finding type that relates to: * <i>Boolean expression complexity is ... (max allowed is ...).</i>. */ public static final CheckstyleFindingType CS_BOOLEAN_EXPRESSION_COMPLEXITY = new CheckstyleFindingType("CS_BOOLEAN_EXPRESSION_COMPLEXITY", "Boolean expression is too complex.", "Boolean expression is too complex. " + "Too many conditions leads to code that is difficult to " + "read and hence debug and maintain.", "Boolean expression complexity is .* \\(max allowed is .*\\)\\."); /** * Checkstyle finding type that relates to: * <i>String comparison with ==.</i>. */ public static final CheckstyleFindingType CS_STRING_EQUALS_COMPARISON = new CheckstyleFindingType("CS_STRING_EQUALS_COMPARISON", "String comparison with ==.", "String comparison with ==.", "Literal Strings should be compared using equals\\(\\), not '=='\\."); /** * Checkstyle finding type that relates to: * <i>Missing package documentation file.</i>. */ public static final CheckstyleFindingType CS_MISSING_PACKAGE_DOCUMENTATION = new CheckstyleFindingType("CS_MISSING_PACKAGE_DOCUMENTATION", "Missing package documentation file.", "Package content should be documentet using a package.html or" + " package.xml file.", "Missing package documentation file\\."); /** * Checkstyle finding type that relates to: * <i>Unable to get class information for .....</i>. */ public static final CheckstyleFindingType CS_EXCEPTION_CLASS_NOT_FOUND = new CheckstyleFindingType("CS_EXCEPTION_CLASS_NOT_FOUND", "Unable to get class information for certain class.", "Mostly this is caused by a checkstyle internal issue or a finder" + "class path setting.", "Unable to get class information for .*\\."); /** * Checkstyle finding type that relates to: * <i>Using '.*' is not allowed.</i>. */ public static final CheckstyleFindingType CS_TYPE_NOT_ALLOWED = new CheckstyleFindingType("CS_TYPE_NOT_ALLOWED", "Use of a type that is not permited.", "The type noted in the message should not be used.", "Using '.*' is not allowed\\."); /** * A internal checkstyle exception was triggered we shoulds also * report this! */ public static final CheckstyleFindingType CS_EXCEPTION = new CheckstyleFindingType("CS_EXCEPTION", "Checkstyle analysis exception.", "Exception during checkstyle analysis. There seems to be " + "something strange here. One often problem is a reference to a " + "Unknown or not visible class in Javadoc.", "Got an exception - .*\\."); private CheckstyleFindingType (String symbol, String shortText, String description, String messagePattern, Severity severity) { super(symbol, shortText, description); mMessagePattern = messagePattern; mSeverity = severity; CHECKSTYLE_FINDING_TYPES.add(this); } private CheckstyleFindingType (String symbol, String shortText, String description, String messagePattern) { this(symbol, shortText, description, messagePattern, Severity.CODE_STYLE); } /** * Reads the given message and tries to find a matching finding type. * @param message the message to read. * @return the finding type matching to the message, or null if no such * type was found. */ public static FindingType detectFindingTypeForMessage (String message) { new FindingType.LazyInit(); FindingType result = null; for (final CheckstyleFindingType type : CHECKSTYLE_FINDING_TYPES) { if (message.matches(type.getMessagePattern())) { result = type; break; } } return result; } /** @return the severity assigned to findings of this type by default. */ public Severity getSeverity () { return mSeverity; } /** * @return Returns the messagePattern. */ private String getMessagePattern () { return mMessagePattern; } /** * Init of the enum. */ public static void initialize () { try { final JAXBContext jaxbContext = JAXBContext.newInstance(CHECKSTYLE_MESSAGE_JAXB_CONTEXT, CheckstyleFindingType.class.getClassLoader()); final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); final CheckstyleMessages messageCollection = (CheckstyleMessages) unmarshaller.unmarshal( CheckstyleFindingType.class.getClassLoader(). getResourceAsStream(CHECKSTYLE_MESSAGE_FILE)); for (final FindingData e : (List<FindingData>) messageCollection.getFindingType()) { new CheckstyleFindingType(e.getSymbol(), e.getShortDescription(), e.getDetailedDescription(), e.getMessagePattern()); } } catch (Exception e) { throw new RuntimeException( "Cannot initialize CheckstyleFindingTypes", e); } } }