在XPath查询中使用条件

时间:2017-04-13 21:06:26

标签: java logging xpath pmd

我试图为我的仓库编写PMD规则,我需要所有记录器类只有log4j类型。 例如:

代码:

export class App {
    name:string;
    date: date;
    constructor() {
       this.name = `Angular! v${VERSION.full}`
    }

  todaysDate(month: number): void {
    let day = new Date().getDate();
    let year = new Date().getFullYear();
    this.date = new Date(year, month, day);

  }

  tomorrowsDate(month: number): void {
        let day = new Date().getDate() + 1;
        let year = new Date().getFullYear();
        this.date = new Date(year, month, day);
  }
}

我的PMD规则的XPath查询:

import some;
class Foo{
    Logger log = Logger.getLogger(Foo.class.getName());
    }
}

我在这里测试是否在代码和代码中使用了Logger类。它不是log4j类型,那么它就是违规行为。

1 个答案:

答案 0 :(得分:0)

由于可以有星级导入,相同的包访问以及简单和完全限定的名称,我建议您使用typeresolution

//ClassOrInterfaceBodyDeclaration//FieldDeclaration//Type//ReferenceType//ClassOrInterfaceType[ends-with(@Image, 'Logger') and not(typeof(@Image, 'org.apache.log4j.Logger', 'Logger'))]

最终规则将表述为:

<rule name="All Loggers must be Log4J Loggers"
      message="All Loggers must be Log4J Loggers"
      class="net.sourceforge.pmd.lang.rule.XPathRule"
      language="java"
      typeResolution="true">
    <description>
        All Loggers must be Log4J Loggers
    </description>
    <priority>3</priority>
    <properties>
        <property name="xpath">
            <value>
    //ClassOrInterfaceBodyDeclaration//FieldDeclaration//Type//ReferenceType//ClassOrInterfaceType[ends-with(@Image, 'Logger') and not(typeof(@Image, 'org.apache.log4j.Logger', 'Logger'))]
            </value>
        </property>
    </properties>
</rule>

请注意typeResolution="true"节点上的rule属性。还要确保正确填充类型解析的auxclasspath。 Gradle自动执行,在Maven上你需要enable it through configuration,使用Ant你需要手动传递auxclasspath

最后要注意的是,这个规则只会查找字段,其他记录器的未使用的导入/星级导入将不会被检测到,即使可以添加它们,我也只需要与the existing rule进行交易未使用的进口。