This software is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative.
The license (Mozilla version 1.0) can be read at the MMBase site. See http://www.mmbase.org/license
Table of Contents
The following is a summary of coding standards that need to be applied to source code.
All future sources need to conform to these standards.
The style conventions were based on suggestions from the following documents:
Code Conventions for the JavaTM Programming Language
This is the basis for these guidelines. Unless otherwise specified, the conventions described here follow those as outlined in the above document.
AmbySoft Inc. Coding Standards for Java
This document contains several suggestions which were used to expand the standard conventions, especially for naming identifiers.
Ottinger's Rules for Variable and Class Naming
This document also contains suggestions for naming, focused on improving the readability of your code.
We understand that formatting is a matter of taste and that many developers prefer other formmatting styles, but try to stick to the guidelines. We are using them to keep the code readable. Don't take it personally when someone points you to the coding standards when you submit some code. We will accept your code anyway.
Every method, whether public or private, must start out with a documentation comment that describes what the method does. The documentation should mention every parameter received by the method, every possible return value, and (if not obvious) the conditions under which the method could return an error. Put the parameter names in the same case in the doc string as in the method signature,
Read over the MMBase code to get an overview of how documentation looks in practice; in particular, see src/org/mmbase/bridge/* for examples.
Use Single line documentation (// ...) for in-code documentation.
Single line comments should be on their own line, preceding the statement concerned. The exception is local variables declaration, where the line comment may follow directly behind the declaration.
Required javadoc tags:
For a class/interface:
@author (by alphabetical order)
@version (versions should be annotated with @version $Id: codingstandards.xml,v 1.6 2004/02/17 10:21:13 gerard Exp $ , so that CVS can insert the correct version number.)
For a member function:
@param
@return
@exception
From version 1.5 of MMBase and onwards, new classes and member functions should contain the @sincetag (i.e. @since MMBase-1.6)
The version to use during development will be defined by the MMC.
Use Single line documentation (// ...) for in-code documentation.
Single line comments should be on their own line, preceding the statement concerned. The exception is local variables declaration, where the line comment may follow directly behind the declaration.
If you are one of those developers who has a personal issue with documentation then at least document the public methods of your code. Public methods can be used by everyone and should have a clear contract. One exception to this rule are getter and setter methods.
Names should be full English descriptors where possible. They should be smaller than 20 characters and unique within the context.
Interface names may be :
Case:
Indentation is four spaces for each block. Do not use tabs.
This deviates from some standards, there are differences in how people use tabs or how editors show them. The alternate would be to use ONLY tabs (which is not likely to work).
Placing of braces for blocks follow the C-standard :
statement { otherstatement; }
Elements in a class should be ordered in the following way:
createAlias()
,
createObject()
. The prefixes add and insert are only used for Collections.deleteAlias
,
deleteRelations
).MMBase has it's own logging facility (similar, but older than commons logging).
Every class has its own logger, identified with the name of the class. The logger instance is final static private. It is not necessary that the logger instance is used, and therefore this is perhaps the only variable which need not be removed if it is not used.
MMBase has the following logging levels, from low to high.
trace. log.trace can be used for things which happen very often, and can be used during debugging. log.trace should be protected by log.isDebugEnabled, especially if the argument is costly (complicated toStrings, may concatations). In inner-loops log.trace should perhaps not be used at all (or commented out).
debug. log.debug can be used for things which happen not very often, but still are only interesing during debugging. log.debug should be protected by log.isDebugEnabled, especially if the argument is costly (complicated toStrings, may concatations). In inner-loops log.debug should not be used at all (or commented out).
service. log.service is to be used for events which can interest the interested administrator. It is used for things which happen only seldomly, and which may be heavy on resources (like for example sending mail or converting an image). It can also be used for one-time messages during start-up and shutdown.
info. log.info is even higher then 'service'. Even uninterested adminstrators need to know this, or probably want to know this. Very important things during startup and shut-down or otherwise one-time only events can also be logged on info.
warn. If something's wrong, but there exist a reasonable fall-back, the event can be logged as a warning.
error. If something's wrong, and no reasonable fall-back exists, the event can be logged as an error.
fatal. Something is so wrong, that MMBase will not work any more. This can be logged as fatal error. E.g. no database-connection could be acquired.
When using the value of a variable in the log message and there exists even the tiniest chance that this variable's toString evaluates to the empty String, single quotes must surround the value. Make absolutely sure that not accidently an Exception (especially NullPointerException) can be caused during the creation of the message.
The first lines of a method are usually devoted to checking the validity of all arguments. The idea is to fail as quickly as possible in the event of an error. This is particularly important for constructors.
For non-private methods, an Exception is thrown if a test on an argument fails. This is often IllegalArgumentException or NullPointerException. (These are RuntimeExceptions. Checked exceptions may also be thrown Document these exceptions in the @throws clause of the method's javadoc, since they clearly state the method's requirements to the caller (the pre-conditions).
If every object parameter of every method in a class needs to be non-null in order to avoid throwing NullPointerException, then it is acceptable to state this once in the general class javadoc, instead of repeating it for each method.
To build Strings dynamically, one may use either the String concatenation operator + or the StringBuffer class. In the great majority of cases, only a few items are concatenated, and either style may be used freely, according to taste, without concern for performance.
On relatively rare occasions, however, when performing extensive String manipulation, replacing + with StringBuffer.append is recommended. This is because the + operator does not scale well to large numbers of operations, and is much slower than StringBuffer.append under such circumstances.
Cases in which + is very likely acceptable :
Portability is one of the principal advantages of using Java. Guidelines for ensuring that a Java application remains portable are:
Much of object programming is centered on minimizing the ripple effects caused by changes to a program. This is done simply by keeping details secret (information hiding or encapsulation).
The principal ways of doing this are
All of these techniques accomplish the same thing - they confine knowledge of implementation details to the smallest possible part of a program. That is, they keep a secret of some sort.
Constant and liberal use of the above techniques is recommended. For example:
For error messages the following conventions apply:
Exceptions in java are used to communicate errors between a callee and a caller. They aren't supposed to be used for control flow (throw and catch in the same method). Exception declarations are usually found on the boundaries of an API.
A section on writing error messages can be found elsewhere in this document under the title 'Error message conventions'.
Here are some of the guidelines for exception handling in MMBase.
Never throw the error upwards, unmodified:
try { ...... } catch(Exception e) { throw e; }
This code only pollutes the code base and adds nothing.
If you *receive* an error, you have two choices:
This is part of the MMBase documentation.
For questions and remarks about this documentation mail to: [email protected]