前提:
1. 了解XPath:http://www.w3.org/TR/xpath
2. 对PMD 的实现原理有一定的了解
简单介绍一下pmd的实现原理:
Pmd利用javacc和EBNF文法产生一个分析器,用来分析java源代码(文本)。又在JavaCC的基础上加入了语义的概念也就是JJTree,这样就把java source转换成了一个抽象语法树(AST),AST是一个结构化的对象层次结构。我们可以用访问者模式访问这个结构上的每个节点。从而找出哪个节点违反了哪些规则。
实现过程:
l 首先传一个文件名或者Ruleset给pmd
l Pmd把该文件流传给自己生成的javaCC分析器
l 分析完毕后,pmd获得了分析生成的AST的一个引用
l PMD把AST处理成一个符号表,你可以在符号表里面查询一些有用的信息
l 每个pmd规则都会遍历整个AST并检验是否发生了错误
l 接着pmd产生一个报表,上面说明了有哪些地方违反了pmd规则
编写pmd规则有两种方法:
用java code,需要了解pmd的api,需要进行深入研究,也常常用于一些比较复杂的pmd规则
用xpath,对着产生的AST树,写就行了,上手比较快,写起来也比较简单
下面举一个用XPath实现的一个PMD规则:
在项目中,我们不希望Application的开发人员手动的调用Toplink UnitOfWork的commit,
commitAndResume, commitAndResumeOnFailure'方法,因为每次提交都会映像performa,我们的提交是放在自己编写的framework里面,在指定的位置提交。所以我们把规则的优先级设置为3. 在eclipse的pmd plugin中,优先级为3会产生一个警告。
1首先将D:"local_lib"pmd-bin-4.2"bin 加到系统环境变量的path中
2打开cmd 运行 designer 分析器
3左上角source code可以把你写好的java source copy过来主要就在这个java source code基础上不断修正你的pmd规则。
4xpath query:用来编写自定义的xpath expression(先不忙写xpath expression)
5点击go,就会在左下角的Abstract syntax Tree中产生AST,你可以选择AST上的某个节点,左下角的下面一个框中就会出现该节点的一些信息。是在符号表中查询得到的。
6.DFA是pmd4的新功能,用于编写更复杂的pmd规则,不光是某个source code级别了,pmd4使用了asm读取字节码,并作分析,处理类文件之间的依赖性。在实际使用中,特别是在特定应用中,这个功能是相当有用的。还可以用来简化一些现有的规则。
7根据生成的AST编写xpath expression。对于上文提到的source检查规则编写了一个xpath
Expression,在编写xpath expression的过程中需要反复的修改源代码并且反复的修改xpath expression这样才能满足所有的需要,反复的点击go。
最后写好的规则大致如下:
//PrimaryExpression[
(PrimaryPrefix/Name[ends-with(@Image, 'commit') or ends-with(@Image, 'commitAndResume') or ends-with(@Image, 'commitAndResumeOnFailure')] and substring-before(PrimaryPrefix/Name/@Image, '.') = //VariableDeclaratorId[../..//ClassOrInterfaceType[@Image =
'UnitOfWork']]/@Image) or (PrimarySuffix[ends-with(@Image, 'commit') or ends-with(@Image, 'commitAndResume') or ends-with(@Image, 'commitAndResumeOnFailure')] and (PrimarySuffix[ends-with(@Image, 'getActiveUnitOfWork')] or PrimarySuffix[ends-with(@Image, 'acquireUnitOfWork')]))
and
//ImportDeclaration/Name[
contains(@Image,'oracle.toplink.sessions.UnitOfWork') or contains(@Image, 'oracle.toplink.sessions')]
]
8.将写好的xpath expression转换成pmd rule。Designer可以自动生成点击菜单actions下面的create rule xml。
9.最后将生成的rule添加到ruleset中,并最好在大批量的代码中进行验证。