1. PMD自带代码检查规则
在“Modify Your Codes with PMD(1)”中,我使用了PMD针对JBuilder IDE的插件。在介绍这个插件安装过程中,我提到了将4个*.jar放入“…\JBuilder\lib\ext”目录中。其中的“pmd-1.5.jar”中保含了PMD代码检查规则的定义和声明。
PMD的每一个检查规则都是以一个java类的形式存在的,也就是说,PMD的对一项代码规范的检查规则是用java语言进行定义和描述的同时。在“pmd-1.5.jar\rulesets”中还用XML对这些规则进行了元数据(Metadata)定义,以便使用者阅读、了解每个规则的定义、描述和示例。
pmd-1.5.jar中的规则(Rules)java类和其描述XML文档(注意其在*.jar中的位置):

增加规则(Rules)的描述XML是帮助开发者使用PMD时对每项规则的理解,以便快速的修改或重构其代码。在JBuilder(已经引入PMD插件)中,点击菜单“Tools->PMD->Configure PMD”可进入PMD的配置对话框,在这里可以配置已有PMD的代码检查规则,注册添加新的自定义的检查规则或对某项规则的定义、描述和示例。下图是PMD的Basic Rules中的Empty Try Block的描述和示例。这些描述和示例全都是写在“pmd-1.5.jar\rulesets”中的那个对应的XML文档“basic.xml”中的。

通过这个图形界面,可以对PMD中自带的规则进行一个全面的了解。也从一个侧面让我明白了高质量的代码和我的代码究竟差多远。当然,很多规则并不一定是强制性的,或一定要成为你的项目组的规范,自己取舍吧。
2. 细看规则
所有的规则(Rules)java类均继承于“net.sourceforge.pmd.AbstractRules.class”抽象类,并在包“net.sourceforge.pmd.*”的支持下生效。规则对代码的检查当然是基于前面所提到的抽象语义树(AST,Abstract Syntax Tree)。还是在实际环境中看看吧。
在PMD的安装目录下,找到“astviewer.bat”。注意,不是PMD的JBuilder插件所在的那个目录,在我的环境中是“C:\pmd-1.8\etc\astviewer.bat”。运行该命令,可以调出AST分析器,该分析器可以将一段java代码分析为抽象语意树(AST)。
AST在即将普通的代码视为若干块(Block),块和块的关系即构成了树。举个简单的例子:如果我们的代码中一个if 嵌套另一个if,在AST中,就是一个if块为树枝,另一个if块为其上的树叶。还是以前面提到那个“Basic Rules”中的“Empty Try Block”规则为例来认识以下AST吧。
在“AST Viewer”中左上第一个窗口中将“Empty Try Block”规则那段例子代码拷贝进去,并为其加上一个类外观(即:将其放在一个类中,AST Viewer才能识别),然后点击“Go”按钮,在中间的一个窗口中会出现该段代码的AST(以退格代表树节点之间的关系)。

PMD的检查规则(Rules)就是建立在对代码进行AST分析的基础上的,并且是以一种基于事件的方式生效的。有点类似于SAX对XML文档的解析,一个PMD检查规则(Rules)就是一个事件处理类,当某个特定的代码块(Block,在AST中的一个节点)出现时,即激发该Rule的判断函数。比如,在上图所示AST中我们可以判断在该AST中“TryStatement”块中,在“Name:Exception”之前是否有其他有意义的语义节点。如果没有,即违法了“Empty Try Block”规则。
当然,这样的规则开发需要一套类库,即“net.sourceforge.pmd.*”。
3. 总结
对PMD规则(Rule)的了解,分为对其规则内容的了解和对其规则作用原理的了解。前者是为了帮助我们提高我们代码的质量;后者是为了开发我们自己的规则,以借助PMD的力量来提高我们的工程的质量。下次,我们一起来写个自己的PMD规则。