Java

General Style

Order of methods

We aim for best readability - that's the reason why we (from now on) put methods in the specific order:

Imports

Indentation

Naming conventions

Package


Interface and concrete class

Follow the suggestion from Stephen Colebourne's blog:

Enum
Test code

If-statements

Overrides

For optimal refactoring support, we use the @Override  for all methods that override methods declared in superclasses/implemented interfaces

SuppressWarnings

serialVersionUID's

We don't explicitly set serialVersionUID's as we don't want to decide ourselves when these IDs should be updated. We rely on the JVM doing that for us (Be aware that this ID can potentially differ from JVM to JVM). If for any (valid) reason, such an ID would be needed for a given class, the reason needs to be documented in the code. Failing that, there's a good chance that the field will be removed by some zealous fellow developer.

$NON-NLS-1$

If you come across a //$NON-NLS-1$, please just delete it - that's legacy stuff created by Eclipse - we don't want to keep that!

TODOs & FIXMEs

Eclipse setup

Please see  Eclipse setup page and attached formatter settings ( Magnolia.epf ).

Intellij setup

Please see  Intellij IDEA  page and attached formatter settings ( Magnolia-IntelliJ-CodeStyle.xml ).

Lombok

We use Lombok sparingly in our own implementation details; we try to avoid abusing it for publicly visible code (configured classes).

Atomic-refs / concurrency in general

Empty lines

One blank line should be used :

Final variables

Final keyword for variable prevents re-assign, implicitly indicates that the value once assigned can not be changed (only true for primitive type), so developers don't have to track the state/value of the variable, instead, concentrate on other things. It also improves readability.

Example:

	protected Node getOrCreate(String tagName) throws RepositoryException {
 
        tagName = nodeNameHelper.getValidatedName(tagName);
    
        final Session session = getTagsSession();
    
        final Node parentNode = NodeUtil.createPath(session.getRootNode(), getParentPath(tagName), NodeTypes.Folder.NAME, false);
    
        if (parentNode.hasNode(tagName)) {
    
            return parentNode.getNode(tagName);
    
        } else {
    
            final Node node = parentNode.addNode(tagName, TAG_NODE_TYPE);
    
            session.save();
    
            return node;
    
        }
	}

   

Functional-style idioms / Stream formatting

// BAD FORMATTING:
strings.stream().filter(s -> s.length() > 2).sorted()
            .map(s -> s.substring(0, 2)).collect(Collectors.toList());

// GOOD FORMATTING:
strings.stream()
       .filter(s -> s.length() > 2)
       .sorted()
       .map(s -> s.substring(0, 2))
       .collect(Collectors.toList());


Null vs Optional

Prefer Optional to Null, except for the following cases:

Optional  works well with the  Stream  API for chaining action. It leads to more explicit APIs saying that a (return) value may be present or not.

Example:

@Override
public Optional<? extends Form> fetch(Form.Id id) {
    return Optional.ofNullable(formMap.get(id));
}

General QA, what do we look for

In Magnolia development process, we have (not only) at least the following steps/process to ensure code quality:

These tests are automatically checked on our Jenkins server. When code review and automated tests passed, manual tests must be executed before integration (pre-integration test aka piQA). After piQA is successfully completed and code is merged, integration tests must be executed manually once again to ensure quality.

In all those automated and manual tests : all edge cases, error cases, happy cases... must be covered.

Log statements, arguments, messaging

CSS style

Apply BEM methodology

Syntax:

.block__element--modifier {}


Example:

.form {
  position: relative;
  .form__button {
     height: 20px;
     width: 80px;
     .form__button--red {
       color: red;
     } 
     .form__button--green {
       color: green;
     }
   }
}


Deprecation

Javadocs

Miscellaneous

Arrays#asList vs. Collections#singletonList

Magnolia specific 

General UI development guidelines

ModuleVersionHandler test

Writing or doing tests for MVH (Module Version Handler) must ensure all version upgrading tasks and fresh install state relevant tasks are triggered.

YAML & Magnolia definitions

YAML is a highly-prominent part of Magnolia configuration; we recommend the following rules throughout YAML definition:

class: info.magnolia.foo.MySmartDefinition
components:
  - name: First component
    class: info.magnolia.foo.MySmartComponent
    description: Some short description of the first component
  - name: Second ...