Add checkstyle plugin (#67)

diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..9373a70
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module PUBLIC
+        "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
+        "https://checkstyle.org/dtds/configuration_1_3.dtd">
+<!-- 参考:https://checkstyle.sourceforge.io/checks.html -->
+<module name="Checker">
+    <!--检查不通过时被判定的违规级别,必须修复后才能使build通过-->
+    <property name="severity" value="error"/>
+    <!--对java文件做检查-->
+    <property name="fileExtensions" value="java"/>
+    <!--对UTF-8编码的文件做检查-->
+    <property name="charset" value="UTF-8"/>
+    <!--文件中不允许包含制表符-->
+    <module name="FileTabCharacter">
+        <property name="eachLine" value="true"/>
+    </module>
+
+    <!--检查java源文件并定义一些适用于检查此类文件的一些属性-->
+    <module name="TreeWalker">
+        <!--检查行长度-->
+        <module name="LineLength">
+            <property name="max" value="80"/>
+            <!--可以忽略的行-->
+            <property name="ignorePattern"
+                      value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
+        </module>
+        <!--检查没有import语句使用*号-->
+        <module name="AvoidStarImport"/>
+        <!--检查是否存在多余的import语句,比如重复的,java自带的包,相同包下的其他类-->
+        <module name="RedundantImport"/>
+        <!--检查是否存在没有使用的import语句-->
+        <module name="UnusedImports"/>
+        <!--检查包名称是否遵守命名规约-->
+        <module name="PackageName">
+            <property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
+        </module>
+        <!--检查局部变量的名称是否遵守命名规约-->
+        <module name="LocalVariableName">
+            <property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
+        </module>
+        <!--检查成员变量(非静态字段)的名称是否遵守命名规约-->
+        <module name="MemberName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查方法名称是否遵守命名规约-->
+        <module name="MethodName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查参数名称是否遵守命名规约-->
+        <module name="ParameterName">
+            <property name="format" value="^[a-z][a-zA-Z0-9]*$"/>
+        </module>
+        <!--检查常量(用static final修饰的字段)的名称是否遵守命名规约-->
+        <module name="ConstantName">
+            <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/>
+        </module>
+        <!--检查数组是否属于java风格,方括号放在类型后面,而不是变量后面,比如:int[] nums(合法),int nums[](不合法)-->
+        <module name="ArrayTypeStyle">
+            <property name="javaStyle" value="true"/>
+        </module>
+        <!--long类型的字面量如果要以"L"结尾,必须是大写的"L",而非小写的"l"-->
+        <module name="UpperEll"/>
+        <!--代码换行时,运算符必须在当前行的末尾,比如:+、&&、?、: 等-->
+        <module name="OperatorWrap">
+            <property name="option" value="eol"/>
+        </module>
+        <!--检查指定标记的周围是否有空格,比如:if、for、while、synchoronized 等-->
+        <module name="WhitespaceAround"/>
+        <!--左圆括号之后和右圆括号之前是否需要有一个空格,不需要-->
+        <module name="ParenPad"/>
+        <!--检查修饰符是否符合Java建议,顺序是:public、protected、private、abstract、default、static、final、transient、volatile、synchronized、native、strictfp-->
+        <module name="ModifierOrder"/>
+        <!--检查代码块的左花括号的放置位置,必须在当前行的末尾-->
+        <module name="LeftCurly">
+            <property name="option" value="eol"/>
+            <property name="ignoreEnums" value="false"/>
+        </module>
+        <!--代码中不允许有空语句,也就是单独的;符号-->
+        <module name="EmptyStatement"/>
+        <!--覆盖equals()方法的类必须也覆盖了hashCode()方法-->
+        <module name="EqualsHashCode"/>
+        <!--switch语句必须含有default子句-->
+        <module name="MissingSwitchDefault"/>
+        <!--switch语句的default必须放在所有的case分支之后-->
+        <module name="DefaultComesLast"/>
+        <!--覆盖clone()方法时调用了super.clone()方法-->
+        <module name="SuperClone"/>
+    </module>
+</module>
diff --git a/pom.xml b/pom.xml
index fb28181..10a7e88 100644
--- a/pom.xml
+++ b/pom.xml
@@ -247,7 +247,28 @@
                     </compilerArgs>
                 </configuration>
             </plugin>
-
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>3.1.0</version>
+                <configuration>
+                    <configLocation>checkstyle.xml</configLocation>
+                    <encoding>UTF-8</encoding>
+                    <consoleOutput>true</consoleOutput>
+                    <failsOnError>true</failsOnError>
+                    <linkXRef>false</linkXRef>
+                    <includeTestSourceDirectory>false</includeTestSourceDirectory>
+                </configuration>
+                <executions>
+                    <execution>
+                        <id>validate</id>
+                        <phase>validate</phase>
+                        <goals>
+                            <goal>check</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-jar-plugin</artifactId>
diff --git a/src/main/java/com/baidu/hugegraph/config/OptionSpace.java b/src/main/java/com/baidu/hugegraph/config/OptionSpace.java
index 8e633fa..8c1128c 100644
--- a/src/main/java/com/baidu/hugegraph/config/OptionSpace.java
+++ b/src/main/java/com/baidu/hugegraph/config/OptionSpace.java
@@ -36,13 +36,13 @@
 
     private static final Logger LOG = Log.logger(OptionSpace.class);
 
-    private static final Map<String, Class<? extends OptionHolder>> holders;
-    private static final Map<String, TypedOption<?, ?>> options;
+    private static final Map<String, Class<? extends OptionHolder>> HOLDERS;
+    private static final Map<String, TypedOption<?, ?>> OPTIONS;
     private static final String INSTANCE_METHOD = "instance";
 
     static {
-        holders = new ConcurrentHashMap<>();
-        options = new ConcurrentHashMap<>();
+        HOLDERS = new ConcurrentHashMap<>();
+        OPTIONS = new ConcurrentHashMap<>();
     }
 
     public static void register(String module, String holder) {
@@ -98,26 +98,26 @@
 
     public static void register(String module, OptionHolder holder) {
         // Check exists
-        if (holders.containsKey(module)) {
+        if (HOLDERS.containsKey(module)) {
             LOG.warn("Already registered option holder: {} ({})",
-                     module, holders.get(module));
+                     module, HOLDERS.get(module));
         }
         E.checkArgumentNotNull(holder, "OptionHolder can't be null");
-        holders.put(module, holder.getClass());
-        options.putAll(holder.options());
+        HOLDERS.put(module, holder.getClass());
+        OPTIONS.putAll(holder.options());
         LOG.debug("Registered options for OptionHolder: {}",
                   holder.getClass().getSimpleName());
     }
 
     public static Set<String> keys() {
-        return Collections.unmodifiableSet(options.keySet());
+        return Collections.unmodifiableSet(OPTIONS.keySet());
     }
 
     public static boolean containKey(String key) {
-        return options.containsKey(key);
+        return OPTIONS.containsKey(key);
     }
 
     public static TypedOption<?, ?> get(String key) {
-        return options.get(key);
+        return OPTIONS.get(key);
     }
 }
diff --git a/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java b/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java
index c8fa31d..68cd008 100644
--- a/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java
+++ b/src/main/java/com/baidu/hugegraph/date/SafeDateFormat.java
@@ -63,10 +63,4 @@
     public Object toPattern() {
         return this.pattern;
     }
-
-    @Override
-    public Object clone() {
-        // No need to clone due to itself is thread safe
-        return this;
-    }
 }
diff --git a/src/main/java/com/baidu/hugegraph/rest/RestResult.java b/src/main/java/com/baidu/hugegraph/rest/RestResult.java
index b633591..dc78f18 100644
--- a/src/main/java/com/baidu/hugegraph/rest/RestResult.java
+++ b/src/main/java/com/baidu/hugegraph/rest/RestResult.java
@@ -33,7 +33,7 @@
 
 public class RestResult {
 
-    private static final ObjectMapper mapper = new ObjectMapper();
+    private static final ObjectMapper MAPPER = new ObjectMapper();
 
     private final int status;
     private final MultivaluedMap<String, Object> headers;
@@ -59,7 +59,7 @@
 
     public <T> T readObject(Class<T> clazz) {
         try {
-            return mapper.readValue(this.content, clazz);
+            return MAPPER.readValue(this.content, clazz);
         } catch (Exception e) {
             throw new SerializeException(
                       "Failed to deserialize: %s", e, this.content);
@@ -69,16 +69,16 @@
     @SuppressWarnings("deprecation")
     public <T> List<T> readList(String key, Class<T> clazz) {
         try {
-            JsonNode root = mapper.readTree(this.content);
+            JsonNode root = MAPPER.readTree(this.content);
             JsonNode element = root.get(key);
             if (element == null) {
                 throw new SerializeException(
                           "Can't find value of the key: %s in json.", key);
             }
-            JavaType type = mapper.getTypeFactory()
+            JavaType type = MAPPER.getTypeFactory()
                                   .constructParametrizedType(ArrayList.class,
                                                              List.class, clazz);
-            return mapper.convertValue(element, type);
+            return MAPPER.convertValue(element, type);
         } catch (IOException e) {
             throw new SerializeException(
                       "Failed to deserialize %s", e, this.content);
@@ -87,11 +87,11 @@
 
     @SuppressWarnings("deprecation")
     public <T> List<T> readList(Class<T> clazz) {
-        JavaType type = mapper.getTypeFactory()
+        JavaType type = MAPPER.getTypeFactory()
                               .constructParametrizedType(ArrayList.class,
                                                          List.class, clazz);
         try {
-            return mapper.readValue(this.content, type);
+            return MAPPER.readValue(this.content, type);
         } catch (IOException e) {
             throw new SerializeException(
                       "Failed to deserialize %s", e, this.content);
@@ -105,6 +105,6 @@
     }
 
     public static void registerModule(Module module) {
-        mapper.registerModule(module);
+        MAPPER.registerModule(module);
     }
 }
diff --git a/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java b/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
index 60938b3..0d7c7c4 100644
--- a/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
+++ b/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
@@ -169,7 +169,9 @@
             if (superclass != null) {
                 try {
                     return method(superclass, methodName, argsClasses);
-                } catch (Exception ignored){}
+                } catch (Exception ignored) {
+                    // pass
+                }
             }
             throw new RuntimeException(String.format(
                       "Can't find method '%s' with args %s of class '%s'",
diff --git a/src/main/java/com/baidu/hugegraph/util/CheckSocket.java b/src/main/java/com/baidu/hugegraph/util/CheckSocket.java
index 9a60665..c0dfc89 100644
--- a/src/main/java/com/baidu/hugegraph/util/CheckSocket.java
+++ b/src/main/java/com/baidu/hugegraph/util/CheckSocket.java
@@ -37,7 +37,7 @@
     private static final String MSG_USAGE =
             "Usage: " + CheckSocket.class.getSimpleName() + " hostname port";
 
-    public static void main(String args[]) {
+    public static void main(String[] args) {
         if (args.length != 2) {
             System.err.println(MSG_USAGE);
             System.exit(E_USAGE);
diff --git a/src/main/java/com/baidu/hugegraph/util/NumericUtil.java b/src/main/java/com/baidu/hugegraph/util/NumericUtil.java
index 1dafa8b..f1b4f88 100644
--- a/src/main/java/com/baidu/hugegraph/util/NumericUtil.java
+++ b/src/main/java/com/baidu/hugegraph/util/NumericUtil.java
@@ -216,7 +216,7 @@
         E.checkArgumentNotNull(clazz, "The clazz can't be null");
 
         if (Long.class.isAssignableFrom(clazz) ||
-            Double.class.isAssignableFrom(clazz) ) {
+            Double.class.isAssignableFrom(clazz)) {
             return Long.MAX_VALUE;
         }
         if (Integer.class.isAssignableFrom(clazz) ||
diff --git a/src/main/java/com/baidu/hugegraph/util/VersionUtil.java b/src/main/java/com/baidu/hugegraph/util/VersionUtil.java
index 92bef3d..891cab0 100644
--- a/src/main/java/com/baidu/hugegraph/util/VersionUtil.java
+++ b/src/main/java/com/baidu/hugegraph/util/VersionUtil.java
@@ -23,6 +23,7 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.net.URL;
+import java.util.Objects;
 import java.util.jar.Attributes;
 import java.util.jar.Manifest;
 
@@ -121,7 +122,9 @@
             if (isr != null) {
                 try {
                     isr.close();
-                } catch (Exception ignored) {}
+                } catch (Exception ignored) {
+                    // pass
+                }
             }
 
             // Destroy child process
@@ -206,6 +209,11 @@
         }
 
         @Override
+        public int hashCode() {
+            return Objects.hash(this.version);
+        }
+
+        @Override
         public String toString() {
             return this.version;
         }