MOSIP is developed as an open source framework project. The code developed complied to the Java standards and best practices.
This document gives various Java coding standards which arefollowed during the MOSIP development.
This document covers the coding standards, which are followed by the Java developers.
The number of lines in the Java files is restricted to 2000 lines. Beyond 2000 lines, the java file is refactored into multiple files.
Each java file contains one public class or interface.
When some private classes and interfaces are associated, this can be in the same file.
Declare the public class and interface as the first declaration in the file.
When a java file is written, the following order is maintained,
The beginning comment should be in a C-style comment. Following is the format of the comment.
/*
* Firstname Lastname
*
* Copyright notice
*/
The first non-comment line is the package statement.
-
After a line-break below the package statement, import statements are placed. The import statements are grouped and segregated by a line-break. For example,
import java.util.List; import java.util.Map; import java.time.zone.ZoneRulesException; import org.mosip.kernel.core.authn.LoginInfo; import org.mosip.kernel.core.exception.InvalidInputException; import org.mosip.kernel.core.exception.UnauthenticatedException;
-
Do not use asterisk symbol while importing packages.
-
Class comment goes in the order of class description, version and author. For example,
/* * Class description goes here * * @version 2.4 05 July 2018 * @author Rajkumar Mahanty * */
- Then the public class or interface is defined.
- The other private class or interface are followed.
Please refer the section 10.12
Following is the order of elements inside the class declaration
This comment will be going in to the Javadocs
Class of interface statement
Additional comments to the Class comment
The public class variables are followed by the protected and the private variables.
The constructor declarations ordered by the number of parameters.
The methods are ordered by the functionality. The methods need not to be in the order of scope or accessibility.
The indentation unit it TAB.
The number of characters in a line should not exceed 80 characters
When the number of characters exceed the limit, the line should be broken into multiple lines. The following standard is used during the line breaks,
- Break the line after the comma
- Break before the operator
- From higher-level breaks go to the lower-level breaks.
#5 Comments
There are 2 types of comments in Java.
- Implementation comments
- Documentation comments
Both the comment types are used in the source code of MOSIP.
This is the comment type used for better understanding of the code. Most of the times, the source code will be maintained by different people. The programmer writes these comments so that the other programmers will come to know the functionality of the code in plain English language. Following lines are used.
When the developer needs to explain in detail about some functionality, block comments are used. Block comments are used anywhere in the code. It can be for the class or interface declarations or it can be within the java methods also. Example of block comments,
/*
* This is the block comment. This is the block comment. This is the block
* comment. This is the block comment. This is the block comment. This is
* block comment.
*/
Single line comments are used for short description. For example,
/* This is short description */
if( height > 45) {
...
}
Trailing comments are given in the same line where the source code resides. For example,
if( height > 45) { /* This is the trailing comment */
...
}
The end-of-line comments are also used in the source file. For example,
if(width > 45) {
return false;// some description
}
Documentation comments are used to generate the javadoc files.
One variable is declared per line.
Variables are declared at the beginning of the code block.
- When declaring a method, no space are there before and after "(".
- Open brace "{" is in the same line as the declaration.
- Closing brace "}" is in a new line and should match the open braces in the indentation.
- An empty line is there in between the method declarations.
One statement is there per line.
The return value is obvious. Parenthesis are not used while returning from the method.
Always curly braces are used in the if-else statements. Even though there is a single statement below the if-else statement, curly braces is used. For example,
if(some_condition) {
//some statement
}
Only for the following situations 2 blank lines are used,
- Between 2 different sections of the source file
- If you have more than one class or interface, use 2 blank lines
Only for the following situations, 1 blank line is used,
- Between method declarations.
- Between the variable declarations and the method code.
- Before the block comment or line comment.
- To provide a better readability in between logical blocks, an empty line are used, wherever applicable.
Under the following circumstances, blank space are used,
- When a keyword followed by parenthesis, a blank space should be given after the keyword. For example,
while(age > 60) {
- In the argument list, the parameters are given a space after comma.
All the package name in MOSIP application starts with org.mosip
The names given to classes are always nouns and in camel case.
The names given to interface is always noun and in camel case.
The method names are always verbs and in camel case. For example,
public void deleteFromCache(String cacheName, String key) {
The variable names are short and meaningful. Any new observer can understand the meaning of the variable. No single letter variable names are used. Camel case is used when declaring variables.
The constants are given the name in capital letters. The words in the names are separated by underscore("_").
The instance variables should not be made public unless you have a specific reason.
Always use the class name to call the static method. For example,
LogFactory.getLogger();
Numerical values should not used in the code directly. Declare them and use it in the code. For example,
int MAX_AGE = 60;
while (age > MAX_AGE) {
...
}
Avoid multiple assignments in the same line. For example,
int MAX_AGE = MAX_YEARS = 10; // AVOID
MAX_CALC = (RETIREMENT_AGE = MAX_YEARS + THRESHOLD); // AVOID
Always use parameter type inference. For example,
(employee, requesterEmployee) -> employee.name.compareTo(requesterEmployee.name)// PREFER
(Employee employee, Employee requesterEmployee) -> {employee.name.compareTo(requesterEmployee.name)}// PREFER
Do not use the parenthesis wherever it is optional
Avoid using the block lambdas wherever an expression lambda are used. For example,
// PREFER
someVar -> someVar.toUpperCase(Constants.SOME_CONST);
// AVOID
someVar -> {
**return** someVar.toUpperCase(Constants.SOME_CONST);
}
Whenever calling the functional interface, place them at last in the parameter list. For example,
// PREFER
public Foo parse(Locale locale, **Function<Locale,Foo> fn** );
// AVOID
public Foo parse( **Function<Locale,Foo> fn** , Locale locale);
Throw specific exceptions are caught, rather than generic exceptions. For example,
public void myMethod()throws Exception{ // AVOID
public void myMethod()throws NumberFormatException{ // PREFER
The exceptions are documented clearly. For example,
/**
* The method description goes here ...
*
* @param input
* @throws PacketNotValidException
* if so and so... happens
*/
public void myMethod(String someInput) throws PacketNotValidException {
Error and Throwable are never caught in MOSIP. For example,
try {
// some code
} catch (Error e) {
}
All the exceptions in MOSIP extends from the exception module from the mosip-core
Logs are classified and logged accordingly. Following are the various log levels used in the MOSIP application.
- TRACE
- DEBUG
- INFO
- WARN
- ERROR
The log levels are configured according to the environment such as Development, Testing, UAT or Production. For example, the log levels in production is from WARN. Whereas in Development and Testing environment, it is from TRACE.
MOSIP's log component from the core-kernel is used to log entries.
The log module in the core-kernel is used to log all the log entries.
Every log entry contains the following format,
<date_iso> - <application_id> - <module_id> - <component_id> - <id_type> - -
For example,
2008-09-15T15:53:00+05:00 - ENROLMENT – PACKET_VALIDATOR - VALIDATE – EnrolmentId - 829329 – Packet validator had been called and now we are going to validate the packets.
Care is taken, not to log any sensitive information is logged. Modules leads review the code to ensure that no sensitive information is logged.
Streams are less readable than the "for" loops. Streams are used wherever necessary.
Exception handling in the streams are carefully handled.
Apache Commons is used to handle the common utilities like StringUtil, FileUtil, Hashcode, toString, null check etc., are
In case if Apache Commons doesn't have the necessary utilities, the util project from mosip-core is used.
Following are the miscellaneous practices which are followed in MOSIP.
Parentheses are used in the code liberally to improve the readability and for precedence clarity.
The return values are made sure that it is understandable.
If any binary operator is used before "?" in the ternary operator, then parentheses is used.
(age >= 25) ? true : false ;
Special comments are used to give a hint for further development. Following are the special comments used in MOSIP project,
- NOTE
- OPTIMIZE
- TODO
- FIXME
/*
* Copyright 2002-2018 the original author or authors.
*
* 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.
*/
package org.mosip.orm;
import org.mosip.dao.SomeDAO;
import org.mosip.exception.SMSException;
/**
* This class does the so and so activity. And more description goes here. And
* more description goes here. And more description goes here. And more
* description goes here. And more description goes here.
*
* @author SadanandGowda
* @since v1.0
*/
public class SampleReference extends SomeSuperClass {
/**
* someClass is used for so and so purpose
*/
@Nullable
private final Object someClass;
/**
* someIdentifier is used to identify something
*/
@Nullable
private final Object someidentifier;
/**
* Create some functionality with the with the given message, unless so and so
* functionality.
*
* @param msg
* the display message
* @param cause
* the source exception
*/
public SampleReference(String message, Throwable cause) {
super (message, cause);
this.someClass = null ;
this.someidentifier = null ;
}
/**
* Sends the SMS to the given phone number
*
* @param someClass
* this is for this purpose
* @param mobileNumber
* the mobile number to which the SMS have to be sent
* @param msg
* the message sent to the phone number
* @return
*/
public String sendSMS(Class<?> someClass, int mobileNumber, String msg) {
// the SMS sending code comes here.
}
}