libreccm/src/site/apt/code-conventions.apt

199 lines
8.3 KiB
Plaintext

-------------------------
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 <<must>> 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 <<<edu.umd.cs.findbugs.annotations.SuppressWarnings>>>
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:
--------------------------------------------------------------------------------
<dependency>
<groupId>net.sourceforge.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>1.3.2</version>
<scope>provided</scope>
</dependency>
-------------------------------------------------------------------------------
The scope here is <<<provided>>> 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
<<<edu.umd.cs.findbugs.annotations.SuppressWarnings>>> or
<<<java.lang.SuppressWarnings>>> must be accompanied by an comment in the
same line or above the usage of the <<<SuppressWarnings>>> 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:
*-------------------------*----------------------------------------------------*
| <<<org.libreccm>>> | Core components or other common components |
*-------------------------*----------------------------------------------------*
| <<<org.librecms>>> | Common content management components including |
| | common content types like Article or NewsItem |
*-------------------------*----------------------------------------------------*
| <<<org.aplaws>>> | Classes of modules for usage by local authorities |
| | or other public organisations |
*-------------------------*----------------------------------------------------*
| <<<org.scientificcms>>> | 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 <<<org.librecms.contenttypes.SomeFanyContentTypeInitalizer>>> use
<<<org.librecms.contenttypes.somefanytype.Initalizer>>>.
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
<<<org.example.librecms.contenttypes.somefancytype>>> as package. When
a third-party module is promoted to an official module it has to be
refactored.