------------------------- LibreCCM Code Conventions ------------------------- Jens Pelzetter ------------------------- 2015-06-29 ------------------------- LibreCCM Code Conventions The LibreCCM project uses the following code conventions. * Target language and platform The target language of the project is Java 8. LibreCCM also uses the {{{http://www.jcp.org/en/jsr/detail?id=342}Java EE 7 platform}}. In particular LibreCCM makes heavy use of the following APIs from the Java EE 7 standard: * {{{http://www.jcp.org/en/jsr/detail?id=338}Java Persistence API (JPA) 2.1}} * {{{http://www.jcp.org/en/jsr/detail?id=340}Servlet 3.1}} * {{{http://www.jcp.org/en/jsr/detail?id=346}Context and Dependency Injection for the Java EE platform (CDI) 1.1}} [] In consequence LibreCCM requires a Java EE compatible application server to like {{{http://wildfly.org/}Wildfly}} to run. We will stay as close to the standard as possible, but in some cases we will enforce a specific implementation. * Coding style The LibreCCM project uses the the {{{http://google.github.io/styleguide/javaguide.html}Google Java Style}} with the following modifications: [Block indentation] 4 spaces [Column limit (line length)] 80 characters [Imports] Star imports are allowed for static imports ** Imports ordering * All static import in a single group * All imports from com.arsdigita, org.libreccm, org.librecms, org.aplaws and org.scientificcms * Third-party imports, in group per top-level package in ACSII sort order * java imports * javax imports * Style checking The ensure good code quality the LibreCCM project uses {{{http://findbugs.sourceforge.net/}FindBugs}} and {{{http://pmd.sourceforge.net/}PMD}} to check the code for potential bugs and other problems. Code for the official modules <> pass all checks from FindBugs and must follow the followings rule sets from PMD: * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/basic.html}Basic}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/braces.html}Braces}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/clone.html}Clone}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/codesize.html}Code Size}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/design.html}Design}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/empty.html}Empty code}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/finalizers.html}Finalizers}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/imports.html}Import statements}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/javabeans.html}Java Beans}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/naming.html}Naming}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/optimizations.html}Optimizations}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/strictexception.html}Strict exception}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/strings.html}String and StringBuffer}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/sunsecure.html}Security Code Guidelines}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/typeresolution.html}Type resolution}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/unnecessary.html}Unnecessary}} * {{{http://pmd.sourceforge.net/pmd-5.3.2/pmd-java/rules/java/unusedcode.html}Unused code}} [] In some cases it might necessary to suppress warnings. For FindBugs this can be done using the <<>> annotation (see {{http://findbugs.sourceforge.net/manual/annotations.html}}. To do that it is necessary to add the following dependency to the POM of the module: -------------------------------------------------------------------------------- net.sourceforge.findbugs annotations 1.3.2 provided ------------------------------------------------------------------------------- The scope here is <<>> because the necessary JAR file has already been added due to the use of the FindBugs Maven plugin. For PMD the standard annotation <<<@SuppressWarnings>>> can be used: -------------------------------------------------------------------------------- @SuppressWarning("PMD.$rulename") -------------------------------------------------------------------------------- where <<<$rulename>>> is the name of rule. For example if you have a variable which name is longer than 17 characters and you can't shorten the name without making the name cryptic. Example: -------------------------------------------------------------------------------- ... SuppressWarnings("PMD.LongVariable") private boolean passwordResetRequired; ... -------------------------------------------------------------------------------- In this case it is not possible to shorten the name of the variable without making the name of the variable cryptic. The names of the rules can be found in the PMD documentation (see links to the rulesets above). In every case each usage of <<>> or <<>> must be accompanied by an comment in the same line or above the usage of the <<>> annotation. For example -------------------------------------------------------------------------------- ... SuppressWarnings("PMD.LongVariable") //Name is fine private boolean passwordResetRequired; ... -------------------------------------------------------------------------------- or (better) -------------------------------------------------------------------------------- ... //Can't reduce the name without making the name cryptic SuppressWarnings("PMD.LongVariable") private boolean passwordResetRequired; ... -------------------------------------------------------------------------------- * Package and class names Official modules should use on the following packages depending to which subproject they belong: *-------------------------*----------------------------------------------------* | <<>> | Core components or other common components | *-------------------------*----------------------------------------------------* | <<>> | Common content management components including | | | common content types like Article or NewsItem | *-------------------------*----------------------------------------------------* | <<>> | Classes of modules for usage by local authorities | | | or other public organisations | *-------------------------*----------------------------------------------------* | <<>> | Classes of modules for Scientific research | | | organisations, universities etc. | *-------------------------*----------------------------------------------------* Try to avoid class prefixes or long class names. Instead add an additional level to the package hierarchy. Use descriptive names for the packages. Package and class names should be chosen to be intuitive. A new developer should be able to figure out the the general purpose of a class solely by its package and name. A practical example: Each content type should get its own package. Instead of <<>> use <<>>. This rules apply only for package and classes in the official modules. Third-party modules should use the name of the organisation as package, plus the name of the official parent project. For example a custom module for LibreCMS, for instance a new content type, should use <<>> as package. When a third-party module is promoted to an official module it has to be refactored.