This document defines style rules and formatting advises, so the resulting code is easily readable and understandable. As this project will be open sourced at some point, the code should reflect the discipline of the team and its work.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
The indentation style in every applicable source file must use the setting tab-size=8 and indent-size=4. There is however one exception. Imported files such as the eCard XML Schema may be reformatted, but it is not required to do so.
Line endings must be either \r\n for Windows systems and \n for every other system. Git takes care of the proper conversion (see http://stackoverflow.com/questions/3206843/how-line-ending-conversions-work-with-git-core-autocrlf-between-different-operat) only if these characters are used uniformly across a text file. Binary files are not affected by this rule.
One common pitfall is to import XML files containing the wrong or even mixed line endings. Before adding such files to the repository check the line ending and convert it if needed. Sophisticated editors can take care of this task.
Empty lines must only contain the newline character, but no other whitespace characters. Furthermore whitespace between printable characters and the newline character must not be present. Some editors have a feature to indicate these whitespace characters. The formatter should also take care of their removal.
Most newline related rules are explained later in the document.The default file encoding nowadays should be UTF-8. It is often argued that using UTF-16 results in faster text processing. This myth stems from the misconception that UTF-16 is a fixed length encoding, which is not true. In fact only the underlying code table is defined as 2 byte codepage (UCS-2) rather than an 4 byte codepage (UCS-4). Despite its name, UTF-8 is the newer standard.
Besides the UTF file encodings, UNIX systems used to encode in ISO/IEC 8859 or one of its region specific encodings. Windows systems use CP-1252 as default encoding which is an extension to ISO/IEC 8859.
In Java generally everything read with a Reader or written with a Writer is encoded with the default character set defined by the operating system. That also includes XML processors and serializer. It must be made sure that all data is read accordingly by supplying the respective encoding name to the module.
Source as well as resource files, except binary files, must be encoded as UTF-8. When writing a module which processes text, it must be assumed that the input data is UTF-8 if nothing else is specified like a XML Header or a HTTP encoding header.
It is more than good style to name identifiers in code and write documentation, including comments, in English. There is a high possibility that the code will be read and used by foreign language speakers. Furthermore it gives a uniform picture when only a single language is used.
Writing XML documents is pretty straightforward, however a few rules should be followed, so that the files are readable and easily understandable.
<?xml version="1.0" encoding="UTF-8"?>
<parent><child/></parent>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:oec="http://ws.openecard.org"
targetNamespace="http://ws.openecard.org"
name="Combined_eCard">
<ShortHand/>
<ShortHand1/>
<ShortHand2 attr="val" />
<!-- This is the first Group describing XXX -->
<Group1>
<Child/>
</Group1>
<Group1Second/>
<!-- This is the second Group describing YYY -->
<Group2>
<Child/>
</Group2>
<MoreSiblingsOrNot/>
The file structure of any Java file (including enums and interfaces) is as shown below. Some elements are optional.
/*
* Copyright (C) 2011 Free eCard Foundation, Inc.
* eCard Public License version 3
*/
package org.example.com;
import java.io.File;
import java.io.Inputstream;
import static org.junit.Assert.*;
/**
* Description of class Foo.
* @see Bar
* @author Max Mustermann <max.mustermann@example.com>
*/
public class Foo extends Bar {
}
Putting these elements together results in the file below. Pay attention to the number of newlines between the elements.
/*
* Copyright (C) 2011 Free eCard Foundation, Inc.
* eCard Public License version 3
*/
⠀
package org.example.com;
⠀
import java.io.File;
import java.io.Inputstream;
import static org.junit.Assert.*;
⠀
⠀
/**
* Description of class Foo.
* @see Bar
* @author Max Mustermann <max.mustermann@example.com>
*/
public class Foo extends Bar {
⠀
}
This section deals with the rules specific to Java classes. Most rules are also applicable to Enum and Interface types.
public void setFoo(Foo foo) {
this.foo = foo;
}
public Foo getFoo() {
return this.foo;
}
No dependency SHOULD be added to the module POM. The slf4j dependency is already defined in the ecard client root POM.
slf4j needs a backend implementation. For the tests, logback-classic is pulled in by the root POM. For production use, the client artifact must pull in a compile dependency on a backend and configure it appropriately.
import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(MYCLASS.class);
import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(MYCLASS.class); try{ ... } catch (Exception e){ logger.error(ex.getMessage(), ex); }
try{ ... } catch (Exception e){ logger.error("Error while reading value X.", ex); }
Messages including APDUs, eCard-API messages, PAOS messages.
import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(MYCLASS.class); logger.debug("Message received:\n{}", message); logger.debug("Message sent:\n{}", message);
E.g. GUI events.
import org.slf4j.Logger; import org.slf4j.LoggerFactory; private static final Logger logger = LoggerFactory.getLogger(MYCLASS.class); logger.debug("Event: {}", event);
public void foo(Bar b) { logger.trace("Enter function foo: {}", b); ...
The git master repository is available under the following ssh URL:
git@vserver-001.urospace.de:ecard-client
Every user with git development access has his own repository which is accessible under the following URL:
git@vserver-001.urospace.de:ecard-client/firstname_lastname
To get access to your personal repository, you first have to add it to your remotes. This is accomplished by the following command:
git remote add local-name-for-repo git@vserver-001.urospace.de:ecard-client/firstname_lastname
For example, if John Doe wants to add his personal repository to his remotes, he has to execute the following command:
git remote add jd git@vserver-001.urospace.de:ecard-client/john_doe
The same command can be used to add repositories of other developers.
Commit messages and the appropriate level of granularity is the essence of a readable and comprehensible history. Progit sec. 5.2 recommends that commits are revised with git commit -p
or git add -i
, before being committed.
If however it becomes apparent that the structure of the commits, or its log messages are badly done, a rewrite of the history with git rebase -i
can be used. There are other rewrite tools (magit) which help with the task at hand. http://alexvollmer.com/posts/2009/01/31/rewriting-history-with-git/ has a nice write-up how to rewrite history with the bundled git commands.
Concerning the commit message, there are a lot of descriptions on the web. Most of them are quite similar. One of the more comprehensive descriptions can be found in Progit sec. 5.2 in paragraph Commit Guidelines.
A good commit message begins with a header line which is, according to Progit, 50 characters long. I tend to extend this length to ca. 70 characters. We don't live in times where consoles only have 78 character anymore. The header line should contain a brief summary of the changes in the commit. Issue references should go into the body, because nobody knows what is behind them when looking at the log. An exception to this rule is, when the summary is sufficient to describe the change and no body is needed. The summary must use imperative present tense, meaning 'Add X' instead of 'Added X'. The summary ends without a full stop.
If a body is needed, a blank line followed by the body is inserted after the header line. These items are optional, but it is good practise to add them. The line width of the body should be about 100 characters. The body should contain details and perhaps a motivation for the patch. Especially when adding changes in complicated code, think of cryptography for example, the reader may not understand the change without this explanation. The body may consist of several paragraphs which are separated by blank lines.
Enumerations or bullet points can be used inside the body. They should be indented by one space and their text should be aligned by the first character of the items text. Bullet points should be written with -.
Short (up to 70 chars) summary of changes More detailed explanatory text, if necessary. Wrap it to about 100 characters or so. In some contexts, the first line is treated as the subject of an email and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together. Further paragraphs come after blank lines. Enumerations and bullet points look like this: - Bullet points are okay, too - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary here or 1. Point one 2. Another point