Foreword

This document describes a list of coding conventions that are required for code submissions to AndroMDA. By default, coding conventions for most Open Source Projects should follow the existing coding conventions in the file that you are working on. For example, if the bracket is on the line after the if statement, then you should write all your code to have that convention.

AndroMDA Developer Coding Conventions

Below is a list of coding conventions that are specific to AndroMDA. Anything else not specifically mentioned here should follow the official Sun Java Coding Conventions .

General Coding Conventions

The following applies to any code, whether it be templates, java files, XML files, etc.

  • Indentations: 4 spaces. NO tabs. Period. We understand that a lot of you like to use tabs, but the fact of the matter is that in a distributed development environment, when the cvs commit messages get sent to a mailing list, they are almost impossible to read if you use tabs.

    Another requirement is to set the right margin to 120 characters, so lines break if they exceed this limit. A shorter limit is not acceptable since it will break lines sooner and will disrupt the look and feel of the code.

Java Coding Conventions

  • Brackets: All brackets (class, method, if, try, etc) must begin and end on a new line. Example :

    public
    class
    SomeClass {
    public
    void
    someMethod() {
    if
    (xxx) { } } }
  • Whitespace: Do not add extra whitespace around parenthesis (i.e. "if ( this.isComposition() )") or casts ("(ClassifierFacade) element"), instead they should be written written like the following:

    if
    (
    this
    .isComposition()) { }
    ClassifierFacade classifier = (ClassifierFacade)element;
                            
  • Iterators: Looping using an iterator, do these in for-loops instead of while loops (because this allows the iterator itself to be scoped into that block). Example:

    for
    (
    final
    Iterator stereotypeIterator = stereotypes.iterator(); stereotypeIterator.hasNext();) {
    final
    ModelElement stereotype = (ModelElement)stereotypeIterator.next(); stereoTypeNames.add(stereotype.getName()); }
  • Comments: Javadoc SHOULD exist on all your class members (methods + class variables), including the private ones. Also, if you are working on existing code and there currently isn't a javadoc for that method/class/variable or whatever, then you should contribute and add it. This will improve the project as a whole. Also add code comments when you think it's necessary (like assumptions), especially when the code is not obvious.

  • Author References: If you contribute to a file (code or documentation), add yourself to the top of the file (below the existing authors). For java files the preferred Javadoc format is:

    @author FirstName LastName
                            
  • Exiting Methods: There should be only a single point of exit out of a method (i.e. a single return statement).

    public
    int
    getEntityCount() {
    // don't do this:
    /* if (condition) { return 6; } return 0; */
    // but do this:
    int
    entityCount =
    0
    ;
    if
    (condition) { entityCount =
    6
    ; }
    return
    entityCount; }
  • Variable Names: attr should be written as attribute, collIdents should be identifiers (the type is Collection, don't specify that in the name), the code should read as plain English.

  • Instance Variables: Instance variables should not have any prefix and must be referenced using the this object. Example :
    public
    class
    SomeClass {
    private
    String someString; ...
    public
    void
    someMethod() { logger.debug(
    "Value = "
    +
    this
    .someString); } }
  • Parameter: Method parameter names should not have any prefix indicating the type (strClassName for a String). When more than one parameter is present in the list we write each one of them on a new line and indent. Where possible we make the parameter final. For example :
    public
    void
    someMethod(
    final
    String className,
    final
    int
    count) { }
  • Strings: Avoid hardcoding values, Strings as well as numbers, etc should go into a properties file or a class holding constants.

  • Imports: Use fully qualified import names when importing classes, this makes it easier for users not familiar with the code base to see where classes are coming from.

  • Switch/case: Switch/case constructs look like this (please respect the indentation). When ever a break keyword would be missing it should be replaced by a comment indicating the fall-through. If the default action is to not perform anything then please put this in a comment so people know it's on purpose.

    switch
    (myValue) {
    case
    1
    : doSomething();
    break
    ;
    case
    2
    : doSomething2();
    break
    ;
    case
    3
    :
    // fall-through
    case
    4
    : doSomethingElse();
    break
    ;
    default
    :
    // do nothing
    }

  • Logging: Do NOT use System.out.println() for debugging purposes in your code, instead use a log4j logger.

    try
    { ... }
    catch
    (Exception ex) { logger.error(
    "Some error has occurred"
    + ex); }
  • Exception Recording: Do NOT use ex.printStackTrace() for debugging purposes in your code, instead use the provided ExceptionRecorder class.

    try
    { ... }
    catch
    (Exception ex) { logger.error(
    "Some error has occurred"
    + ex); ExceptionRecorder.instance().record( ex ); }

    This will create a .exc file with the stacktrace and additional debugging and environment information:

    ------- AndroMDA Exception Recording -------
    Version ........: 3.0-RC2-20050420181638
    Error ..........: Error performing ModelProcessor.process with model(s) --> 'jar:file:/home/martin/ews30andromda/workspace/andromda-all/cartridges/andromda-webservice/src/test/uml/WebServiceCartridgeTestModel.xml.zip!/WebServiceCartridgeTestModel.xml'
    Build ..........: 2005-04-20 18:16:38
    Build System ...: Linux-2.6.11-suspend2
    Build JDK ......: Sun Microsystems Inc.-1.4.2_07-b05
    Build Builder ..: martin
    Run System .....: Linux2.6.11-suspend2
    Run JDK ........: Sun Microsystems Inc.1.4.2_07-b05
    Main Exception .: Error performing MDRepositoryFacade.readModel
    Root Exception .: java.lang.OutOfMemoryError
    java.lang.OutOfMemoryError
    	
    

Template Coding Conventions

  • Referencing properties: In Velocity (etc) try to do $variable.property instead of $variable.getProperty(), the two calls are equivalent but the former better matches our metamodels (and is less code to write).

Committing Code into CVS

  • As always, make sure to have a clear comment supporting your change in CVS, if something goes wrong others might help to track down the problem by reading the history.

  • If you fixed, added, updated or removed a feature then update /documentation/changes.xml. Take a look at previous changes for examples.

Submitting Patches

As always, use JIRA to submit feature requests and patches.

If you have modified your local version by adding a new feature and would like to see in the main distribution, then file a new issue in JIRA and attach the patch to it (please do not send it to the mailing list).

If you want to see your patch quickly applied by committers, you should be able to provide the following items:

  1. A patch file (this can be very easily created if you're using eclipse) against the latest CVS version. No, a zip file with all modified sources is *not* okay.
  2. If appropriate, include one or more JUnit tests related to the new feature. Also, be sure to run all of the existing testcases to verify that you are not breaking existing code.
  3. Where applicable, update the documentation (namespace/modeling docs, samples, ...).

If all of these requirements are met and you are respecting the coding conventions, then it is very likely your patch will be accepted soon.