Conventions

This pages summaries the naming and coding conventions used in Chameleon.

Structure

The repository is structured as follow:
.
|- tags -> store tagged versions
|- branches -> used if we need to create branched from subproject
|- releases -> store tagged version created during a release
|- sandboxes -> member sandboxes
  |-cescoffier -> sandbox of clement
  |- …
|- trunk -> trunk root
  |- pom.xml -> Reactor pom file
  |- pom -> Main pom file (sub-project must inherits from that file)
  |- database -> Root of the database sub-project
     |- pom.xml -> Sub-project reactor file
     |- datasource -> common bundle storing service interfaces
     |- hsql -> HSQL implementation of the service
       |- pom.xml -> Pom file for the HSQL sub-project
       |- chameleon-hsql-> Implementation
       |- chameleon-hsql-it -> Integration Test
       |- chameleon-hsql-example -> Store usage example 
     |… -> Others implementations
  |- …

The structure may depends on the sub-project, but should be close to that one.

Launching mvn clean install must build the entire project.

Naming

Chameleon projects

  • The sub-project should follow this following scheme rules: main-subproject/$implementation_name/chameleon-$implementation_name.
  • Each sub-project may use it's own groupid following the convention : org.ow2.chameleon.$name
  • The artifact id may be : chameleon-$name
  • Bundle Name must begin by : OW2 Chameleon
  • The Bundle Symbolic Name must follows the convention: org.ow2.chameleon.subproject.$implementation_name
  • The bundle vendor must be: OW2 Chameleon
  • The package must start by : org.ow2.chameleon
For example, the transaction service based on the Geronimo transaction engine will use such names:
  • Folder: ./transaction/geronimo/chameleon-geronimo
  • Maven: [org.ow2.chameleon.transaction:chameleon-geronimo]
  • Bundle Name: OW2 Chameleon Transaction Service - Geronimo
  • Symbolic Name / Main Package Name: org.ow2.chameleon.transaction.geronimo
Tests will follows:
  • Folder : chameleon/transaction/geronimo/chameleon-geronimo-it
  • Maven : [org.ow2.chameleon.transaction:chameleon-geronimo-it]

Commons project

Commons projects are non Chameleon library bundlelized to be used inside OSGi. These project focus on the best OSGi integration, and so may slightly modified the original project. For such project the conventions differs a little bit:
  • The sub-project should follow this following scheme rules: commons/$library_name.
  • Each sub-project uses the original groupd id.
  • The artifact id may be : org.ow2.chameleon.commons-$library
  • Bundle Name must begin by : OW2 Chameleon $Library_Name
  • The Bundle Symbolic Name must follows the convention: org.ow2.chameleon.$library
  • The version must be the library version
  • Bundle-Vendor : OW2 Chameleon
  • Bundle-License : original license
  • Bundle-DocURL : chameleon wiki page or original web site if it's just a wrapping.
As an example, here is the names for the DOJO bundle:
  • Folder : /chameleon/commons/dojo
  • Group Id : org.dojotoolkit
  • Artifact ID : org.ow2.chameleon.dojo
  • Bundle Name : OW2 Chameleon DOJO Toolkit for OSGi
  • Bundle symbolic Name : org.ow2.chameleon.dojo (artifact id)
  • Version : 1.3.2
  • Bundle-Vendor : OW2 Chameleon
  • Bundle-License : original license (Apache License 2.0)
  • Bundle-DocURL : chameleon wiki page

Version Scheme and Policy

Development version must used odd numbers (as last digit) and be followed by -SNAPSHOT. For example, 0.0.1-SNAPSHOT is a development version, same thing for 1.3.0-SNAPSHOT.and 1.4.1-SNAPSHOT.

Released version must even numbers (as last digit) and must not be followed by -SNAPSHOT. For example, 0.2.0 is a release version, as 1.4.0 and 1.4.2.

Commons Libraries reuse the embedded library version. If modifications must be done a qualifier may be used: 1.3.2.2, where the last 2 is the added qualifier.

Code Convention

Header

The header of each file should contains the Apache License

/*
 * Copyright 2009 OW2 Chameleon
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

<!--
Copyright 2009 OW2 Chameleon
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -->

Imports

No wildcard imports are authorized. They have to be avoided. The imports should reference the correct classes.

ie : if you need to use List and ArrayList classes, don't do:

import java.util.*;
but :
import java.util.List;
import java.util.ArrayList;

Unused imports need to be removed.

  • Note that eclipse IDE allow you to do the job. (Source/Organize imports)

Class and Interface Declarations

The Class and Interface name begin with an Uppercase and have a javadoc comment with the @author tag. The author tag should contains the email address. ie :

/**
 * This is an example of a class
 * @author Clement Escoffier clement.escoffier@akquinet.de
 */
public class MyClass implements MyInterface {
}

The following table describes the parts of a class or interface declaration, in the order that they should appear.

Part of Class/Interface DeclarationNotes
Class/Interface documentationAccording to comment block as shown above.
Class or interface statement 
Class (static) variablesThese should be grouped by functionality rather than by scope.
Instance variablesThese should be grouped by functionality rather than by scope.
ConstructorsStart with the default constructor if any.
Methods that belong to the class(see also 2.1.3.4 Class methods versus specific interface methods and event methods) These methods should also be grouped by functionality rather than by scope or accessibility. E.g. a private class method can be in between two public instance methods. The goal is to make reading and understanding the code easier. When implementing an interface, group the methods that are part of the interface.
Methods of interfaces that are implemented by the class.Automatically grouped by functionality if grouped by interface.
Inner classesAs they are only visible within their top-level class, they are placed at the bottom of the file.

Indentation / WhiteSpace

Indentation

No tabs characters are used. Always use space characters and the number of the characters for an indent is 4 spaces. There is eclipse plugin like AnyEdit for changing tabs into spaces.

For the wrapping of lines, follow the Java code conventions on this part

WhiteSpace Also, the trailing spaces should be removed. AnyEdit plugin do this.

Use whitespaces in for() loop, while(), when concatenating strings.

One before the separator and one after. ie :

for (int i = 0; i < TEST.length; i++) {
    String str = "this is" + " " + "a test with value = " + i;
}
<div class="code"><pre><div class="error">code: </div>
and not :
<div class="code"><pre><div class="error">code: </div>
for (int i= 0; i <TEST.length; i++){
    String str = "this is"+" "+"a test with value = "+i;
}

Line length

There is no explicit limit for the length of a line. Make sure that the flow of the code is clear and that, when printing the file, it is well formed when using a reasonable font. A reasonable length would be around 80 characters.

Wrapping lines

When an expression will not fit on a single line, break it according to these general principles:

  • break after a comma;
  • break before an operator;
  • prefer higher level breaks to lower level breaks;
  • align the new line with the beginning of the expression after the assignment;
  • if the above rules lead to confusing code or to code that's squished up against the right margin, please use common sense.
Some examples breaking an arithmetic expression. The first is preferred, since the break occurs outside the parenthesised expression:
longName1 = longName2 * (longName3 + longName4 - longName5)
    + 4; // preferred
longName1 = longName2 * (longName3 + longName4 
    - longName5) + 4;

Comment styles

The Java language supports three different kinds of comments:

// text
The compiler ignores everything from // to the end of the line. Use this style when adding a description or some kind of explanation at the same line of code.
/* text */
The compiler ignores everything from / to /. The next documentation style is preferred.
/** Documentation. */
This indicates a documentation comment (doc comment, for short). The compiler ignores this kind of comment, just like it ignores comments that use / and /. The JDK JavaDoc tool uses doc comments when preparing automatically generated documentation (See: JavaDoc keywords and HTML tags). But JavaDoc only uses this documentation when it occurs at an expected position in the file like the class definition or a member declaration.

Block comments

Block comments are used to provide English descriptions of the contents of files, the task of methods and the description of data structures and algorithms. Block comments should be used at the beginning of each file and before each method. They can also be used in other places, such as within methods.

For a description of class comment see Class and Interface Declarations. A method block comment looks as follows:

/**
 * Position the splitter location at a specified position.
 * This method can for instance be used when the last position
 * is stored as a preference setting for the user.
 *
 * @param position  New position of divider, defined in pixels
 *     from the left of the containing window
 * @see com.sun.java.swing.JSplitPane
 * @exception org.apache.felix.player.PositionException
 *     Whenever an invalid position is passed.
 */
public void setSplitterLocation(int position) throws PositionException

JavaDoc Comments

It's pretty simple, all attributes and methods need javadoc comment.(Even if they are private/protected).

If a method throw an exception, the javadoc contains the @throws tag for each exception thrown.

All parameters of a method must be documented. If the method override a method from a parent class, the @see tag is required.

If a method return something, the javadoc contains the @return element.

Example :

/**
 * This is a sample attribute used for chameleon code convention wiki
 */
private String simpleExample = null;

/** * This method is a sample example with a parameter and a return value and an exception * @param dummyArg an example of parameter * @return an object * @throws Exception to illustrate the example */ private Object myMethod(String dummyArg) throws Exception { return null; }

For class headers, method headers and member variables JavaDoc is used in order to generate API documentation from the source later on (See: JavaDoc homepage - Sun Microsystems, Inc.). A few specific JavaDoc keywords are:

KeywordShort description
@versionCan be used to label a specific version of a package or application so the documentation shows this version number also.
@authorThe name entered here is shown as the author.
@paramUsed to define one parameter and describe this parameter.
@seeWhen there are similarities with another class this tag is used to offer the reader a hyperlink to the mentioned class.
@exception or @throwsOffered as hyperlink to the exception that can be thrown by a method.
@returnReturn value of a method

Some HTML-tags that can be used in order to make the comment blocks more readable:

TagShort description
<p>New paragraph.
<br>Break, a carriage return. For separation of two paragraphs, usage of <p> is preferred.
<ul><li></li></ul>Unordered list of items; each item should start with a <li> tag. By most browsers, this is formatted as a bulleted list.
<code></code>Code samples; use this when refering to class names, method names, parameter names, etc.
<pre></pre>Preformatted text. Use these tags to protect figures and schemas "drawn" in Ascii, against formatting by the browser (which normally ignores whitespace and line breaks)
<dl><dt></dt><dd></dd></dl>Definition lists; <dt> specifies the term that is defined and
the definition of this term. Not frequently used.
Note: there is no need to embed the parameter name in the @param tag in <code> tags; this is done by javadoc automatically. The same holds for the exception name in the @exception or @throws tag. In the clarifying text however, use the <code> tags when refering to parameter names etc. The example below shows the <code> tag being used for the array parameter in the text, but not in its definition.

Example:

/**
 * Prints a range from an object array. The range
 * is specified by the first element to print, and
 * ranges to the last element of the array.
 *
 * @param array contains the objects to print
 * @param first index of first element in 
 *     the <code>array</code> to print
 */
public void printRange(Object[] array, int first)

Declaration

When declaring a variable or method make the accessibility as restrictive as possible. When using multiple keywords use the following ordering of keywords:

  1. accessibility
Start with the accessibility as it makes clear if the method or variable is reachable at all.
  1. static (if applicable)
  2. final (if applicable)
  3. return type (methods only) or type (for variables)
The type is for readability as close as possible to the name.

This order is also compatible with the order that is used in Java for the main() method. This results in following sequence:

// A familiar one:
public static void main(String[] args) {}
private static String m_lastCreated = null;
private static final int RED = 4711;

Number per line

One declaration per line is recommended since it encourages commenting and it does not lead to confusing code. It also is more clear about the explicit initialization of variables as discussed in Initialization.

Example:

int level = 0;           // level where user enters the system
int horizontalSize = 0;  // horizontal size of current level layer
is preferred over:
int level, horizontalSize; // level and size of current level layer
Placement

In a method, declare local variables just before they are needed. This overcomes the problem of a big list of parameters at the beginning of a method and the use of a variable becomes more clearly in the context of the code, .e.g. its initialization. Initialization

The initialization of class variables is strictly not necessary because of the default initialization that takes place for these kinds of members. For some types, e.g. Booleans, this requires detailed knowledge of all the default values so it is more clear and explicit to initialize each member. Variables that are used and declared within methods must always be initialized explicitly (the compiler will generate an error when you forget this).

Statements

if/else When using if else blocks, even if there is a single statement, the braces have to be used :

if (true) {
    doThis();
}
and not
if (true)
    doThis();

Note that the braces follow the previous example. Don't use:

if (true)
{
  test1();
  test2();
}

try/catch All exceptions required a statement. Silent catching like should be avoided, and if used, a reason has to be given.

try {
   doThis();
} catch (Exception e) {
    // should not occur because, it was already checked…
}

You may use a logger, and avoid System.out as well as System.err :

try {
   doThis();
} catch (Exception e) {
    logger.debug("Exception while doing .....", e);
}

Inline Conditionals Don't use inline conditions.

b = isOk() ? true : false;
but
if (isOk()) {
    b = true;
} else {
    b = false;
}

Naming conventions

  • Static final attributes
Following the JLS suggestions, the declaration is static final and not final static.
  • Constants
Constants should match the pattern '^[A-Z][A-Z0-9](_[A-Z0-9]+)$' Also they need to be declared static and final. No magic number, use constants ie : Don't do :
private int myAttribute = 5;
but :
/**
   * Default value
   */
  private static final int DEFAULT_VALUE = 5;

/** * This attribute is initialized with the default value */ private int myAttribute = DEFAULT_VALUE;

  • Attributes name
no _ (underscore) is authorized in the name of the attributes. _ character is used only in constants (UPPERCASE). so avoid m_value or p_value, use instead mValue or pValue. The regexp is the following :
^[a-z][a-zA-Z0-9]*$.

Tools

By using eclipse IDE, there are other good checks like :
  • unnecessary cast or instance of
  • unused variable
  • methods which should be used in a static way
  • unused methods
  • unnecessary throws
  • etc.

License and Notice

Each project must contains a license file and a notice file, as well as each distributed file (jar, zip ...). The license file contains the Apache License 2.0. The Notice file should follow the format used by Apache Felix, such as:

OW2 Chameleon - Core
Copyright 2009 OW2 Chameleon http://wiki.chameleon.ow2.org

I. Included Software

This product includes software developed at The OW2 Consortium (http://www.ow2.org/). Licensed under the Apache License 2.0.

II. Used Software

This product uses software developed at The Apache Software Foundation (http://www.apache.org/). Licensed under the Apache License 2.0.

This product uses software developed at The OSGi Alliance (http://www.osgi.org/). Copyright (c) OSGi Alliance (2000, 2007). Licensed under the Apache License 2.0.

This product uses software developed at QOS.ch (https://www.qos.ch/). Licensed under the MIT License.

This product uses software developed at QOS.ch (https://www.qos.ch/). Licensed under the Eclipse Public License 1.0.

III. License Summary - Apache License 2.0 - MIT License - Eclipse Public License 1.0

Be care to list ALL your dependencies. For each non ASL dependencies, you must add in your project (as associated artifacts) the license of the dependency. In the previous example, each artifact must contains the LICENSE.s4f4j and LICENSE.logback file containing the MIT and EPL license.

Note: Please use license rather than licence.

Download

Checkstyle formater and Eclipse formater are provided on http://chameleon.ow2.org/conventions/.