blob: 9c3f5785d9efc3772ff7b834196497d34af78cec [file] [log] [blame]
<?xml version="1.0"?>
<!--
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this work except in compliance with the License.
You may obtain a copy of the License in the LICENSE file, or at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<ruleset name="Aurora"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description>
Aurora PMD ruleset.
</description>
<rule ref="rulesets/java/design.xml">
<!-- We're not currently focusing on localization. -->
<exclude name="SimpleDateFormatNeedsLocale"/>
<exclude name="UseLocaleWithCaseConversions"/>
<!-- We deliberately use method-level synchronization for simplicity in many cases. -->
<exclude name="AvoidSynchronizedAtMethodLevel"/>
<!-- Empty methods in abstract classes can save implementers from boilerplate. -->
<exclude name="EmptyMethodInAbstractClassShouldBeAbstract"/>
<!-- We don't follow this practice, as we often prefer to keep like constants closest to where
they are used. -->
<exclude name="FieldDeclarationsShouldBeAtStartOfClass"/>
<!-- Unfortunately we have several large classes that trip this rule.
TODO(wfarner): Break apart god classes. -->
<exclude name="GodClass"/>
</rule>
<!-- Custom rules -->
<rule name="TimedAnnotationNonOverridableMethod"
language="java"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="A method must be overridable to have the @Timed annotation.">
<description>
A method must be overridable (non-static, non-final, public, protected or package-private)
in order to be used with the @Timed annotation. See: https://github.com/google/guice/wiki/AOP.
</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceBodyDeclaration[MethodDeclaration]
[count(./Annotation//Name[@Image='Timed']) > 0]
[count(./MethodDeclaration[(@Static = 'true') or (@Final = 'true') or (@Private = 'true')]) > 0]
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
public class Foo {
@Timed
// Must be non-static, non-final, public, protected or package-private.
protected Foo() { }
}
]]>
</example>
</rule>
<rule name="TimedAnnotationNonOverridableClass"
language="java"
class="net.sourceforge.pmd.lang.rule.XPathRule"
message="A class must be non-final, public or package-private to have methods with the @Timed annotation.">
<description>
A class must be non-final, public or package-private to have methods with the @Timed
annotation. See: https://github.com/google/guice/wiki/AOP.
</description>
<priority>1</priority>
<properties>
<property name="xpath">
<value>
<![CDATA[
//ClassOrInterfaceDeclaration[(@Final = 'true') or (@Private = 'true') or (@Protected = 'true')]
/ClassOrInterfaceBody/ClassOrInterfaceBodyDeclaration/Annotation//Name[@Image='Timed']
]]>
</value>
</property>
</properties>
<example>
<![CDATA[
// Must be non-final, public or package-private
class Foo {
@Timed
public Foo() { }
}
]]>
</example>
</rule>
</ruleset>