├── .gitignore ├── README.md ├── build.sh ├── pom.xml └── src ├── main ├── java │ └── org │ │ └── sonar │ │ └── java │ │ └── rule │ │ ├── MyJavaFileCheckRegistrar.java │ │ ├── MyJavaRulesDefinition.java │ │ ├── MyJavaRulesPlugin.java │ │ ├── RulesList.java │ │ └── checks │ │ ├── MyFirstCustomCheck.java │ │ └── namerules │ │ ├── AbstractClassNameCheck.java │ │ ├── ArrayNameCheck.java │ │ ├── ConstantNameCheck.java │ │ ├── ExceptionClassNameCheck.java │ │ ├── LowerCameCaseCheck.java │ │ ├── UnderlineDollarNameCheck.java │ │ └── UpperCameCaseCheck.java └── resources │ └── org │ └── sonar │ └── l10n │ └── java │ └── rules │ └── squid │ ├── AbstractClassNameCheck.html │ ├── AbstractClassNameCheck.json │ ├── AbstractClassNameCheck_java.json │ ├── ArrayNameCheck.html │ ├── ArrayNameCheck.json │ ├── ArrayNameCheck_java.json │ ├── ConstantNameCheck.html │ ├── ConstantNameCheck.json │ ├── ConstantNameCheck_java.json │ ├── ExceptionClassNameCheck.html │ ├── ExceptionClassNameCheck.json │ ├── ExceptionClassNameCheck_java.json │ ├── LowerCameCaseCheck.html │ ├── LowerCameCaseCheck.json │ ├── LowerCameCaseCheck_java.json │ ├── UnderlineDollarNameCheck.html │ ├── UnderlineDollarNameCheck.json │ ├── UnderlineDollarNameCheck_java.json │ ├── UpperCameCaseCheck.html │ ├── UpperCameCaseCheck.json │ └── UpperCameCaseCheck_java.json └── test ├── files ├── AbstractMysql.java ├── ActionTestCase.java ├── ActionTestCaseImpl.java ├── AgeOutOfBound.java ├── AgeOutOfException.java ├── AgeOutOfExceptionBound.java ├── ArrayNameCheckMapper.java ├── BaseMysql.java ├── ConstantNameMapper.java ├── HiClass.java ├── LowerCameCaseMapper.java ├── MyFirstCustomCheck.java ├── MyNameIsAbstract.java ├── TestKeyWordContainsRule.java ├── UnderlineDollarRuleMapper.java ├── UserDo.java ├── XMLService.java └── macroPolo.java └── java └── org └── sonar └── java └── rule ├── MyJavaRulesDefinitionTest.java └── checks ├── MyFirstCustomCheckTest.java └── namerules ├── AbstractClassNameCheckTest.java ├── ArrayNameCheckTest.java ├── ConstantNameCheckTest.java ├── ExceptionClassNameCheckTest.java ├── LowerCameCaseChecTest.java ├── UnderlineDollarNameCheckTest.java └── UpperCameCaseCheckTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | # ---- Maven 2 | target/ 3 | dependency-reduced-pom.xml 4 | 5 | # ---- IntelliJ IDEA 6 | *.iws 7 | *.iml 8 | *.ipr 9 | *.jar 10 | .idea/ 11 | 12 | # ---- Eclipse 13 | .classpath 14 | .project 15 | .settings 16 | 17 | # ---- Mac OS X 18 | .DS_Store? 19 | Icon? 20 | # Thumbnails 21 | ._* 22 | # Files that might appear on external disk 23 | .Spotlight-V100 24 | .Trashes 25 | 26 | # ---- Windows 27 | # Windows image file caches 28 | Thumbs.db 29 | # Folder config file 30 | Desktop.ini 31 | 32 | .java-version 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 基于阿里JAVA开发手册,编写sonar JAVA规则插件 2 | 3 | 已完成: 4 | 5 | (一)命名规约 6 | 7 | (1)下划线和美元符号命名检查 8 | 9 | (2)类命名驼峰检查 10 | 11 | (3)方法名、参数名、成员变量、局部变量 驼峰检查 12 | 13 | (4)常量名称检查 14 | 15 | (5)抽象类命名检查 16 | 17 | (6)异常类命名检查 18 | 19 | (7)中括号数组检查 20 | 21 | 编写规范参考:https://www.cnblogs.com/feihufeihu/p/10676304.html 22 | 整个sonar插件部署参考:https://www.cnblogs.com/feihufeihu/p/10676314.html 23 | -------------------------------------------------------------------------------- /build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mvn clean && mvn package -Dmaven.test.skip=true -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.sonar.java.rule 7 | sonar-java-custom-rules 8 | 1.0-SNAPSHOT 9 | sonar-plugin 10 | 11 | 12 | 6.2.1 13 | 4.6.0.8784 14 | 1.21 15 | 16 | 17 | Sonar Java Custom Rules 18 | As Ali JAVA Rule 19 | 2017 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | com.google.code.gson 37 | gson 38 | 2.6.2 39 | 40 | 41 | 42 | org.sonarsource.sonarqube 43 | sonar-plugin-api 44 | ${sonar.version} 45 | provided 46 | 47 | 48 | 49 | org.sonarsource.java 50 | sonar-java-plugin 51 | ${java.plugin.version} 52 | 53 | 54 | 55 | org.sonarsource.java 56 | java-frontend 57 | ${java.plugin.version} 58 | 59 | 60 | 61 | org.sonarsource.sslr-squid-bridge 62 | sslr-squid-bridge 63 | 2.6.1 64 | 65 | 66 | org.codehaus.sonar.sslr 67 | sslr-core 68 | 69 | 70 | org.codehaus.sonar 71 | sonar-plugin-api 72 | 73 | 74 | org.codehaus.sonar.sslr 75 | sslr-xpath 76 | 77 | 78 | org.slf4j 79 | jcl-over-slf4j 80 | 81 | 82 | org.slf4j 83 | slf4j-api 84 | 85 | 86 | 87 | 88 | 89 | org.sonarsource.java 90 | java-checks-testkit 91 | ${java.plugin.version} 92 | test 93 | 94 | 95 | 96 | org.sonarsource.sslr 97 | sslr-testing-harness 98 | ${sslr.version} 99 | test 100 | 101 | 102 | 103 | org.slf4j 104 | slf4j-api 105 | 1.6.2 106 | 107 | 108 | 109 | junit 110 | junit 111 | 4.11 112 | test 113 | 114 | 115 | org.easytesting 116 | fest-assert 117 | 1.4 118 | test 119 | 120 | 121 | org.assertj 122 | assertj-core 123 | 3.6.1 124 | test 125 | 126 | 127 | ch.qos.logback 128 | logback-classic 129 | 0.9.30 130 | test 131 | 132 | 133 | 134 | 135 | 136 | 137 | org.sonarsource.sonar-packaging-maven-plugin 138 | sonar-packaging-maven-plugin 139 | 1.17 140 | true 141 | 142 | sonar-java-custom-rules 143 | Sonar Java Custom Rules 144 | org.sonar.java.rule.MyJavaRulesPlugin 145 | true 146 | 5.6 147 | 148 | 149 | 150 | 151 | org.apache.maven.plugins 152 | maven-compiler-plugin 153 | 3.6.0 154 | 155 | 1.8 156 | 1.8 157 | 158 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/MyJavaFileCheckRegistrar.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Java Custom Rules Example 3 | * Copyright (C) 2016-2016 SonarSource SA 4 | * mailto:contact AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.java.rule; 21 | 22 | import org.sonar.java.rule.checks.namerules.*; 23 | import org.sonar.plugins.java.api.CheckRegistrar; 24 | import org.sonar.plugins.java.api.JavaCheck; 25 | import org.sonarsource.api.sonarlint.SonarLintSide; 26 | 27 | import java.util.Arrays; 28 | 29 | /** 30 | * Provide the "checks" (implementations of rules) classes that are gonna be executed during 31 | * source code analysis. 32 | * 33 | * This class is a batch extension by implementing the {@link CheckRegistrar} interface. 34 | */ 35 | @SonarLintSide 36 | public class MyJavaFileCheckRegistrar implements CheckRegistrar { 37 | 38 | /** 39 | * Register the classes that will be used to instantiate checks during analysis. 40 | */ 41 | @Override 42 | public void register(RegistrarContext registrarContext) { 43 | // Call to registerClassesForRepository to associate the classes with the correct repository key 44 | registrarContext.registerClassesForRepository(MyJavaRulesDefinition.REPOSITORY_KEY, Arrays.asList(checkClasses()), Arrays.asList(testCheckClasses())); 45 | } 46 | 47 | /** 48 | * Lists all the checks provided by the plugin 49 | */ 50 | public static Class[] checkClasses() { 51 | return new Class[] { 52 | UnderlineDollarNameCheck.class, 53 | UpperCameCaseCheck.class, 54 | LowerCameCaseCheck.class, 55 | ConstantNameCheck.class, 56 | AbstractClassNameCheck.class, 57 | ExceptionClassNameCheck.class, 58 | ArrayNameCheck.class 59 | }; 60 | } 61 | 62 | /** 63 | * Lists all the test checks provided by the plugin 64 | */ 65 | public static Class[] testCheckClasses() { 66 | return new Class[] {}; 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/MyJavaRulesDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Java Custom Rules Example 3 | * Copyright (C) 2016-2016 SonarSource SA 4 | * mailto:contact AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.java.rule; 21 | 22 | import com.google.common.base.Charsets; 23 | import com.google.common.io.Resources; 24 | import com.google.gson.Gson; 25 | import org.sonar.api.rule.RuleStatus; 26 | import org.sonar.api.server.debt.DebtRemediationFunction; 27 | import org.sonar.api.server.rule.RulesDefinition; 28 | import org.sonar.plugins.java.Java; 29 | import org.sonar.squidbridge.annotations.AnnotationBasedRulesDefinition; 30 | 31 | import javax.annotation.Nullable; 32 | import java.io.IOException; 33 | import java.net.URL; 34 | import java.util.Locale; 35 | 36 | /** 37 | * Declare rule metadata in server repository of rules. 38 | * That allows to list the rules in the page "Rules". 39 | */ 40 | public class MyJavaRulesDefinition implements RulesDefinition { 41 | 42 | public static final String REPOSITORY_KEY = "finger-java-custom-rules"; 43 | 44 | private final Gson gson = new Gson(); 45 | 46 | @Override 47 | public void define(Context context) { 48 | NewRepository repository = context 49 | .createRepository(REPOSITORY_KEY, Java.KEY) 50 | .setName("Finger Java Custom Rules"); 51 | 52 | new AnnotationBasedRulesDefinition(repository, Java.KEY) 53 | .addRuleClasses(/* don't fail if no SQALE annotations */ false, RulesList.getChecks()); 54 | 55 | for (NewRule rule : repository.rules()) { 56 | String metadataKey = rule.key(); 57 | System.out.println(metadataKey); 58 | // Setting internal key is essential for rule templates (see SONAR-6162), and it is not done by AnnotationBasedRulesDefinition from 59 | // sslr-squid-bridge version 2.5.1: 60 | rule.setInternalKey(metadataKey); 61 | rule.setHtmlDescription(readRuleDefinitionResource(metadataKey + ".html")); 62 | addMetadata(rule, metadataKey); 63 | } 64 | 65 | repository.done(); 66 | } 67 | 68 | @Nullable 69 | private static String readRuleDefinitionResource(String fileName) { 70 | URL resource = MyJavaRulesDefinition.class.getResource("/org/sonar/l10n/java/rules/squid/" + fileName); 71 | if (resource == null) { 72 | return null; 73 | } 74 | try { 75 | return Resources.toString(resource, Charsets.UTF_8); 76 | } catch (IOException e) { 77 | throw new IllegalStateException("Failed to read: " + resource, e); 78 | } 79 | } 80 | 81 | private void addMetadata(NewRule rule, String metadataKey) { 82 | String json = readRuleDefinitionResource(metadataKey + ".json"); 83 | if (json != null) { 84 | RuleMetadata metadata = gson.fromJson(json, RuleMetadata.class); 85 | rule.setSeverity(metadata.defaultSeverity.toUpperCase(Locale.US)); 86 | rule.setName(metadata.title); 87 | rule.setTags(metadata.tags); 88 | rule.setStatus(RuleStatus.valueOf(metadata.status.toUpperCase(Locale.US))); 89 | 90 | if (metadata.remediation != null) { 91 | // metadata.remediation is null for template rules 92 | rule.setDebtRemediationFunction(metadata.remediation.remediationFunction(rule.debtRemediationFunctions())); 93 | rule.setGapDescription(metadata.remediation.linearDesc); 94 | } 95 | } 96 | } 97 | 98 | private static class RuleMetadata { 99 | String title; 100 | String status; 101 | @Nullable 102 | Remediation remediation; 103 | 104 | String[] tags; 105 | String defaultSeverity; 106 | } 107 | 108 | private static class Remediation { 109 | String func; 110 | String constantCost; 111 | String linearDesc; 112 | String linearOffset; 113 | String linearFactor; 114 | 115 | private DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) { 116 | if (func.startsWith("Constant")) { 117 | return drf.constantPerIssue(constantCost.replace("mn", "min")); 118 | } 119 | if ("Linear".equals(func)) { 120 | return drf.linear(linearFactor.replace("mn", "min")); 121 | } 122 | return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/MyJavaRulesPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Java Custom Rules Example 3 | * Copyright (C) 2016-2016 SonarSource SA 4 | * mailto:contact AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.java.rule; 21 | 22 | import org.sonar.api.Plugin; 23 | 24 | /** 25 | * Entry point of your plugin containing your custom rules 26 | */ 27 | public class MyJavaRulesPlugin implements Plugin { 28 | 29 | @Override 30 | public void define(Context context) { 31 | 32 | // server extensions -> objects are instantiated during server startup 33 | context.addExtension(MyJavaRulesDefinition.class); 34 | 35 | // batch extensions -> objects are instantiated during code analysis 36 | context.addExtension(MyJavaFileCheckRegistrar.class); 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/RulesList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarQube Java Custom Rules Example 3 | * Copyright (C) 2016-2016 SonarSource SA 4 | * mailto:contact AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package org.sonar.java.rule; 21 | 22 | import com.google.common.collect.ImmutableList; 23 | import org.sonar.java.rule.checks.namerules.*; 24 | import org.sonar.plugins.java.api.JavaCheck; 25 | 26 | import java.util.List; 27 | 28 | public final class RulesList { 29 | 30 | private RulesList() { 31 | } 32 | 33 | public static List getChecks() { 34 | return ImmutableList.builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build(); 35 | } 36 | 37 | public static List> getJavaChecks() { 38 | return ImmutableList.>builder() 39 | .add(UnderlineDollarNameCheck.class) 40 | .add(UpperCameCaseCheck.class) 41 | .add(LowerCameCaseCheck.class) 42 | .add(ConstantNameCheck.class) 43 | .add(AbstractClassNameCheck.class) 44 | .add(ExceptionClassNameCheck.class) 45 | .add(ArrayNameCheck.class) 46 | .build(); 47 | } 48 | 49 | public static List> getJavaTestChecks() { 50 | return ImmutableList.>builder() 51 | .build(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/MyFirstCustomCheck.java: -------------------------------------------------------------------------------- 1 | //package org.finger.java.rule.checks; 2 | // 3 | //import com.google.common.collect.ImmutableList; 4 | //import org.sonar.check.Priority; 5 | //import org.sonar.check.Rule; 6 | //import org.sonar.java.ast.visitors.SubscriptionVisitor; 7 | //import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; 8 | //import org.sonar.plugins.java.api.semantic.Symbol; 9 | //import org.sonar.plugins.java.api.semantic.Type; 10 | //import org.sonar.plugins.java.api.tree.MethodTree; 11 | //import org.sonar.plugins.java.api.tree.Tree; 12 | //import org.sonar.plugins.java.api.tree.Tree.Kind; 13 | // 14 | //import java.util.List; 15 | // 16 | ///** 17 | // * Created by huqingen on 2017/3/16. 18 | // */ 19 | //@Rule( 20 | // key = "MyFirstCustomCheck", 21 | // name = "Return type and parameter of a method should not be the same", 22 | // description = "For a method having a single parameter, the types of its return value and its parameter should never be the same.", 23 | // priority = Priority.CRITICAL, 24 | // tags = {"bug"}) 25 | //public class MyFirstCustomCheck extends IssuableSubscriptionVisitor{ 26 | // @Override 27 | // public List nodesToVisit() { 28 | // return ImmutableList.of(Kind.METHOD); 29 | // } 30 | // 31 | // 32 | // 33 | // @Override 34 | // public void visitNode(Tree tree){ 35 | // MethodTree method = (MethodTree) tree; 36 | // if(method.parameters().size() == 1){ 37 | // Symbol.MethodSymbol symbol = method.symbol(); 38 | // Type firstParameterType = symbol.parameterTypes().get(0); 39 | // Type returnType = symbol.returnType().type(); 40 | // 41 | // System.out.println(">>>" + firstParameterType + "<<<"); 42 | // System.out.println(">>>" + returnType + "<<<"); 43 | // 44 | // if(returnType.equals(firstParameterType.fullyQualifiedName())){ 45 | // reportIssue(method.simpleName(),"For a method having a single parameter, the types of its return value and its parameter should never be the same"); 46 | // } 47 | // 48 | // } 49 | // } 50 | //} 51 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/AbstractClassNameCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.plugins.java.api.JavaFileScanner; 7 | import org.sonar.plugins.java.api.JavaFileScannerContext; 8 | import org.sonar.plugins.java.api.tree.*; 9 | 10 | /** 11 | * 抽象类命名检查 12 | * 抽象类命名使用 Abstract 或 Base 开头 13 | * Created by 古月随笔 on 2017/3/17. 14 | */ 15 | @Rule(key = "AbstractClassNameCheck") 16 | public class AbstractClassNameCheck extends BaseTreeVisitor implements JavaFileScanner{ 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(AbstractClassNameCheck.class); 19 | 20 | private JavaFileScannerContext context; 21 | 22 | @Override 23 | public void scanFile(JavaFileScannerContext context) { 24 | this.context = context; 25 | scan(context.getTree()); 26 | } 27 | 28 | @Override 29 | public void visitClass(ClassTree tree) { 30 | String className = tree.simpleName().name(); 31 | 32 | LOGGER.info(className + "<<>>" + tree.symbol().isAbstract()); 33 | 34 | 35 | if(tree.symbol().isAbstract()){ 36 | //判断名称是否以Abstract 或 Base 开头 37 | 38 | String abName = "Abstract"; 39 | String bsName = "Base"; 40 | //判断类名如果小于Abstract 或 Base 41 | if (className.length() < abName.length() || className.length() < bsName.length()) { 42 | context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 43 | } else { 44 | //判断是否存在 Abstract 或 Base 45 | if (!className.contains(abName)) { 46 | if (!className.contains(bsName)) { 47 | context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 48 | } else { 49 | if (className.indexOf(bsName) != 0) { 50 | context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 51 | } 52 | } 53 | } else { 54 | if (className.indexOf(abName) != 0) { 55 | context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 56 | } 57 | } 58 | } 59 | } 60 | 61 | // for(ModifierTree modifiersTree : tree.modifiers()){ 62 | // if(modifiersTree instanceof ModifierKeywordTree) { 63 | // ModifierKeywordTree modifierKeywordTree = (ModifierKeywordTree) modifiersTree; 64 | // String name = modifierKeywordTree.modifier().name(); 65 | // //判断是否为抽象类 66 | // if ("ABSTRACT".equals(name)) { 67 | // //判断名称是否以Abstract 或 Base 开头 68 | // 69 | // String abName = "Abstract"; 70 | // String bsName = "Base"; 71 | // //判断类名如果小于Abstract 或 Base 72 | // if (className.length() < abName.length() || className.length() < bsName.length()) { 73 | // context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 74 | // } else { 75 | // //判断是否存在 Abstract 或 Base 76 | // if (!className.contains(abName)) { 77 | // if (!className.contains(bsName)) { 78 | // context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 79 | // } else { 80 | // if (className.indexOf(bsName) != 0) { 81 | // context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 82 | // } 83 | // } 84 | // } else { 85 | // if (className.indexOf(abName) != 0) { 86 | // context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first"); 87 | // } 88 | // } 89 | // } 90 | // 91 | // } 92 | // } 93 | // } 94 | super.visitClass(tree); 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/ArrayNameCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.java.model.JavaTree; 7 | import org.sonar.plugins.java.api.JavaFileScanner; 8 | import org.sonar.plugins.java.api.JavaFileScannerContext; 9 | import org.sonar.plugins.java.api.tree.*; 10 | 11 | /** 12 | * 数组名称检查 13 | * 中括号是数组类型的一部分,数组定义如下:String[] args; 14 | * Created by huqingen on 2017/3/18. 15 | */ 16 | @Rule(key = "ArrayNameCheck") 17 | public class ArrayNameCheck extends BaseTreeVisitor implements JavaFileScanner{ 18 | 19 | private static final Logger LOGGER = LoggerFactory.getLogger(ArrayNameCheck.class); 20 | 21 | private JavaFileScannerContext context; 22 | 23 | @Override 24 | public void scanFile(JavaFileScannerContext context) { 25 | this.context = context; 26 | scan(context.getTree()); 27 | } 28 | 29 | /** 30 | * 通过获取String 所在到列值,以及[所在到列值,组合判断是否符合规范 31 | * @param tree 32 | */ 33 | @Override 34 | public void visitVariable(VariableTree tree) { 35 | 36 | String variableName = tree.simpleName().name(); 37 | 38 | String typeName = tree.symbol().type().name(); 39 | 40 | if("Array".equals(typeName)) { 41 | if (tree.type() instanceof JavaTree) { 42 | //获取数据类型 43 | JavaTree sTree = (JavaTree) tree.type(); 44 | //获取基础数组类对象所在列 45 | int firstColumn = sTree.firstToken().column(); 46 | //获取基础数组类对象到字符长度 47 | int arrayClassLenth = sTree.firstToken().text().length(); 48 | //获取基础数组类对象 ] 所在列 49 | int lastColumn = sTree.lastToken().column(); 50 | //根据对象所在列 + 对象长度 + 1,预期应等于类对象 ] 所在列 51 | if((firstColumn + arrayClassLenth + 1) != lastColumn){ 52 | context.reportIssue(this,tree,"[] should follow the array object"); 53 | } 54 | } 55 | } 56 | 57 | super.visitVariable(tree); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/ConstantNameCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.plugins.java.api.JavaFileScanner; 7 | import org.sonar.plugins.java.api.JavaFileScannerContext; 8 | import org.sonar.plugins.java.api.tree.*; 9 | 10 | /** 11 | * 常量名称检查 12 | * 常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚 13 | * Created by huqingen on 2017/3/17. 14 | */ 15 | @Rule(key = "ConstantNameCheck") 16 | public class ConstantNameCheck extends BaseTreeVisitor implements JavaFileScanner{ 17 | 18 | private static final Logger LOGGER = LoggerFactory.getLogger(ConstantNameCheck.class); 19 | 20 | 21 | private JavaFileScannerContext context; 22 | 23 | @Override 24 | public void scanFile(JavaFileScannerContext context) { 25 | this.context = context; 26 | scan(context.getTree()); 27 | } 28 | 29 | /** 30 | * 1.检查是否有常量 31 | * 2.检查常量的命名是否符合规范(变量名称和是否有static final) 32 | * 33 | * @param tree 34 | */ 35 | @Override 36 | public void visitVariable(VariableTree tree){ 37 | 38 | String varibaleName = tree.simpleName().name();//变量名称 39 | 40 | 41 | if(tree.symbol().isFinal()){ 42 | //如果字符串大于10时,且没有按照_进行分割,报错 43 | if(varibaleName.length() > 10 && !varibaleName.contains("_")){ 44 | LOGGER.info("长度过长BUG:" + varibaleName); 45 | context.reportIssue(this,tree,"different name should spilt as _"); 46 | } 47 | 48 | //变量字符串中有数字,报错 49 | int count = 0; 50 | for(char s : varibaleName.toCharArray()){ 51 | if(Character.isDigit(s)){ 52 | count ++; 53 | } 54 | } 55 | if(count > 0){ 56 | LOGGER.info("变量字符串中有数字:" + varibaleName); 57 | context.reportIssue(this,tree,"The Name should not contain digit"); 58 | } 59 | 60 | //把变量的所有英文字符串提取出来 61 | String sVaribaleName = varibaleName.replaceAll("[^a-z^A-Z]",""); 62 | int i = 0;//计数器 63 | for(char s : sVaribaleName.toCharArray()){ 64 | if(Character.isLowerCase(s)){ 65 | i++; 66 | } 67 | } 68 | if(i > 0){ 69 | LOGGER.info("没有大写的BUG" + i + ":" + varibaleName); 70 | context.reportIssue(this,tree,"The Name should be As UpperCase"); 71 | } 72 | } 73 | super.visitVariable(tree); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/ExceptionClassNameCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.plugins.java.api.JavaFileScanner; 7 | import org.sonar.plugins.java.api.JavaFileScannerContext; 8 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 9 | import org.sonar.plugins.java.api.tree.ClassTree; 10 | 11 | /** 12 | * 异常类命名检查 13 | * 异常类命名使用 Exception 结尾 14 | * Created by huqingen on 2017/3/17. 15 | */ 16 | @Rule(key = "ExceptionClassNameCheck") 17 | public class ExceptionClassNameCheck extends BaseTreeVisitor implements JavaFileScanner{ 18 | private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionClassNameCheck.class); 19 | 20 | private JavaFileScannerContext context; 21 | 22 | @Override 23 | public void scanFile(JavaFileScannerContext context) { 24 | this.context = context; 25 | scan(context.getTree()); 26 | } 27 | 28 | @Override 29 | public void visitClass(ClassTree tree) { 30 | String className = tree.simpleName().name(); 31 | String checkName = "Exception"; 32 | if(tree.superClass() != null) { 33 | String superClassName = tree.superClass().symbolType().name(); 34 | 35 | if(checkName.equals(superClassName)){ 36 | if(checkName.length() > className.length()){ 37 | context.reportIssue(this,tree,"Class name must end with Exception"); 38 | }else { 39 | if(!className.contains(checkName)){ 40 | context.reportIssue(this,tree,"Class name must end with Exception"); 41 | }else { 42 | if(!checkName.equals(className.substring(className.length()-checkName.length()))){ 43 | context.reportIssue(this,tree,"Class name must end with Exception"); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | super.visitClass(tree); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/LowerCameCaseCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.plugins.java.api.JavaFileScanner; 7 | import org.sonar.plugins.java.api.JavaFileScannerContext; 8 | import org.sonar.plugins.java.api.tree.*; 9 | 10 | /** 11 | * 方法名、参数名、成员变量、局部变量都统一使用 lowerCamelCase 风格,必须遵从 驼峰形式 12 | * Created by huqingen on 2017/3/17. 13 | */ 14 | @Rule(key="LowerCameCaseCheck") 15 | public class LowerCameCaseCheck extends BaseTreeVisitor implements JavaFileScanner{ 16 | 17 | private static final Logger LOGGER = LoggerFactory.getLogger(LowerCameCaseCheck.class); 18 | 19 | 20 | private JavaFileScannerContext context; 21 | 22 | @Override 23 | public void scanFile(JavaFileScannerContext context) { 24 | this.context = context; 25 | scan(context.getTree()); 26 | } 27 | 28 | /** 29 | * 方法内检查驼峰命名 30 | * 构造函数除外 31 | * @param tree 32 | */ 33 | @Override 34 | public void visitMethod(MethodTree tree){ 35 | //判断是否为构造函数,构造函数返回类型为null 36 | if(tree.symbol().returnType() != null) { 37 | 38 | String methodName = tree.simpleName().name(); 39 | LOGGER.info("构造函数:" + methodName + ">>>>" + tree.symbol().returnType()); 40 | //判断方法名称首字符是否小写 41 | char methodChar = methodName.charAt(0); 42 | 43 | if (Character.isUpperCase(methodChar)) { 44 | LOGGER.info(">>判断方法名称首字符是否小写>>" + methodName); 45 | context.reportIssue(this, tree, "The first Character Of Method Name should not UpperCase"); 46 | } 47 | 48 | if ("CLASS".equals(tree.parent().kind().name())) { 49 | //判断方法内的局部变量是否符合驼峰规则 50 | for (StatementTree statementTree : tree.block().body()) { 51 | 52 | //判断值类型是否为VariableTree 53 | if (statementTree instanceof VariableTree) { 54 | VariableTree sTree = (VariableTree) statementTree; 55 | if (sTree.simpleName() != null) { 56 | char sName = sTree.simpleName().name().charAt(0); 57 | if (Character.isUpperCase(sName)) { 58 | LOGGER.info(">>判断方法内的局部变量是否符合驼峰规则>>" + sTree.simpleName().name()); 59 | context.reportIssue(this, tree, "The first character of local Parameters should not be UpperCase"); 60 | } 61 | } 62 | } 63 | } 64 | } 65 | } 66 | 67 | super.visitMethod(tree); 68 | } 69 | 70 | /** 71 | * 判断变量命名是否符合规范(方法参数变量和成员变量) 72 | * @param tree 73 | */ 74 | @Override 75 | public void visitVariable(VariableTree tree){ 76 | 77 | String variableName = tree.simpleName().name(); 78 | char cVariableName = variableName.charAt(0); 79 | 80 | if(!tree.symbol().isFinal()){ 81 | if(Character.isUpperCase(cVariableName)){ 82 | LOGGER.info(">>判断变量命名是否符合规范>>" + tree.simpleName().name()); 83 | context.reportIssue(this,tree,"The first character of Member Variable should not be UpperCase"); 84 | } 85 | } 86 | super.visitVariable(tree); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/UnderlineDollarNameCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.plugins.java.api.JavaFileScanner; 7 | import org.sonar.plugins.java.api.JavaFileScannerContext; 8 | import org.sonar.plugins.java.api.tree.*; 9 | 10 | /** 11 | * 命名规约 12 | * 代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束 13 | * Created by huqingen on 2017/3/16. 14 | */ 15 | //@Rule( 16 | // key = "UnderlineDollarNameCheck", 17 | // name = "Can't use underline or Dollar first or end As Name", 18 | // description = "Can't use underline or Dollar first or end As Name", 19 | // priority = Priority.CRITICAL, 20 | // tags = {"bug"}) 21 | @Rule(key = "UnderlineDollarNameCheck") 22 | public class UnderlineDollarNameCheck extends BaseTreeVisitor implements JavaFileScanner { 23 | 24 | private static final Logger LOGGER = LoggerFactory.getLogger(UnderlineDollarNameCheck.class); 25 | 26 | 27 | private JavaFileScannerContext context; 28 | 29 | @Override 30 | public void scanFile(JavaFileScannerContext context) { 31 | this.context = context; 32 | scan(context.getTree()); 33 | } 34 | 35 | /** 36 | * 判断类名是否以_或$开始或结尾 37 | * @param tree 38 | */ 39 | @Override 40 | public void visitClass(ClassTree tree) { 41 | LOGGER.info("ClassName:" + tree.simpleName().name()); 42 | String className = tree.simpleName().name(); 43 | if("_".equals(className.substring(0,1))){ 44 | context.reportIssue(this,tree,"Can't Name this"); 45 | } 46 | super.visitClass(tree); 47 | } 48 | 49 | /** 50 | * 判断方法名称是否以_或$开始或结尾 51 | * 判断方法的参数是否以_或$开始或结尾 52 | */ 53 | @Override 54 | public void visitMethod(MethodTree tree){ 55 | 56 | String methodName = tree.simpleName().name(); 57 | if("CLASS".equals(tree.parent().kind().name())) { 58 | //判断方法局部变量名称是否以_或$开始或结尾 59 | for (StatementTree statementTree : tree.block().body()) { 60 | if(statementTree instanceof VariableTree) { 61 | VariableTree sTree = (VariableTree) statementTree; 62 | String sName = sTree.simpleName().name(); 63 | if ("_".equals(sName.substring(0, 1)) || "_".equals(sName.substring(sName.length() - 1)) 64 | || "$".equals(sName.substring(0, 1)) || "$".equals(sName.substring(sName.length() - 1))) { 65 | context.reportIssue(this, tree, "Can't Name As This"); 66 | } 67 | } 68 | } 69 | } 70 | 71 | //判断方法名称是否以_或$开始或结尾 72 | if("_".equals(methodName.substring(0,1)) || "_".equals(methodName.substring(methodName.length()-1)) 73 | || "$".equals(methodName.substring(0,1)) || "$".equals(methodName.substring(methodName.length()-1))){ 74 | context.reportIssue(this,tree,"Can't Name As This"); 75 | } 76 | 77 | super.visitMethod(tree); 78 | } 79 | 80 | /** 81 | * 判断成员变量命名是否符合规范 82 | * @param tree 83 | */ 84 | @Override 85 | public void visitVariable(VariableTree tree){ 86 | String variableName = tree.simpleName().name(); 87 | if("_".equals(variableName.substring(0,1)) || "_".equals(variableName.substring(variableName.length()-1)) 88 | || "$".equals(variableName.substring(0,1)) || "$".equals(variableName.substring(variableName.length()-1))){ 89 | context.reportIssue(this,tree,"Can't Name As This"); 90 | } 91 | super.visitVariable(tree); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/main/java/org/sonar/java/rule/checks/namerules/UpperCameCaseCheck.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.sonar.check.Rule; 6 | import org.sonar.plugins.java.api.JavaFileScanner; 7 | import org.sonar.plugins.java.api.JavaFileScannerContext; 8 | import org.sonar.plugins.java.api.tree.BaseTreeVisitor; 9 | import org.sonar.plugins.java.api.tree.ClassTree; 10 | 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | /** 15 | * 检查: 类名是否以驼峰形式命名 16 | * Created by huqingen on 2017/3/17. 17 | */ 18 | @Rule(key="UpperCameCaseCheck") 19 | public class UpperCameCaseCheck extends BaseTreeVisitor implements JavaFileScanner{ 20 | private static final Logger LOGGER = LoggerFactory.getLogger(UpperCameCaseCheck.class); 21 | 22 | 23 | private JavaFileScannerContext context; 24 | 25 | @Override 26 | public void scanFile(JavaFileScannerContext context) { 27 | this.context = context; 28 | scan(context.getTree()); 29 | } 30 | 31 | 32 | /** 33 | * 判断类名是否以驼峰形式命名 34 | * @param tree 35 | */ 36 | @Override 37 | public void visitClass(ClassTree tree) { 38 | 39 | String className = tree.simpleName().name(); 40 | 41 | //例外情况(领域模型 的相关命名)DO / BO / DTO / VO 42 | 43 | List otherList = new ArrayList<>(); 44 | otherList.add("DO"); 45 | otherList.add("BO"); 46 | otherList.add("DTO"); 47 | otherList.add("VO"); 48 | 49 | for(String otherName: otherList){ 50 | if(otherName.equalsIgnoreCase(className.substring(className.length()-otherName.length()))){ 51 | if(!otherName.equals(className.substring(className.length()-otherName.length()))){ 52 | context.reportIssue(this,tree,"Can't Name this"); 53 | } 54 | } 55 | } 56 | 57 | //判断第一个字符是否为大写 58 | char name = className.charAt(0); 59 | if(Character.isLowerCase(name)){ 60 | context.reportIssue(this,tree,"Can't Name this"); 61 | } 62 | super.visitClass(tree); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/AbstractClassNameCheck.html: -------------------------------------------------------------------------------- 1 |

AbstractClassNameCheck Check

2 |

Noncompliant Code Example

3 |
 4 |     public abstract class HiClass {// Noncompliant
 5 |     }
 6 | 
 7 |     public abstract class MyNameIsAbstract {// Noncompliant
 8 |     }
 9 | 
10 |

Compliant Solution

11 |
12 |     public abstract class AbstractMysql {
13 |     }
14 | 
15 |     public abstract class BaseMysql {
16 |     }
17 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/AbstractClassNameCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "The Name Of Abstract Class should use Abstract or Base first", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/AbstractClassNameCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "The Name Of Abstract Class should use Abstract or Base first", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ArrayNameCheck.html: -------------------------------------------------------------------------------- 1 |

AbstractClassNameCheck Check 2 | [] should follow the array object 3 |

4 |

Noncompliant Code Example

5 |
 6 | 
 7 |     private String errorTemp[];// Noncompliant
 8 | 
 9 |     private String[] rightTemp;
10 | 
11 |     public void getTemp(String noTemp[]){// Noncompliant
12 |         int intHi[];// Noncompliant
13 |         int[] intNo;
14 |     }
15 | 
16 |

Compliant Solution

17 |
18 |     private String[] errorTemp;// Noncompliant
19 |     private String[] rightTemp;// Noncompliant
20 | 
21 |     public void getTemp(String[] noTemp){// Noncompliant
22 |         int[] intHi;// Noncompliant
23 |         int[] intNo;// Noncompliant
24 |     }
25 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ArrayNameCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "[] should follow the array object", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "MAJOR" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ArrayNameCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "[] should follow the array object", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "MAJOR" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ConstantNameCheck.html: -------------------------------------------------------------------------------- 1 |

ConstantNameCheck Check

2 |

Noncompliant Code Example

3 |
 4 |     private static final String z; // Noncompliant
 5 | 
 6 |     private static final String Hello_WORLD = "Hello WOLD"; // Noncompliant
 7 | 
 8 |     private static final String NO_123_ZZZ = "sdddsaa";// Noncompliant
 9 | 
10 |      private static final String HELLOWORLDMYNAMEISLILEI = "Hello WOLD MY NAME IS LI LEI"; // Noncompliant
11 | 
12 | 
13 |

Compliant Solution

14 |
15 |     private static final String BAIDU_HOST_NAME = "http://www.baidu.com";
16 | 
17 |     private static final String V = "1.0";
18 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ConstantNameCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Constant Name rule should use UppCase,And each word show spilt as _", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ConstantNameCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Constant Name rule should use UppCase,And each word show spilt as _", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ExceptionClassNameCheck.html: -------------------------------------------------------------------------------- 1 |

ExceptionClassNameCheck Check

2 |

Noncompliant Code Example

3 |
 4 |     public abstract class HiClass {// Noncompliant
 5 |     }
 6 | 
 7 |     public abstract class MyNameIsAbstract {// Noncompliant
 8 |     }
 9 | 
10 |

Compliant Solution

11 |
12 |     public abstract class AbstractMysql {
13 |     }
14 | 
15 |     public abstract class BaseMysql {
16 |     }
17 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ExceptionClassNameCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Class name must end with Exception", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/ExceptionClassNameCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Class name must end with Exception", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/LowerCameCaseCheck.html: -------------------------------------------------------------------------------- 1 |

LowerCameCase Check

2 |

Noncompliant Code Example

3 |
 4 |     private String ID; // Noncompliant
 5 |     private String UserName; // Noncompliant
 6 |     private String password;
 7 | 
 8 |     public String getUserInfo(String info) {
 9 |         String Yes = "Yes"; // Noncompliant
10 |     }
11 | 
12 |     public void GetPassword(){}// Noncompliant
13 | 
14 |     public void getUser(String UserInfo){}// Noncompliant
15 | 
16 |

Compliant Solution

17 |
18 |     private String id;
19 |     private String userName;
20 |     private String password;
21 | 
22 |     public String getUserInfo(String info) {
23 |         String yes = "Yes";
24 |     }
25 | 
26 |     public void getPassword(){}
27 | 
28 |     public void getUser(String userInfo){}
29 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/LowerCameCaseCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Can't use LowerCamelCase Style As Name", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/LowerCameCaseCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Can't use LowerCamelCase Style As Name", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/UnderlineDollarNameCheck.html: -------------------------------------------------------------------------------- 1 |

Can't use underline or Dollar first or end As Name

2 |

Noncompliant Code Example

3 |
 4 |     private String _Hi;// Noncompliant
 5 |     private String Hi_;// Noncompliant
 6 |     private String $Hi;// Noncompliant
 7 |     private String Hi$;// Noncompliant
 8 | 
 9 |     public void test(String _Hi, String Hi_,String $Hi,String Hi$){ // Noncompliant
10 |     }
11 | 
12 |     public void test_(){}  // Noncompliant
13 | 
14 |     public void $test(){}  // Noncompliant
15 | 
16 |     public void test$(){}  // Noncompliant
17 | 
18 |

Compliant Solution

19 |
20 |     private String Hi;
21 | 
22 |     public void test(String Hi){
23 |     }
24 | 
25 |     public void test(){}
26 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/UnderlineDollarNameCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Can't use underline or Dollar first or end As Name", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/UnderlineDollarNameCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Can't use underline or Dollar first or end As Name", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/UpperCameCaseCheck.html: -------------------------------------------------------------------------------- 1 |

UpperCamelCase check

2 |

Noncompliant Code Example

3 |
 4 |     macroPolo // Noncompliant
 5 |     UserDo // Noncompliant
 6 |     XMLService // Noncompliant
 7 |     TCPUDPDeal // Noncompliant
 8 |     TAPromotion // Noncompliant
 9 | 
10 |

Compliant Solution

11 |
12 |     MarcoPolo
13 |     UserDO
14 |     XmlService
15 |     TcpUdpDeal
16 |     TaPromotion
17 | 
-------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/UpperCameCaseCheck.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Can't use UpperCamelCase Style As Name", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/main/resources/org/sonar/l10n/java/rules/squid/UpperCameCaseCheck_java.json: -------------------------------------------------------------------------------- 1 | { 2 | "title": "Can't use UpperCamelCase Style As Name", 3 | "status": "ready", 4 | "remediation": { 5 | "func": "Constant\/Issue", 6 | "constantCost": "5min" 7 | }, 8 | "tags": [ 9 | "bug", 10 | "pitfall" 11 | ], 12 | "defaultSeverity": "CRITICAL" 13 | } -------------------------------------------------------------------------------- /src/test/files/AbstractMysql.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/17. 5 | */ 6 | public abstract class AbstractMysql { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/ActionTestCase.java: -------------------------------------------------------------------------------- 1 | package com.finger.web.api; 2 | 3 | import com.finger.web.model.HTTPRequestInfo; 4 | import com.finger.web.pojo.TResultInfo; 5 | import net.sf.json.JSONObject; 6 | 7 | /** 8 | * 执行测试用例 9 | * Created by huqingen on 2017/3/10. 10 | */ 11 | public interface ActionTestCase { 12 | 13 | /** 14 | * 执行http测试请求 15 | * @param httpRequestInfo 16 | * @return 17 | */ 18 | TResultInfo runTestCase(JSONObject HttpRequestInfo, String assertValue);// Noncompliant 19 | } -------------------------------------------------------------------------------- /src/test/files/ActionTestCaseImpl.java: -------------------------------------------------------------------------------- 1 | package com.finger.web.api.impl; 2 | 3 | import com.finger.web.api.ActionTestCase; 4 | import com.finger.web.common.DateUtils; 5 | import com.finger.web.common.HTTPClientMethod; 6 | import com.finger.web.pojo.TResultInfo; 7 | import net.sf.json.JSONArray; 8 | import net.sf.json.JSONObject; 9 | import org.apache.commons.logging.Log; 10 | import org.apache.commons.logging.LogFactory; 11 | import org.springframework.stereotype.Component; 12 | 13 | import java.text.ParseException; 14 | import java.util.ArrayList; 15 | import java.util.HashMap; 16 | import java.util.Iterator; 17 | import java.util.Map; 18 | /** 19 | * Created by huqingen on 2017/3/10. 20 | */ 21 | @Component 22 | public class ActionTestCaseImpl implements ActionTestCase{ 23 | 24 | private static final Log LOGGER= LogFactory.getLog(ActionTestCaseImpl.class); 25 | 26 | private static final String FINGERSSLHOST = "https://stable.fingerapp.cn"; 27 | 28 | private DateUtils dateUtils; 29 | 30 | /** 31 | * 32 | * @param httpRequestInfo 33 | * @param assertValue 34 | * @return 35 | */ 36 | public TResultInfo runTestCase(JSONObject httpRequestInfo,String assertValue){ 37 | TResultInfo tResultInfo = new TResultInfo(); 38 | try { 39 | tResultInfo = HTTPTestRun(httpRequestInfo,assertValue); 40 | } catch (ParseException e) { 41 | LOGGER.info(e); 42 | } 43 | 44 | return tResultInfo; 45 | } 46 | 47 | /** 48 | * http请求 49 | * @param httpRequestInfo 50 | * @param assertValue 51 | * @return 52 | */ 53 | public TResultInfo HTTPTestRun(JSONObject httpRequestInfo,String assertValue) throws ParseException { 54 | HTTPClientMethod httpClientMethod = new HTTPClientMethod(); 55 | TResultInfo resultInfo = new TResultInfo(); 56 | String model = httpRequestInfo.get("model").toString(); 57 | String method = httpRequestInfo.get("method").toString(); 58 | 59 | if("delete".equalsIgnoreCase(method) || "get".equalsIgnoreCase(method)) { 60 | resultInfo = deleteOrGet(httpClientMethod, resultInfo, httpRequestInfo, method, assertValue,model); 61 | return resultInfo; 62 | } 63 | 64 | if("post".equalsIgnoreCase(method) || "put".equalsIgnoreCase(method)){ 65 | resultInfo = postOrPut(httpClientMethod,resultInfo,httpRequestInfo,method,assertValue,model); 66 | return resultInfo; 67 | } 68 | resultInfo.setActionresult(0); 69 | return resultInfo; 70 | } 71 | 72 | /** 73 | * 处理header 74 | * @param headerContent 75 | * @return 76 | */ 77 | 78 | public Map getHeaders(String headerContent){ 79 | Map headers = new HashMap(); 80 | if (headerContent.length() != 0) { 81 | JSONObject headerJSON = JSONObject.fromObject(headerContent);//转换成JSON 82 | Iterator keys = headerJSON.keys(); 83 | while (keys.hasNext()) { 84 | String key = String.valueOf(keys.next()); 85 | String value = (String) headerJSON.get(key); 86 | headers.put(key, value); 87 | } 88 | } 89 | return headers; 90 | } 91 | 92 | /** 93 | * 处理post或put请求 94 | * @param httpClientMethod 95 | * @param resultInfo 96 | * @param httpRequestInfo 97 | * @param method 98 | * @param assertValue 99 | * @return 100 | */ 101 | public TResultInfo postOrPut(HTTPClientMethod httpClientMethod,TResultInfo resultInfo,JSONObject httpRequestInfo,String method,String assertValue,String model) throws ParseException { 102 | //处理Headers 103 | String headerContent = httpRequestInfo.get("header").toString(); 104 | String paramsContent = httpRequestInfo.get("params").toString(); 105 | String uriContent = httpRequestInfo.get("uri").toString(); 106 | Map headers = getHeaders(headerContent); 107 | String url = FINGERSSLHOST + uriContent; 108 | 109 | LOGGER.info("URL信息:" + url); 110 | LOGGER.info("Header信息:" + headerContent); 111 | JSONObject result = new JSONObject(); 112 | //判断参数是JSONOjcet还是JSONArray 113 | if ("{".equals(paramsContent.substring(0, 1))) { 114 | JSONObject paramsJSON = JSONObject.fromObject(paramsContent);//生成JSON格式的参数 115 | LOGGER.info("Params信息: " + paramsJSON.toString()); 116 | //发送HTTP请求 117 | try { 118 | if("HTTPS".equalsIgnoreCase(model)) { 119 | if ("post".equalsIgnoreCase(method)) { 120 | result = httpClientMethod.postSSLJSONMethod(url, paramsJSON, headers); 121 | } else { 122 | result = httpClientMethod.putSSLJSONMethod(url, paramsJSON, headers); 123 | } 124 | }else { 125 | if ("post".equalsIgnoreCase(method)) { 126 | result = httpClientMethod.postJSONMethod(url, paramsJSON, headers); 127 | } else { 128 | result = httpClientMethod.putJSONMethod(url, paramsJSON, headers); 129 | } 130 | } 131 | resultInfo.setTestresultinfo(result.toString()); 132 | } catch (Exception e) { 133 | LOGGER.info(e); 134 | } 135 | 136 | } else { 137 | JSONArray paramsJSON = JSONArray.fromObject(paramsContent);//生成JSONArray格式 138 | LOGGER.info("Params信息: " + paramsJSON.toString()); 139 | //发送HTTP请求 140 | try { 141 | if("HTTPS".equalsIgnoreCase(model)) { 142 | if ("post".equalsIgnoreCase(method)) { 143 | result = httpClientMethod.postSSLJSONArrayMethod(url, paramsJSON, headers); 144 | } else { 145 | result = httpClientMethod.putSSLJSONArrayMethod(url, paramsJSON, headers); 146 | } 147 | }else { 148 | if ("post".equalsIgnoreCase(method)) { 149 | result = httpClientMethod.postJSONArrayMethod(url, paramsJSON, headers); 150 | } else { 151 | result = httpClientMethod.putJSONArrayMethod(url, paramsJSON, headers); 152 | } 153 | } 154 | resultInfo.setTestresultinfo(result.toString()); 155 | } catch (Exception e) { 156 | LOGGER.info(e); 157 | } 158 | 159 | } 160 | 161 | //断言结果 162 | boolean actionResult = resultAssert(assertValue,result.toString()); 163 | 164 | if(actionResult == true){ 165 | resultInfo.setActionresult(1); 166 | }else { 167 | resultInfo.setActionresult(2); 168 | } 169 | return resultInfo; 170 | } 171 | 172 | /** 173 | * 处理delete或get请求 174 | * @param httpClientMethod 175 | * @param resultInfo 176 | * @param httpRequestInfo 177 | * @param method 178 | * @param assertValue 179 | * @param model 180 | * @return 181 | */ 182 | public TResultInfo deleteOrGet(HTTPClientMethod httpClientMethod,TResultInfo resultInfo,JSONObject httpRequestInfo,String method,String assertValue,String model) throws ParseException { 183 | //处理Headers 184 | String headerContent = httpRequestInfo.get("header").toString(); 185 | // String paramsContent = httpRequestInfo.get("params").toString(); 186 | String uriContent = httpRequestInfo.get("uri").toString(); 187 | Map headers = getHeaders(headerContent); 188 | String url = FINGERSSLHOST + uriContent; 189 | 190 | LOGGER.info("Header信息:" + headerContent); 191 | LOGGER.info("URL信息:" + url); 192 | 193 | JSONObject result = new JSONObject(); 194 | 195 | 196 | //发送HTTP请求 197 | try { 198 | 199 | if("HTTPS".equalsIgnoreCase(model)) { 200 | if("get".equalsIgnoreCase(method)) { 201 | result = httpClientMethod.getSSLMethod(url, headers); 202 | }else { 203 | result = httpClientMethod.deleteSSLMethod(url,new HashMap(), headers); 204 | } 205 | }else { 206 | if("get".equalsIgnoreCase(method)) { 207 | result = httpClientMethod.getMethod(url, headers); 208 | }else { 209 | result = httpClientMethod.deleteMethod(url,new HashMap(), headers); 210 | } 211 | } 212 | resultInfo.setTestresultinfo(result.toString()); 213 | } catch (Exception e) { 214 | LOGGER.info(e); 215 | } 216 | 217 | //断言结果 218 | boolean actionResult = resultAssert(assertValue,result.toString()); 219 | 220 | if(actionResult == true){ 221 | resultInfo.setActionresult(1); 222 | }else { 223 | resultInfo.setActionresult(2); 224 | } 225 | return resultInfo; 226 | } 227 | 228 | 229 | 230 | /** 231 | * 断言处理 232 | * @param excepContent 233 | * @param resultContent 234 | * @return 235 | */ 236 | public boolean resultAssert(String excepContent,String resultContent) { 237 | 238 | //判断预期结果中是否要判断多种类型,以,进行分割 239 | if(excepContent.contains(",") && !",".equals(excepContent.substring(excepContent.length()-1))) { 240 | String[] excepContentList = excepContent.split(","); 241 | //增加不等于,以 !表示不等于 242 | ArrayList equalContentList = new ArrayList(); //等于 243 | ArrayList notEqualContentList = new ArrayList(); //不等于 244 | for(String str : excepContentList){ 245 | if(str.substring(0,1).contains("!")){ 246 | notEqualContentList.add(str.substring(1)); 247 | }else { 248 | equalContentList.add(str); 249 | } 250 | } 251 | ArrayList failList = new ArrayList();//专门存储失败项 252 | //遍历等于 253 | for(String tempStr : equalContentList){ 254 | if(!resultContent.contains(tempStr)){ 255 | failList.add("FAIL"); 256 | } 257 | } 258 | //遍历不等于 259 | for(String tempStr : notEqualContentList){ 260 | if(resultContent.contains(tempStr)){ 261 | failList.add("FAIL"); 262 | } 263 | } 264 | //判断FailList是否为空 265 | if(failList.isEmpty()){ 266 | LOGGER.info("测试结果: PASS"); 267 | return true; 268 | } 269 | LOGGER.info("测试结果: FAIL"); 270 | return false; 271 | }else { 272 | if(!"".equals(excepContent)) { 273 | if (resultContent.contains(excepContent)) { 274 | LOGGER.info("测试结果: PASS "); 275 | return true; 276 | } 277 | LOGGER.info("测试结果: FAIL"); 278 | return false; 279 | } 280 | LOGGER.info("测试结果: FAIL"); 281 | return false; 282 | } 283 | } 284 | 285 | 286 | } 287 | -------------------------------------------------------------------------------- /src/test/files/AgeOutOfBound.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/18. 5 | */ 6 | public class AgeOutOfBound extends Exception implements Hi{// Noncompliant 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/AgeOutOfException.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/18. 5 | */ 6 | public class AgeOutOfException extends Exception implements Hi{ 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/AgeOutOfExceptionBound.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/18. 5 | */ 6 | public class AgeOutOfExceptionBound extends Exception implements Hi{// Noncompliant 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/ArrayNameCheckMapper.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/18. 5 | */ 6 | public class ArrayNameCheckMapper { 7 | 8 | private String zzzz; 9 | 10 | private String errorTemp[];// Noncompliant 11 | 12 | private String[] rightTemp; 13 | 14 | public void getTemp(String noTemp[]){// Noncompliant 15 | int intHi[];// Noncompliant 16 | int[] intNo; 17 | } 18 | 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/test/files/BaseMysql.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/17. 5 | */ 6 | public abstract class BaseMysql { 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/ConstantNameMapper.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/17. 5 | */ 6 | public class ConstantNameMapper { 7 | 8 | private String Biz ; 9 | 10 | private static String WH = "2221"; 11 | 12 | private static final String NO_BB_CC_DD_CC_SSS = "2212313213"; 13 | 14 | private static final String V = "122333"; 15 | 16 | private static final String HELLOWORLDMYNAMEISLILEI = "Hello WOLD MY NAME IS LI LEI"; // Noncompliant 17 | 18 | private static final String Hello_WORLD = "Hello WOLD"; // Noncompliant 19 | 20 | private static final String NO_123_ZZZ = "sdddsaa";// Noncompliant 21 | } 22 | -------------------------------------------------------------------------------- /src/test/files/HiClass.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/17. 5 | */ 6 | public abstract class HiClass {// Noncompliant 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/LowerCameCaseMapper.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/17. 5 | */ 6 | public class LowerCameCaseMapper { 7 | private String ID;// Noncompliant 8 | private String UserName;// Noncompliant 9 | private String password;// Compliant 10 | 11 | private static final String NO_BB_CC_DD_CC_SSS = "2212313213"; 12 | 13 | public String getUserInfo(String info) { // Noncompliant 14 | String Yes = "Yes";// Noncompliant 15 | return info+Yes; 16 | } 17 | 18 | public void GetPassword(){} // Noncompliant 19 | 20 | public void getUser(String UserInfo) {// Noncompliant 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/files/MyFirstCustomCheck.java: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | MyClass(MyClass mc) { } 3 | 4 | int foo1() { return 0; } 5 | void foo2(int value) { } 6 | int foo3(int value) { return 0; } // Noncompliant 7 | Object foo4(int value) { return null; } 8 | MyClass foo5(MyClass value) {return null; } // Noncompliant 9 | 10 | int foo6(int value, String name) { return 0; } 11 | int foo7(int ... values) { return 0;} 12 | } -------------------------------------------------------------------------------- /src/test/files/MyNameIsAbstract.java: -------------------------------------------------------------------------------- 1 | package org.finger.java.rule.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/17. 5 | */ 6 | public abstract class MyNameIsAbstract {// Noncompliant 7 | } 8 | -------------------------------------------------------------------------------- /src/test/files/TestKeyWordContainsRule.java: -------------------------------------------------------------------------------- 1 | import a.b.CallMessage; 2 | 3 | class TestKeyWordContainsRule { 4 | 5 | 6 | void foo(int value) { 7 | CallMessage.sendMsg("abc"); 8 | Thread.sleep(); 9 | } 10 | 11 | int foo3(int value) { 12 | return 0; 13 | } 14 | 15 | 16 | } -------------------------------------------------------------------------------- /src/test/files/UnderlineDollarRuleMapper.java: -------------------------------------------------------------------------------- 1 | package com.finger.alirules.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/16. 5 | */ 6 | public class UnderlineDollarRuleMapper { 7 | private String _Hi;// Noncompliant 8 | private String Hi_;// Noncompliant 9 | private String $Hi;// Noncompliant 10 | private String Hi$;// Noncompliant 11 | 12 | private String Hi; 13 | 14 | public void test(String _Hi){}// Noncompliant 15 | 16 | public void test(String Hi_){}// Noncompliant 17 | 18 | public void test(String $Hi){}// Noncompliant 19 | 20 | public void test(String Hi$){}// Noncompliant 21 | 22 | public void test_(){} // Noncompliant 23 | 24 | public void $test(){} // Noncompliant 25 | 26 | public void test$(){} // Noncompliant 27 | } 28 | -------------------------------------------------------------------------------- /src/test/files/UserDo.java: -------------------------------------------------------------------------------- 1 | package com.finger.alirules.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/16. 5 | */ 6 | public class UserDo { // Noncompliant 7 | 8 | } -------------------------------------------------------------------------------- /src/test/files/XMLService.java: -------------------------------------------------------------------------------- 1 | package com.finger.alirules.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/16. 5 | */ 6 | public class XMLService { 7 | 8 | } -------------------------------------------------------------------------------- /src/test/files/macroPolo.java: -------------------------------------------------------------------------------- 1 | package com.finger.alirules.checks.namerules; 2 | 3 | /** 4 | * Created by huqingen on 2017/3/16. 5 | */ 6 | public class macroPolo { // Noncompliant 7 | 8 | } -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/MyJavaRulesDefinitionTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule; 2 | 3 | import static org.fest.assertions.Assertions.assertThat; 4 | 5 | import org.junit.Test; 6 | import org.sonar.api.rules.RuleType; 7 | import org.sonar.api.server.debt.DebtRemediationFunction; 8 | import org.sonar.api.server.rule.RuleParamType; 9 | import org.sonar.api.server.rule.RulesDefinition; 10 | 11 | public class MyJavaRulesDefinitionTest { 12 | 13 | @Test 14 | public void test() { 15 | MyJavaRulesDefinition rulesDefinition = new MyJavaRulesDefinition(); 16 | RulesDefinition.Context context = new RulesDefinition.Context(); 17 | rulesDefinition.define(context); 18 | RulesDefinition.Repository repository = context.repository(MyJavaRulesDefinition.REPOSITORY_KEY); 19 | 20 | assertThat(repository.key()).isEqualTo("finger-java-custom-rules"); 21 | assertThat(repository.name()).isEqualTo("Finger Java Custom Rules"); 22 | assertThat(repository.language()).isEqualTo("java"); 23 | assertThat(repository.rules()).hasSize(RulesList.getChecks().size()); 24 | 25 | assertRuleProperties(repository); 26 | // assertParameterProperties(repository); 27 | // assertAllRuleParametersHaveDescription(repository); 28 | } 29 | 30 | private void assertParameterProperties(RulesDefinition.Repository repository) { 31 | // TooManyLinesInFunctionCheck 32 | RulesDefinition.Param max = repository.rule("AvoidAnnotation").param("name"); 33 | assertThat(max).isNotNull(); 34 | assertThat(max.defaultValue()).isEqualTo("Inject"); 35 | assertThat(max.description()).isEqualTo("Name of the annotation to avoid, without the prefix @, for instance 'Override'"); 36 | assertThat(max.type()).isEqualTo(RuleParamType.STRING); 37 | } 38 | 39 | private void assertRuleProperties(RulesDefinition.Repository repository) { 40 | RulesDefinition.Rule rule = repository.rule("UnderlineDollarNameCheck"); 41 | assertThat(rule).isNotNull(); 42 | assertThat(rule.name()).isEqualTo("Can't use underline or Dollar first or end As Name"); 43 | assertThat(rule.debtRemediationFunction().type()).isEqualTo(DebtRemediationFunction.Type.CONSTANT_ISSUE); 44 | assertThat(rule.type()).isEqualTo(RuleType.BUG); 45 | } 46 | 47 | private void assertAllRuleParametersHaveDescription(RulesDefinition.Repository repository) { 48 | for (RulesDefinition.Rule rule : repository.rules()) { 49 | for (RulesDefinition.Param param : rule.params()) { 50 | assertThat(param.description()).as("description for " + param.key()).isNotEmpty(); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/MyFirstCustomCheckTest.java: -------------------------------------------------------------------------------- 1 | //package org.finger.java.rule.checks; 2 | // 3 | //import org.junit.Test; 4 | //import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | // 6 | ///** 7 | // * Created by huqingen on 2017/3/16. 8 | // */ 9 | //public class MyFirstCustomCheckTest { 10 | // @Test 11 | // public void test() { 12 | // JavaCheckVerifier.verify("src/test/files/MyFirstCustomCheck.java", new MyFirstCustomCheck()); 13 | // } 14 | //} 15 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/AbstractClassNameCheckTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/17. 8 | */ 9 | public class AbstractClassNameCheckTest { 10 | @Test 11 | public void test() { 12 | JavaCheckVerifier.verify("src/test/files/HiClass.java", new AbstractClassNameCheck()); 13 | } 14 | 15 | @Test 16 | public void test1() { 17 | JavaCheckVerifier.verify("src/test/files/MyNameIsAbstract.java", new AbstractClassNameCheck()); 18 | } 19 | 20 | @Test 21 | public void test2() { 22 | JavaCheckVerifier.verify("src/test/files/BaseMysql.java", new AbstractClassNameCheck()); 23 | } 24 | @Test 25 | public void test3() { 26 | JavaCheckVerifier.verify("src/test/files/AbstractMysql.java", new AbstractClassNameCheck()); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/ArrayNameCheckTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/18. 8 | */ 9 | public class ArrayNameCheckTest { 10 | @Test 11 | public void test() { 12 | JavaCheckVerifier.verify("src/test/files/ArrayNameCheckMapper.java", new ArrayNameCheck()); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/ConstantNameCheckTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/17. 8 | */ 9 | public class ConstantNameCheckTest { 10 | @Test 11 | public void test() { 12 | JavaCheckVerifier.verify("src/test/files/ConstantNameMapper.java", new ConstantNameCheck()); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/ExceptionClassNameCheckTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/18. 8 | */ 9 | public class ExceptionClassNameCheckTest { 10 | @Test 11 | public void test() { 12 | JavaCheckVerifier.verify("src/test/files/AgeOutOfBound.java", new ExceptionClassNameCheck()); 13 | } 14 | 15 | @Test 16 | public void test1() { 17 | JavaCheckVerifier.verify("src/test/files/HiClass.java", new ExceptionClassNameCheck()); 18 | } 19 | 20 | @Test 21 | public void test2() { 22 | JavaCheckVerifier.verify("src/test/files/AgeOutOfException.java", new ExceptionClassNameCheck()); 23 | } 24 | 25 | @Test 26 | public void test3() { 27 | JavaCheckVerifier.verify("src/test/files/AgeOutOfExceptionBound.java", new ExceptionClassNameCheck()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/LowerCameCaseChecTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/17. 8 | */ 9 | public class LowerCameCaseChecTest { 10 | @Test 11 | public void test() { 12 | try { 13 | JavaCheckVerifier.verify("src/test/files/LowerCameCaseMapper.java", new LowerCameCaseCheck()); 14 | }catch (IllegalStateException e){ 15 | e.printStackTrace(); 16 | } 17 | } 18 | 19 | @Test 20 | public void test1() { 21 | JavaCheckVerifier.verify("src/test/files/Result.java", new LowerCameCaseCheck()); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/UnderlineDollarNameCheckTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/17. 8 | */ 9 | public class UnderlineDollarNameCheckTest { 10 | @Test 11 | public void test() { 12 | JavaCheckVerifier.verify("src/test/files/UnderlineDollarRuleMapper.java", new UnderlineDollarNameCheck()); 13 | } 14 | @Test 15 | public void test1(){ 16 | JavaCheckVerifier.verify("src/test/files/ActionTestCase.java", new UnderlineDollarNameCheck()); 17 | } 18 | @Test 19 | public void test2(){ 20 | JavaCheckVerifier.verify("src/test/files/ActionTestCaseImpl.java", new UnderlineDollarNameCheck()); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/org/sonar/java/rule/checks/namerules/UpperCameCaseCheckTest.java: -------------------------------------------------------------------------------- 1 | package org.sonar.java.rule.checks.namerules; 2 | 3 | import org.junit.Test; 4 | import org.sonar.java.checks.verifier.JavaCheckVerifier; 5 | 6 | /** 7 | * Created by huqingen on 2017/3/17. 8 | */ 9 | public class UpperCameCaseCheckTest { 10 | @Test 11 | public void test1() { 12 | JavaCheckVerifier.verify("src/test/files/macroPolo.java", new UpperCameCaseCheck()); 13 | } 14 | 15 | @Test 16 | public void test2(){ 17 | JavaCheckVerifier.verify("src/test/files/UserDo.java", new UpperCameCaseCheck()); 18 | } 19 | @Test 20 | public void test3(){ 21 | JavaCheckVerifier.verify("src/test/files/AbstractMysql.java", new UpperCameCaseCheck()); 22 | } 23 | @Test 24 | public void test4(){ 25 | JavaCheckVerifier.verify("src/test/files/ActionTestCase.java", new UpperCameCaseCheck()); 26 | } 27 | } 28 | --------------------------------------------------------------------------------