阿里巴巴java规范插件my_Sonar Java 规则插件开发 (基于阿里开发手册)

引言

最近在做 Sonar 静态代码扫描管理,以此顺手接了 Sonar 的插件开发,基于阿里开发手册进行开发,在整体开发过程中,其中还是遇到不少坑位,也以此给大家做相应借鉴

官网 Demo 演示插件开发地址:

https://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101

基于官网的我暂时不多说,基础框架按照官网的范例进行搭建即可

sonar 常用方法说明

范例

需求:【强制】抽象类命名使用 Abstract 或 Base 开头;异常类命名使用 Exception 结尾;测试类 命名以它要测试的类的名称开始,以 Test 结尾。

实现:

AbstractClassNameCheck

package org.finger.java.rule.checks.namerules;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.sonar.check.Rule;

import org.sonar.plugins.java.api.JavaFileScanner;

import org.sonar.plugins.java.api.JavaFileScannerContext;

import org.sonar.plugins.java.api.tree.*;

/**

* 抽象类命名检查

* 抽象类命名使用 Abstract 或 Base 开头

* Created by 古月随笔 on 2017/3/17.

*/

@Rule(key = "AbstractClassNameCheck")

public class AbstractClassNameCheck extends BaseTreeVisitor implements JavaFileScanner{

private static final Logger LOGGER = LoggerFactory.getLogger(AbstractClassNameCheck.class);

private JavaFileScannerContext context;

@Override

public void scanFile(JavaFileScannerContext context) {

this.context = context;

scan(context.getTree());

}

@Override

public void visitClass(ClassTree tree) {

String className = tree.simpleName().name();

LOGGER.info(className + "<<>>" + tree.symbol().isAbstract());

if(tree.symbol().isAbstract()){

//判断名称是否以Abstract 或 Base 开头

String abName = "Abstract";

String bsName = "Base";

//判断类名如果小于Abstract 或 Base

if (className.length() < abName.length() || className.length() < bsName.length()) {

context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");

} else {

//判断是否存在 Abstract 或 Base

if (!className.contains(abName)) {

if (!className.contains(bsName)) {

context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");

} else {

if (className.indexOf(bsName) != 0) {

context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");

}

}

} else {

if (className.indexOf(abName) != 0) {

context.reportIssue(this, tree, "The Name Of Abstract Class should use Abstract or Base first");

}

}

}

}

super.visitClass(tree);

}

}

resources 目录下添加目录:org.sonar.l10n.java.rules.squid(这命名主要是由于 sonar 源码中固定写死的)

AbstractClassNameCheck.html

AbstractClassNameCheck Check

Noncompliant Code Example

 
 

public abstract class HiClass {// Noncompliant

}

public abstract class MyNameIsAbstract {// Noncompliant

}

Compliant Solution

 
 

public abstract class AbstractMysql {

}

public abstract class BaseMysql {

}

AbstractClassNameCheck.json

{

"title": "The Name Of Abstract Class should use Abstract or Base first",

"status": "ready",

"remediation": {

"func": "Constant\/Issue",

"constantCost": "5min"

},

"tags": [

"bug",

"pitfall"

],

"defaultSeverity": "CRITICAL"

}

AbstractClassNameCheck_java.json(为什么有这个文件,主要是由于进行单测的时候,sonar 源码内容写死是 xxxx_java.json 命名)

{

"title": "The Name Of Abstract Class should use Abstract or Base first",

"status": "ready",

"remediation": {

"func": "Constant\/Issue",

"constantCost": "5min"

},

"tags": [

"bug",

"pitfall"

],

"defaultSeverity": "CRITICAL"

}

单测:

AbstractClassNameCheckTest

package org.finger.java.rule.checks.namerules;

import org.junit.Test;

import org.sonar.java.checks.verifier.JavaCheckVerifier;

/**

* Created by huqingen on 2017/3/17.

*/

public class AbstractClassNameCheckTest {

@Test

public void test() {

JavaCheckVerifier.verify("src/test/files/HiClass.java", new AbstractClassNameCheck());

}

@Test

public void test1() {

JavaCheckVerifier.verify("src/test/files/MyNameIsAbstract.java", new AbstractClassNameCheck());

}

@Test

public void test2() {

JavaCheckVerifier.verify("src/test/files/BaseMysql.java", new AbstractClassNameCheck());

}

@Test

public void test3() {

JavaCheckVerifier.verify("src/test/files/AbstractMysql.java", new AbstractClassNameCheck());

}

}

开发目录结构:

b4b4331c73907647fd0ee7402ab13c2d.png

PS:

1.由于编辑的时候经常出现 crash 问题,暂时先写到这,😓,真不是故意

2.编写 sonar 规则的时候,给个建议,采用 Debug 方式调试整个 tree 里面的内容,针对性的编写自己想要的规则,sonar 在这块扫描基础方法做的还是很棒的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值