4.2.3.p3c-pmd项目编写自定义代码规则
打开阿里p3c-pmd工程,开始编写我们的自定义规则。
阿里已经写了很多规则,我们现在要编写的规则属于面向对象范畴,可以把规则写到opp包下,新建一个规则类MethodParameterCountRule,继承自AbstractAliRule,重写 visit方法:
package com.alibaba.p3c.pmd.lang.java.rule.oop; import com.alibaba.p3c.pmd.lang.java.rule.AbstractAliRule; import net.sourceforge.pmd.lang.ast.Node; import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit; import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters; import java.util.List; /** * 方法参数列表个数不宜过长 * * @auther qingjian.wu * @create 2018-01-27 14:59 */ public class MethodParameterCountRule extends AbstractAliRule{ private static final String METHOD_XPATH = "//MethodDeclarator"; private static final Integer PARAMETER_COUNT_LIMIT = 5; @Override public Object visit(ASTCompilationUnit node, Object data) { try { // 找到所方法节点 List<Node> methodNodes = node.findChildNodesWithXPath(METHOD_XPATH); if (methodNodes != null && methodNodes.size() > 0) { for (Node methodNode : methodNodes) { // 找到每个方法的参数列表声明 List<ASTFormalParameters> formalParameters = methodNode.findChildrenOfType(ASTFormalParameters.class); if (formalParameters.get(0).getParameterCount() >= PARAMETER_COUNT_LIMIT) { // 违反规则提示信息,第二个参数是提示信息位置,第三个参数是提示信息key,第四个参数用来替换提示信息 // 中的占位符,这里获取的节点image属性就是方法名称 addViolationWithMessage(data, methodNode, "java.oop.MethodParameterCountRule.violation.msg", new Object[]{methodNode.getImage()}); } } } } catch (Exception e) { e.printStackTrace(); } return super.visit(node, data); } }
4.2.4.p3c-pmd项目配置规则
将编写好规则配置到ali-oop.xml文件中
<rule name="MethodParameterCountRule" language="java" message="java.oop.MethodParameterCountRule.rule.msg" class="com.alibaba.p3c.pmd.lang.java.rule.oop.MethodParameterCountRule"> <!--级别,1强制,2推荐,3参考--> <priority>1</priority> <example> <![CDATA[ Negative example: public void methodB(int a, int b, int c, int d, int e) { } ]]> </example> <example> <![CDATA[ Positive example: public void methodA() { } ]]> </example> </rule>
4.2.5.p3c-pmd项目编写提示信息
上两步使用的提示信息和规则信息需要编写到message.xml配置文件中,message_en.xml中是英文提示,这里就先不演示了
<entry key="java.oop.MethodParameterCountRule.violation.msg"> <![CDATA[方法【%s】参数列表过长。 ]]> </entry> <entry key="java.oop.MethodParameterCountRule.rule.msg"> <![CDATA[说明:方法参数列表不允许超过(含)5个,建议封装到一个对象中。]]> </entry>
4.2.6.单元测试
编写测试样例,将要测试的源代码写到test目录对应的xml文件中
推荐一个 Spring Boot 基础教程及实战示例: https://github.com/javastacks/spring-boot-best-practice
<?xml version="1.0" encoding="UTF-8"?> <test-data> <code-fragment id="测试样例"> <![CDATA[ package org.p3c.demo; public class Demo { public void methodA(int a) { } public void methodB(int a, int b, int c, int d, int e) { } } ]]> </code-fragment> <test-code> <!-- 预期问题个数 --> <expected-problems>0</expected-problems> <code-ref id="测试样例" /> </test-code> </test-data>
编写单元测试
运行单元测试,因为样例代码中methodB不符合规范,但是我们预期问题个数写的是0,所以单元测试会不通过:
4.3.配置插件
4.3.1.p3c-pmd打包安装到本地maven仓库
先把用不到的插件maven-javadoc-plugin和maven-gpg-plugin注释掉,然后运行mvn命令:
mvn -DskipTests=true clean install





