Sonar Java 规则插件开发 (基于阿里开发手册)
引言
最近在做Sonar静态代码扫描管理,以此顺手接了Sonar的插件开发,基于阿里开发手册进行开发,在整体开发过程中,其中还是遇到不少坑位,也以此给大家做相应借鉴
官网Demo演示插件开发地址:
https://docs.sonarqube.org/display/PLUG/Writing+Custom+Java+Rules+101
基于官网的我暂时不多说,基础框架按照官网的范例进行搭建即可
#开源地址:
https://github.com/tigerge000/sonar-java-custom-rules.git
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
<p>AbstractClassNameCheck Check</p>
<h2>Noncompliant Code Example</h2>
<pre>
public abstract class HiClass {// Noncompliant
}
public abstract class MyNameIsAbstract {// Noncompliant
}
</pre>
<h2>Compliant Solution</h2>
<pre>
public abstract class AbstractMysql {
}
public abstract class BaseMysql {
}
</pre>
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());
}
}
开发目录结构:
PS:
1.编写sonar规则的时候,给个建议,采用Debug方式调试整个tree里面的内容,针对性的编写自己想要的规则,sonar在这块扫描基础方法做的还是很棒的
Sonar Java 规则插件开发 (基于阿里开发手册)的更多相关文章
- [Jenkins 新插件] 兼容阿里开发手册 (P3C) 的火线插件安装使用教程
一.前言 火线(Fireline)的Jenkins官方插件已经上线,目前火线不仅能检查出安卓代码中的安全类问题和内存泄露问题,还兼容了阿里开源的Java开发规约(P3C项目),本文将以教程的形式帮助大 ...
- idea使用阿里工具优化代码+阿里开发手册
idea安装工具 打开插件安装界面 File-Settings-Plugins-Browse repositories... 搜索Alibaba Java Coding Guidelines 进行安装 ...
- 为什么Arrays.asList() 不能使用其修改方法(阿里开发手册里明确说明)
Arrays.asList()方法把数组转换成集合时,不能使用其修改集合相关的方法,它的add/remove/clear方法会抛出UnsupportedOperationException(),我们来 ...
- Sonar 平台搭建及 Sonar 自定义规则打包部署篇
引言 基于阿里开发手册的sonar自定义插件工程 开源地址: https://github.com/tigerge000/sonar-java-custom-rules.git由于最近来问童鞋,就算写 ...
- 【转】持续集成 Sonar 平台搭建及 Sonar 自定义规则打包部署篇
引言 基于阿里开发手册的sonar自定义插件工程 开源地址: https://github.com/tigerge000/sonar-java-custom-rules.git由于最近来问童鞋,就算写 ...
- 阿里正式发布《Java开发手册》终极版!
摘要: 本文讲的是阿里正式发布<Java开发手册>终极版!,别人都说我们是码农,但我们知道,自己是个艺术家.也许我们不过多在意自己的外表和穿着,但我们不羁的外表下,骨子里追求着代码的美.质 ...
- JUC学习笔记--从阿里Java开发手册学习线程池的正确创建方法
前言 最近看阿里的 Java开发手册,上面有线程池的一个建议: [强制]线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式, 这样的处理方式让写的同学 ...
- 阿里JAVA开发手册零度的思考理解(二)
转载请注明原创出处,谢谢! 说在前面 人生的大道上默默地走,就必须要有一盏灯亮着为你引导方向!而这盏灯抑或只是一句话,一句鼓励,一个赞美,一次承认,一次认可,一次相识一次交流-- 上篇文章:阿里JAV ...
- 阿里Java开发手册1.3.0 文字版
版本: 1.3.0 update: 2017.9.25 一.编程规约 (一) 命名风格 1. [强制]代码中的命名均不能以下划线或美元符号开始,也不能以下划线或美元符号结束. 反例:_name _na ...
随机推荐
- svn 的权限配置
#分配用户所属组 g_admin=admin g_ui=zhangsan,lisi g_code=wangwu g_test=zhaoliu,qianqi #分配目录权限 #表示项目根目录 [/] @ ...
- firewall配置
词解释 在具体介绍zone之前学生先给大家介绍几个相关的名词,因为如果不理解这几个名词zone就无从入手. target:目标,这个前面学生也已经给大家介绍过了,可以理解为默认行为,有四个可选值:de ...
- LARS 最小角回归算法简介
最近开始看Elements of Statistical Learning, 今天的内容是线性模型(第三章..这本书东西非常多,不知道何年何月才能读完了),主要是在看变量选择.感觉变量选择这一块领域非 ...
- Jekyll博客添加Valine评论
Jekyll博客添加Valine评论 关于github搭建jekyl博客,在这里不做过多描述,详情参考: 百度搜索关键字:github搭建jekyll博客 官网:https://www.jekyll. ...
- IPhone手机常用的一些连
1.查看固件可下载链接. ipsw.me 2.查看手机型号(是global还是GSM). https://ipsw.me/device-finder 3.系统降级链接. https://jingyan ...
- java第六次课后作业
class Check{ public boolean validate(String name, String password){ if(name.equals("shenhaochen ...
- 读取properties配置文件,value值为中文时出现乱码
已确保idea工具默认设置都是UTF-8格式: 然后在配置类上,指定编码: @PropertySource(value = "classpath:short_message.prop ...
- Linux常用shell命令
1.>>>>>刚安装好的ubuntu需要为root创建密码[解决]passwd root 2.>>>>>安装完ubuntu后需要更新[解决] ...
- js 两数的最大公约数
function gcd(a,b){ if (b == 0){ return a; } var r = parseInt(a % b) ; return gcd(b, r);}gcd(12,5);
- C++之 类型定义语句--typedef
typedef的作用是给一个已经存在的数据类型起个别名. 使用的语法形式是:typedef 已有类型名 新类型名表;. 新类型名表中可以有多个标识符,它们之间用逗号分开,就是在一个typedef ...