Guía para desarrolladores de gvSIG 1.11.0
Forewords
This document describes a list of coding conventions that are required for code submissions to the project. By default, the coding conventions for most Open Source Projects should follow the existing coding conventions in the code that you are working on. For example, if the bracket is on the same line as the if statement, then you should write all your code to have that convention.
If you commit code that does not follow these conventions and you are caught, you are responsible for also fixing your own code.
Below is a list of coding conventions that are specific to gvSIG, everything else not specificially mentioned here should follow the official Sun Java Coding Conventions
Why code conventions
As explained in the Sun Java Coding Conventions:
Code conventions are important to programmers for a number of reasons:
- 80% of the lifetime cost of a piece of software goes to maintenance.
- Hardly any software is maintained for its whole life by the original author.
- Code conventions improve the readability of the software, allowing engineers to understand new code more quickly and thoroughly.
- If you ship your source code as a product, you need to make sure it is as well packaged and clean as any other product you create.
How to apply?
Having coding conventions is nice but having a way to ensure they are applied is even better ... :-)
The gvSIG maven configuration has a checkstyle target which performs coding conventions using the Checkstyle tool.
Please run this target before committing any code.
Also the eclipse configuration needed to format the source code taking into account the code conventions defined in the current document will be available in the org.gvsig.maven.base.build project, from the gvsig-tools OSOR project.
If the project you are working with has a prepare-workspace.xml file which you have used to configure your workspace, you will have those files already downloaded and available into the folder:
WORKSPACE/org.gvsig.maven.base.build/eclipse-configs
Otherwise, you may download all the files through the repository URL:
To import those configurations perform the following:
- Clean up:
- Go to Window > Preferences > Java > Code Style > Clean Up and click the button Import.
- In the file system explorer, select the clean_up.xml file.
![images/clean_up_optim.png](../../2.0.0/coding-development-guidelines/images/clean_up_optim.png)
- Code templates:
- Go to Window > Preferences > Java > Code Style > Code Templates and click the button Import.
- In the file system explorer, select the code_templates.xml file.
- Activate the option Automatically add comments for new methods and types.
![images/code_templates_optim.png](../../2.0.0/coding-development-guidelines/images/code_templates_optim.png)
- Formatter:
- Go to Window > Preferences > Java > Code Style > Formatter and click the button Import.
- In the file system explorer, select the formatter.xml file.
![images/formatter_optim.png](../../2.0.0/coding-development-guidelines/images/formatter_optim.png)
- Organize imports:
- Go to Window > Preferences > Java > Code Style > Organize Imports and click the button Import.
- In the file system explorer, select the organize_imports.importorder file.
![images/organize_imports_optim.png](../../2.0.0/coding-development-guidelines/images/organize_imports_optim.png)
gvSIG specific coding conventions
Mandatory conventions
Headers
Look at the Headers document for more information.
Indentations
4 spaces. NO tabs.
Javadoc
All API interfaces and classes must be fully documented through javadocs comments at interface/class, method and package level.
When you inherit or extend from another interface or class which is already documented, and implement or rewrite one of the parent methods, don't write any javadoc comments, as they are also inherited since java 1.4.
Brackets
All brackets should begin at the end of the line that begins the statement, and end on a new line indented to the beginning of the statement. Example:
AVOID:
public class MyClass { public void someMethod() { if (...) { // Do something } } }
RIGHT:
public class MyClass { public void someMethod() { if (...) { // Do something } } }
Brackets are mandatory even for single line statements:
if (expression) // AVOID! // some code if (expression) { // RIGHT // some code }
Blank Spaces
Keywords followed by a parenthesis should be separated by a space. Example:
while (true) { // some code }
Blank space should appear after commas in argument lists. Binary operators should be separated from their operands by spaces:
a += c + d; a = (a + b) / (c * d); while (d++ = s++) { n++; } printSize("size is " + foo + "\n");
Class variables
Class variables should not have any prefix or suffix related to its data type or scope. Example:
String nameString; // AVOID! String name; // RIGHT
Parameter names
Method parameters should be prefixed by "the" for differentiating them from inner variables, when there is an inner variable with the same name or use. For example:
public void someMethod(String theClassName) { String className; // inner variable }
Line length
Avoid lines longer than 80 characters for Code, comments, ...
Versioning
All .java files should have a @version tag like the one below into the class javadoc comment:
@version $Id$
Logging
Do not use System.out to log. Instead, use the SLF4J logging API. For example:
private static final Logger LOG = LoggerFactory.getLogger(MyClass.class); public void someMethod() { LOG.debug("some debug text"); }
For more information on SLF4J usage, you can read the Logging document.
Exception handling
Managing exceptions correctly requires experience. This is not supposed to be a guide on managing exceptions, simply a few best practices.
- Rule 1: Try to catch exceptions as much as possible and rethrow higher level exceptions (meaning hiding the low level detailed and putting a message that is more related to the function of your code).
- Rule 2: It is important not to loose the stack trace which contains important information. Use chained exceptions for that.
- Rule 3: Always log the exception at the higher level (ie. where it is handled and not rethrown).
- Rule 4: Try to avoid catching Throwable or Exception and catch specific exceptions instead.
- Rule 5: Create one parent Exception for each API library, so methods of the API that throw any exception use that parent exception or one of the child ones.
- Rule 6: If you have an exception or an error which can't be handled or resolved by code, throw or rethrow a BaseRuntimeException subclass.
An example:
public void getTestClass() { try { Class responseClass = Class.forName("some.package.MyClass"); } catch (ClassNotFoundException cnfe) { String message = "Cannot instantiate test class"; LOG.error(message, ex); throw new ChainedRuntimeException(message, e); } }
Qualified imports
All import statements should containing the full class name of classes to import and should not use the "*" notation: An example:
// AVOID! import java.util.*; import java.net.*; // RIGHT import java.util.Date; import java.net.HttpURLConnection;
Use interfaces in the declaration of methods and variables.
By example, if you need a variable x that is a list, declare it as List instead an ArrayList:
// AVOID! ArrayList x = new ArrayList(); HashMap y = new HashMap(); public HashMap create(ArrayList keys, ArrarList values) { ... } // RIGHT List x = new ArrayList(); Map y = new HashMap(); public Map create(List keys, List values) { ... }
API packages
Usually, API interfaces and classes will belong to the library's main root package. If you create subpackages, use them to group by functionality, not by type.
How to name packages
All packages must begin with org.gvsig.
For more information on this convention, you can read the How to name packages document.
Advised conventions
- How to name interfaces and classes
Attention!
TODO
For more information on this convention, you can read the How to name interfaces and classes document.