<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">

<!--

    A set of style checks for Java code that uses the Checkstyle
    project:

        http://checkstyle.sourceforge.net/

    This file can also be used with the Eclipse plug-in for Checkstyle:

        http://eclipse-cs.sourceforge.net/    

    author: Paul Constantinides
-->

<module name="Checker">

    <!-- Checks that the Java file ends with a line feed character. This an
         encouraged practice, especially for files that are managed by source
         control. -->
    <module name="NewlineAtEndOfFile">
        <property name="lineSeparator" value="lf"/>
    </module>

    <module name="TreeWalker">


        <!-- NAMING CONVENTIONS -->
        <!-- http://checkstyle.sourceforge.net/config_naming.html -->

        <!-- Requires that static final variables be named in all caps, or like
             static variables -->
        <module name="ConstantName">
            <property name="format" value="^s_[a-zA-Z0-9]+$|^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
        </module>

        <!-- Local final variables can either be all alphanumeric and
             start with a lowercase letter, or be all uppercase with
             numbers. -->
        <module name="LocalFinalVariableName">
            <property name="format" value="^[a-z][a-zA-Z0-9]*$|^[A-Z][A-Z0-9]*$"/>
        </module>

        <!-- Requires that all local variables be named with only alphanumerics
             starting with a lowercase letter -->
        <module name="LocalVariableName"/>

        <!-- Members variables names must be prefixed with m_ and be
             alphanumeric -->
        <module name="MemberName">
            <property name="format" value="^m_[a-zA-Z0-9]+$"/>
        </module>

        <!-- Methods must start with a lowercase and be alphanumeric -->
        <module name="MethodName"/>

        <!-- Package names must be . separated alphanumeric strings that start
             with a lower case letter -->
        <module name="PackageName"/>

        <!-- Parameter names must be alphanumeric and start with a lower case
             letter -->
        <module name="ParameterName"/>

        <!-- Static variables names must be prefixed with s_ and be
             alphanumeric -->
        <module name="StaticVariableName">
            <property name="format" value="^s_[a-zA-Z0-9]+$"/>
        </module>

        <!-- Type names must start with an uppercase letter and be
             alphanumeric -->
        <module name="TypeName"/>


        <!-- IMPORTS -->
        <!-- http://checkstyle.sourceforge.net/config_import.html -->

        <!-- Requires that imports be ordered and grouped correctly -->
        <module name="ImportOrder">
            <property name="groups"
                      value="java,javax,org,com"/>
            <property name="ordered" value="true"/>
            <property name="separated" value="true"/>
        </module>

        <!-- Disallow the same class from being imported if it is already
             visible -->
        <module name="RedundantImport"/>

        <!-- Identifies explicitly declared imports that are not used (does not
             use * notation) -->
        <module name="UnusedImports"/>


        <!-- WHITESPACE -->
        <!-- http://checkstyle.sourceforge.net/config_whitespace.html -->

        <!-- Disallows space between a method and constructor, definition or
             call and the open paren -->
        <module name="MethodParamPad"/>

        <!-- Disallows space or new lines after "++" (and decrement), ".",
             while, if, for, and catch. Note that these last 4 only work after
             Checkstyle version 3.4. Also, since synchronized can appear in two
             contexts, we handle the block case as a generic illegal regular
             expression. -->
        <module name="NoWhitespaceAfter">
            <property name="tokens" value="DEC, DOT, INC, LITERAL_WHILE, LITERAL_IF, LITERAL_FOR, LITERAL_CATCH"/>
            <property name="allowLineBreaks" value="false"/>
        </module>

        <!-- Disallows space before ";", ".", "++" (and decrement) -->
        <module name="NoWhitespaceBefore"/>

        <!-- Requires a space after a left paren and before a right paren -->
        <module name="ParenPad">
            <property name="option" value="space"/>
        </module>

        <!-- Disallows \t in source code -->
        <module name="TabCharacter"/>

        <!-- Disallows space with the parens of a typecast -->
        <module name="TypecastParenPad"/>

        <!-- Requires whitespace after ",", ";", and a typecast -->
        <module name="WhitespaceAfter"/>

        <!-- Requires whitespace around several different tokens,
             including: "=", "==", ">", "<", "{", "+=", etc. -->
        <module name="WhitespaceAround">
            <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LCURLY, LE, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_TRY, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, RCURLY, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN"/>
        </module>


        <!-- MODIFIERS -->
        <!-- http://checkstyle.sourceforge.net/config_modifiers.html -->

        <!-- Requires modifiers be in the correct order: public protected 
             private abstract static final transient volatile synchronized
             native strictfp -->
        <module name="ModifierOrder"/>


        <!-- BLOCKS -->
        <!-- http://checkstyle.sourceforge.net/config_blocks.html -->

        <!-- Disallows {} blocks that are dangling in the code -->
        <module name="AvoidNestedBlocks"/>

        <!-- Disallows empty blocks -->
        <module name="EmptyBlock"/>

        <!-- Ensures that the left curly appears on a new line -->
        <module name="LeftCurly">
            <property name="option" value="nl"/>
        </module>

        <!-- Requires that braces be used under do, else, for, and while -->
        <module name="NeedBraces"/>

        <!-- Ensures that the right curly appears on a new line -->
        <module name="RightCurly">
            <property name="option" value="alone"/>
        </module>


        <!-- CODING PROBLEMS -->
        <!-- http://checkstyle.sourceforge.net/config_coding.html -->

        <!-- Finds a test that is repeated inside and outside a synchronized
             block. Why this is does not work in Java is explained here:
             http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html -->
        <module name="DoubleCheckedLocking"/>

        <!-- TODO this uses the wrong order, fix to use the correct order -->
        <!-- <module name="DeclarationOrder"/> -->

        <!-- Requires that the default case be last in a switch statement -->
        <module name="DefaultComesLast"/>

        <!-- Disallows a standalone ";" -->
        <module name="EmptyStatement"/>

        <!-- Disallows the assignment of member variables to the default value
             for their type (e.g. null or false) -->
        <module name="ExplicitInitialization"/>

        <!-- Checks that a local variable does not shadow a field defined in
             the same class -->
        <module name="HiddenField"/>

        <!-- Disallows new operation on the supplied list of classes -->
        <module name="IllegalInstantiation">
        <!-- TODO Add more classes here -->
            <property name="classes"  value="java.lang.Boolean"/>
        </module>

        <!-- Disallow the declaration of variables of a set of types, where the
             interface should be used (TreeSet, ArrayList, etc.) -->
        <module name="IllegalType">
            <property name="illegalClassNames" value="java.util.GregorianCalendar, java.util.Hashtable, java.util.HashSet, java.util.HashMap, java.util.ArrayList, java.util.LinkedList, java.util.TreeSet, java.util.TreeMap, java.util.Vector"/>
        </module>

        <!-- Requires a default case in switch statments -->
        <module name="MissingSwitchDefault"/>

        <!-- Requires that each variable be declared on its own line -->
        <module name="MultipleVariableDeclarations"/>

        <!-- Ensure that the class has a package declaration -->
        <module name="PackageDeclaration"/>
        
        <!-- Disallows the assignment of a parameter (bad style, leads to code
             that is hard to follow) -->
        <module name="ParameterAssignment"/>

        <!-- Checks for redundancy in throws declarations -->
        <module name="RedundantThrows"/>

        <!-- Allow a maximum of 3 return statements in a method; this is an
             indicator that the code is overly complex -->
        <module name="ReturnCount">
            <property name="max" value="3"/>
        </module>

        <!-- Identifies boolean expressions that could be simplified for better
             readability -->
        <module name="SimplifyBooleanExpression"/>

        <!-- Identifies overly complicated boolean return statements -->
        <module name="SimplifyBooleanReturn"/>

        <!-- Requires that overridden clone methods call the super -->
        <module name="SuperClone"/>

        <!-- Requires that overridden finalize methods call the super -->
        <module name="SuperFinalize"/>

        <!-- Checks for parentheses that are not needed -->
        <module name="UnnecessaryParentheses"/>


        <!-- CLASS DESIGN -->
        <!--  http://checkstyle.sourceforge.net/config_design.html -->

        <!-- A class with only private constructors must be final -->
        <module name="FinalClass"/>

        <!-- Classes that contain only static fields and members must not have
             a public constructor -->
        <module name="HideUtilityClassConstructor"/>

        <!-- Disallows interfaces that only declare constants -->
        <module name="InterfaceIsType"/>

        <!-- Disallows exceptions that can mutated -->
        <module name="MutableException"/>

        <!-- Disallows members variables (non-constants) to be public -->
        <module name="VisibilityModifier">
            <property name="protectedAllowed" value="true"/>
        </module>


        <!-- MISC -->
        <!-- http://checkstyle.sourceforge.net/config_misc.html -->

        <!-- Requires Java style array declaration (e.g. String[] args, not
             String args[]) -->
        <module name="ArrayTypeStyle"/>

        <!-- Disallows whitespace after the synchronized keyword in a block -->
        <module name="GenericIllegalRegexp">
            <property name="format" value="synchronized\s+\("/>
            <property name="message" value="`synchronized` is followed by space"/>
        </module>

        <!-- Disallows use of the default constructor for StringBuffer -->
        <module name="GenericIllegalRegexp">
            <property name="format" value="new\s+StringBuffer\s*\(\s*\)"/>
            <property name="message" value="An initial size must always be passed when creating a StringBuffer"/>
        </module>

    </module>

</module>
