[doc] [apex] Adjust externalInfoUrl properties to new site - Part 5

Note: I also took the chance to fix tab damage
This commit is contained in:
Andreas Dangel
2017-08-14 21:18:27 +02:00
parent 1aaf52f0b0
commit cfa4e15d54
12 changed files with 605 additions and 551 deletions

View File

@ -20,7 +20,7 @@ import net.sourceforge.pmd.lang.apex.ast.ApexNode;
* *
* @author a.subramanian * @author a.subramanian
*/ */
public class ApexUnitTestClassShouldHaveAsserts extends AbstractApexUnitTestRule { public class ApexUnitTestClassShouldHaveAssertsRule extends AbstractApexUnitTestRule {
private static final Set<String> ASSERT_METHODS = new HashSet<>(); private static final Set<String> ASSERT_METHODS = new HashSet<>();

View File

@ -25,7 +25,7 @@ import apex.jorje.services.Version;
* *
* @author a.subramanian * @author a.subramanian
*/ */
public class ApexUnitTestShouldNotUseSeeAllDataTrue extends AbstractApexUnitTestRule { public class ApexUnitTestShouldNotUseSeeAllDataTrueRule extends AbstractApexUnitTestRule {
@Override @Override
public Object visit(final ASTUserClass node, final Object data) { public Object visit(final ASTUserClass node, final Object data) {

View File

@ -11,8 +11,8 @@
<rule name="ApexUnitTestClassShouldHaveAsserts" <rule name="ApexUnitTestClassShouldHaveAsserts"
since="5.5.1" since="5.5.1"
message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()" message="Apex unit tests should System.assert() or assertEquals() or assertNotEquals()"
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAsserts" class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestClassShouldHaveAssertsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/apexunit.html#ApexUnitTestClassShouldHaveAsserts"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_apexunit.html#apexunittestclassshouldhaveasserts">
<description> <description>
Apex unit tests should include at least one assertion. This makes the tests more robust, and using assert Apex unit tests should include at least one assertion. This makes the tests more robust, and using assert
with messages provide the developer a clearer idea of what the test does. with messages provide the developer a clearer idea of what the test does.
@ -35,8 +35,8 @@ public class Foo {
<rule name="ApexUnitTestShouldNotUseSeeAllDataTrue" <rule name="ApexUnitTestShouldNotUseSeeAllDataTrue"
since="5.5.1" since="5.5.1"
message="Apex unit tests should not use @isTest(seeAllData = true)" message="Apex unit tests should not use @isTest(seeAllData = true)"
class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrue" class="net.sourceforge.pmd.lang.apex.rule.apexunit.ApexUnitTestShouldNotUseSeeAllDataTrueRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/apexunit.html#ApexUnitTestShouldNotUseSeeAllDataTrue"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_apexunit.html#apexunittestshouldnotuseseealldatatrue">
<description> <description>
Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests. Apex unit tests should not use @isTest(seeAllData=true) because it opens up the existing database data for unexpected modification by tests.
</description> </description>

View File

@ -13,7 +13,7 @@ The Braces ruleset contains rules regarding the use and placement of braces.
since="5.6.0" since="5.6.0"
message="Avoid using if statements without curly braces" message="Avoid using if statements without curly braces"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule" class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#IfStmtsMustUseBraces"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#ifstmtsmustusebraces">
<description> <description>
Avoid using if statements without using braces to surround the code block. If the code Avoid using if statements without using braces to surround the code block. If the code
formatting or indentation is lost then it becomes difficult to separate the code being formatting or indentation is lost then it becomes difficult to separate the code being
@ -23,23 +23,21 @@ controlled from the rest.
<properties> <properties>
<property name="xpath"> <property name="xpath">
<value> <value>
<![CDATA[ <![CDATA[
//IfBlockStatement/BlockStatement[@CurlyBrace='false'] //IfBlockStatement/BlockStatement[@CurlyBrace='false']
]]> ]]>
</value> </value>
</property> </property>
</properties> </properties>
<example> <example>
<![CDATA[ <![CDATA[
if (foo) // not recommended if (foo) // not recommended
x++; x++;
if (foo) { // preferred approach if (foo) { // preferred approach
x++; x++;
} }
]]>
]]>
</example> </example>
</rule> </rule>
@ -48,7 +46,7 @@ if (foo) { // preferred approach
since="5.6.0" since="5.6.0"
message="Avoid using 'while' statements without curly braces" message="Avoid using 'while' statements without curly braces"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule" class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#WhileLoopsMustUseBraces"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#whileloopsmustusebraces">
<description> <description>
Avoid using 'while' statements without using braces to surround the code block. If the code Avoid using 'while' statements without using braces to surround the code block. If the code
formatting or indentation is lost then it becomes difficult to separate the code being formatting or indentation is lost then it becomes difficult to separate the code being
@ -81,7 +79,7 @@ while (true) { // preferred approach
since="5.6.0" since="5.6.0"
message="Avoid using 'if...else' statements without curly braces" message="Avoid using 'if...else' statements without curly braces"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule" class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#IfElseStmtsMustUseBraces"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#ifelsestmtsmustusebraces">
<description> <description>
Avoid using if..else statements without using surrounding braces. If the code formatting Avoid using if..else statements without using surrounding braces. If the code formatting
or indentation is lost then it becomes difficult to separate the code being controlled or indentation is lost then it becomes difficult to separate the code being controlled
@ -95,19 +93,19 @@ from the rest.
//IfBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0] //IfBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
| |
//IfElseBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0] //IfElseBlockStatement/BlockStatement[@CurlyBrace='false'][count(child::*) > 0]
]]> ]]>
</value> </value>
</property> </property>
</properties> </properties>
<example> <example>
<![CDATA[ <![CDATA[
// this is OK // this is OK
if (foo) x++; if (foo) x++;
// but this is not // but this is not
if (foo) if (foo)
x = x+1; x = x+1;
else else
x = x-1; x = x-1;
]]> ]]>
</example> </example>
@ -118,7 +116,7 @@ if (foo)
since="5.6.0" since="5.6.0"
message="Avoid using 'for' statements without curly braces" message="Avoid using 'for' statements without curly braces"
class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule" class="net.sourceforge.pmd.lang.apex.rule.ApexXPathRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/braces.html#ForLoopsMustUseBraces"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_braces.html#forloopsmustusebraces">
<description> <description>
Avoid using 'for' statements without using surrounding braces. If the code formatting or Avoid using 'for' statements without using surrounding braces. If the code formatting or
indentation is lost then it becomes difficult to separate the code being controlled indentation is lost then it becomes difficult to separate the code being controlled
@ -128,11 +126,11 @@ from the rest.
<properties> <properties>
<property name="xpath"> <property name="xpath">
<value> <value>
<![CDATA[ <![CDATA[
//ForLoopStatement/BlockStatement[@CurlyBrace='false'] //ForLoopStatement/BlockStatement[@CurlyBrace='false']
| |
//ForEachStatement/BlockStatement[@CurlyBrace='false'] //ForEachStatement/BlockStatement[@CurlyBrace='false']
]]> ]]>
</value> </value>
</property> </property>
</properties> </properties>

View File

@ -12,13 +12,14 @@ The Complexity ruleset contains rules that find problems related to code size or
since="5.5.0" since="5.5.0"
message="Deeply nested if..then statements are hard to read" message="Deeply nested if..then statements are hard to read"
class="net.sourceforge.pmd.lang.apex.rule.complexity.AvoidDeeplyNestedIfStmtsRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.AvoidDeeplyNestedIfStmtsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#AvoidDeeplyNestedIfStmts"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#avoiddeeplynestedifstmts">
<description> <description>
Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain. Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Foo { <![CDATA[
public class Foo {
public void bar(Integer x, Integer y, Integer z) { public void bar(Integer x, Integer y, Integer z) {
if (x>y) { if (x>y) {
if (y>z) { if (y>z) {
@ -37,20 +38,21 @@ Avoid creating deeply nested if-then statements since they are harder to read an
since="5.5.0" since="5.5.0"
message="Avoid long parameter lists." message="Avoid long parameter lists."
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveParameterListRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveParameterListRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#ExcessiveParameterList"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#excessiveparameterlist">
<description> <description>
Methods with numerous parameters are a challenge to maintain, especially if most of them share the Methods with numerous parameters are a challenge to maintain, especially if most of them share the
same datatype. These situations usually denote the need for new objects to wrap the numerous parameters. same datatype. These situations usually denote the need for new objects to wrap the numerous parameters.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[// too many arguments liable to be mixed up <![CDATA[
// too many arguments liable to be mixed up
public void addPerson(int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) { public void addPerson(int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) {
... // ...
} }
// preferred approach // preferred approach
public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) { public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
... // ...
} }
]]> ]]>
</example> </example>
@ -60,7 +62,7 @@ public void addPerson(Date birthdate, BodyMeasurements measurements, int ssn) {
since="5.5.0" since="5.5.0"
message="Avoid really long classes." message="Avoid really long classes."
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveClassLengthRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessiveClassLengthRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#ExcessiveClassLength"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#excessiveclasslength">
<description> <description>
Excessive class file lengths are usually indications that the class may be burdened with excessive Excessive class file lengths are usually indications that the class may be burdened with excessive
responsibilities that could be provided by external classes or functions. In breaking these methods responsibilities that could be provided by external classes or functions. In breaking these methods
@ -68,7 +70,8 @@ apart the code becomes more managable and ripe for reuse.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Foo { <![CDATA[
public class Foo {
public void bar1() { public void bar1() {
// 1000 lines of code // 1000 lines of code
} }
@ -86,11 +89,11 @@ apart the code becomes more managable and ripe for reuse.
</example> </example>
</rule> </rule>
<rule name="NcssMethodCount" <rule name="NcssMethodCount"
since="5.5.0" since="5.5.0"
message="The method ''{0}()'' has an NCSS line count of {1}" message="The method ''{0}()'' has an NCSS line count of {1}"
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssMethodCountRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssMethodCountRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#NcssMethodCount"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#ncssmethodcount">
<description> <description>
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm, of code for a given method. NCSS ignores comments, and counts actual statements. Using this algorithm,
@ -98,7 +101,8 @@ lines of code that are split are counted as one.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Foo extends Bar { <![CDATA[
public class Foo extends Bar {
//this method only has 1 NCSS lines //this method only has 1 NCSS lines
public Integer methd() { public Integer methd() {
super.methd(); super.methd();
@ -112,11 +116,11 @@ lines of code that are split are counted as one.
</example> </example>
</rule> </rule>
<rule name="NcssTypeCount" <rule name="NcssTypeCount"
since="5.5.0" since="5.5.0"
message="The type has an NCSS line count of {0}" message="The type has an NCSS line count of {0}"
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssTypeCountRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssTypeCountRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#NcssTypeCount"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#ncsstypecount">
<description> <description>
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm, of code for a given type. NCSS ignores comments, and counts actual statements. Using this algorithm,
@ -124,7 +128,8 @@ lines of code that are split are counted as one.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[//this class only has 6 NCSS lines <![CDATA[
//this class only has 6 NCSS lines
public class Foo extends Bar { public class Foo extends Bar {
public Foo() { public Foo() {
super(); super();
@ -137,13 +142,14 @@ public class Foo extends Bar {
} }
} }
]]> ]]>
</example></rule> </example>
</rule>
<rule name="NcssConstructorCount" <rule name="NcssConstructorCount"
since="5.5.0" since="5.5.0"
message="The constructor has an NCSS line count of {0}" message="The constructor has an NCSS line count of {0}"
class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssConstructorCountRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.NcssConstructorCountRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#NcssConstructorCount"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#ncssconstructorcount">
<description> <description>
This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines This rule uses the NCSS (Non-Commenting Source Statements) algorithm to determine the number of lines
of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm, of code for a given constructor. NCSS ignores comments, and counts actual statements. Using this algorithm,
@ -151,7 +157,8 @@ lines of code that are split are counted as one.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Foo extends Bar { <![CDATA[
public class Foo extends Bar {
//this constructor only has 1 NCSS lines //this constructor only has 1 NCSS lines
public Foo() { public Foo() {
super(); super();
@ -160,29 +167,28 @@ lines of code that are split are counted as one.
super.foo(); super.foo();
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="StdCyclomaticComplexity" <rule name="StdCyclomaticComplexity"
since="5.5.0" since="5.5.0"
message="The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}." message="The {0} ''{1}'' has a Standard Cyclomatic Complexity of {2}."
class="net.sourceforge.pmd.lang.apex.rule.complexity.StdCyclomaticComplexityRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.StdCyclomaticComplexityRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#StdCyclomaticComplexity"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#stdcyclomaticcomplexity">
<description> <description>
<![CDATA[
Complexity directly affects maintenance costs is determined by the number of decision points in a method Complexity directly affects maintenance costs is determined by the number of decision points in a method
plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls. plus one for the method entry. The decision points include 'if', 'while', 'for', and 'case labels' calls.
Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
high complexity, and 11+ is very high complexity. high complexity, and 11+ is very high complexity.
]]>
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[// This has a Cyclomatic Complexity = 12 <![CDATA[
public class Foo { // This has a Cyclomatic Complexity = 12
public class Foo {
1 public void example() { 1 public void example() {
2 if (a == b || (c == d && e == f)) { 2 if (a == b || (c == d && e == f)) {
3 if (a1 == b1) { 3 if (a1 == b1) {
@ -216,8 +222,7 @@ high complexity, and 11+ is very high complexity.
break; break;
} }
} }
} }
}
]]> ]]>
</example> </example>
</rule> </rule>
@ -226,7 +231,7 @@ high complexity, and 11+ is very high complexity.
since="5.5.0" since="5.5.0"
message="Too many fields" message="Too many fields"
class="net.sourceforge.pmd.lang.apex.rule.complexity.TooManyFieldsRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.TooManyFieldsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#TooManyFields"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#toomanyfields">
<description> <description>
Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields, Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields,
possibly through grouping related fields in new objects. For example, a class with individual possibly through grouping related fields in new objects. For example, a class with individual
@ -234,7 +239,8 @@ city/state/zip fields could park them within a single Address field.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Person { <![CDATA[
public class Person {
// too many separate fields // too many separate fields
int birthYear; int birthYear;
int birthMonth; int birthMonth;
@ -256,7 +262,7 @@ public class Person {
since="5.5.0" since="5.5.0"
message="This class has a bunch of public methods and attributes" message="This class has a bunch of public methods and attributes"
class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessivePublicCountRule" class="net.sourceforge.pmd.lang.apex.rule.complexity.ExcessivePublicCountRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/complexity.html#ExcessivePublicCount"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_complexity.html#excessivepubliccount">
<description> <description>
Classes with large numbers of public methods and attributes require disproportionate testing efforts Classes with large numbers of public methods and attributes require disproportionate testing efforts
since combinational side effects grow rapidly and increase risk. Refactoring these classes into since combinational side effects grow rapidly and increase risk. Refactoring these classes into
@ -265,7 +271,8 @@ developed easily.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Foo { <![CDATA[
public class Foo {
public String value; public String value;
public Bar something; public Bar something;
public Variable var; public Variable var;

View File

@ -14,7 +14,7 @@
since="6.0.0" since="6.0.0"
class="net.sourceforge.pmd.lang.apex.metrics.rule.CyclomaticComplexityRule" class="net.sourceforge.pmd.lang.apex.metrics.rule.CyclomaticComplexityRule"
metrics="true" metrics="true"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/metrics.html#CyclomaticComplexity"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_metrics.html#cyclomaticcomplexity">
<description> <description>
<![CDATA[ <![CDATA[
The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic

View File

@ -12,13 +12,14 @@ The Performance ruleset contains a collection of good practices which should be
since="5.5.0" since="5.5.0"
message="Avoid Soql queries inside loops" message="Avoid Soql queries inside loops"
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidSoqlInLoopsRule" class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidSoqlInLoopsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/performance.html#AvoidSoqlInLoops"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_performance.html#avoidsoqlinloops">
<description> <description>
New objects created within loops should be checked to see if they can created outside them and reused. New objects created within loops should be checked to see if they can created outside them and reused.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class Something { <![CDATA[
public class Something {
public static void main( String as[] ) { public static void main( String as[] ) {
for (Integer i = 0; i < 10; i++) { for (Integer i = 0; i < 10; i++) {
List<Account> accounts = [SELECT Id FROM Account]; List<Account> accounts = [SELECT Id FROM Account];
@ -33,8 +34,10 @@ New objects created within loops should be checked to see if they can created ou
since="5.5.0" since="5.5.0"
message="Avoid DML statements inside loops" message="Avoid DML statements inside loops"
class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidDmlStatementsInLoopsRule" class="net.sourceforge.pmd.lang.apex.rule.performance.AvoidDmlStatementsInLoopsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/performance.html#AvoidDmlStatementsInLoops"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_performance.html#avoiddmlstatementsinloops">
<description>Avoid DML statements inside loops to avoid hitting the DML governor limit. Instead, try to batch up the data into a list and invoke your DML once on that list of data outside the loop.</description> <description>
Avoid DML statements inside loops to avoid hitting the DML governor limit. Instead, try to batch up the data into a list and invoke your DML once on that list of data outside the loop.
</description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
@ -42,7 +45,7 @@ public class Something {
public void foo() { public void foo() {
for (Integer i = 0; i < 151; i++) { for (Integer i = 0; i < 151; i++) {
Account account; Account account;
... // ...
insert account; insert account;
} }
} }

View File

@ -2,4 +2,10 @@
# BSD-style license; for more info see http://pmd.sourceforge.net/license.html # BSD-style license; for more info see http://pmd.sourceforge.net/license.html
# #
rulesets.filenames=rulesets/apex/complexity.xml,rulesets/apex/performance.xml,rulesets/apex/style.xml,rulesets/apex/apexunit.xml,rulesets/apex/security.xml,rulesets/apex/braces.xml rulesets.filenames=\
rulesets/apex/apexunit.xml,\
rulesets/apex/braces.xml,\
rulesets/apex/complexity.xml,\
rulesets/apex/performance.xml,\
rulesets/apex/security.xml,\
rulesets/apex/style.xml

View File

@ -3,95 +3,99 @@
<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0" <ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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"> xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 http://pmd.sourceforge.net/ruleset_2_0_0.xsd">
<description> <description>
These rules deal with different security problems that can occur within Apex. These rules deal with different security problems that can occur within Apex.
</description> </description>
<rule name="ApexSharingViolations" since="5.5.3" <rule name="ApexSharingViolations"
since="5.5.3"
message="Apex classes should declare a sharing model if DML or SOQL/SOSL is used" message="Apex classes should declare a sharing model if DML or SOQL/SOSL is used"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSharingViolationsRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexSharingViolationsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexSharingViolations"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexsharingviolations">
<description> <description>
Detect classes declared without explicit sharing mode if DML methods are used. This Detect classes declared without explicit sharing mode if DML methods are used. This
forces the developer to take access restrictions into account before modifying objects. forces the developer to take access restrictions into account before modifying objects.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public without sharing class Foo { public without sharing class Foo {
// DML operation here // DML operation here
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexOpenRedirect" since="5.5.3" <rule name="ApexOpenRedirect"
since="5.5.3"
message="Apex classes should safely redirect to a known location" message="Apex classes should safely redirect to a known location"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexOpenRedirectRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexOpenRedirectRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexOpenRedirect"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexopenredirect">
<description> <description>
Checks against redirects to user-controlled locations. This prevents attackers from Checks against redirects to user-controlled locations. This prevents attackers from
redirecting users to phishing sites. redirecting users to phishing sites.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public without sharing class Foo { public without sharing class Foo {
String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param'); String unsafeLocation = ApexPage.getCurrentPage().getParameters.get('url_param');
PageReference page() { PageReference page() {
return new PageReference(unsafeLocation); return new PageReference(unsafeLocation);
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexInsecureEndpoint"
<rule name="ApexInsecureEndpoint" since="5.5.3" since="5.5.3"
message="Apex callouts should use encrypted communication channels" message="Apex callouts should use encrypted communication channels"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexInsecureEndpointRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexInsecureEndpointRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexInsecureEndpoint"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexinsecureendpoint">
<description> <description>
Checks against accessing endpoints under plain **http**. You should always use Checks against accessing endpoints under plain **http**. You should always use
**https** for security. **https** for security.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public without sharing class Foo { public without sharing class Foo {
void foo() { void foo() {
HttpRequest req = new HttpRequest(); HttpRequest req = new HttpRequest();
req.setEndpoint('http://localhost:com'); req.setEndpoint('http://localhost:com');
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexXSSFromURLParam" since="5.5.3" <rule name="ApexXSSFromURLParam"
since="5.5.3"
message="Apex classes should escape/sanitize Strings obtained from URL parameters" message="Apex classes should escape/sanitize Strings obtained from URL parameters"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromURLParamRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromURLParamRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexXSSFromURLParam"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexxssfromurlparam">
<description> <description>
Makes sure that all values obtained from URL parameters are properly escaped / sanitized Makes sure that all values obtained from URL parameters are properly escaped / sanitized
to avoid XSS attacks. to avoid XSS attacks.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public without sharing class Foo { public without sharing class Foo {
String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param'); String unescapedstring = ApexPage.getCurrentPage().getParameters.get('url_param');
String usedLater = unescapedstring; String usedLater = unescapedstring;
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexXSSFromEscapeFalse"
<rule name="ApexXSSFromEscapeFalse" since="5.5.3" since="5.5.3"
message="Apex classes should escape Strings in error messages" message="Apex classes should escape Strings in error messages"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromEscapeFalseRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexXSSFromEscapeFalseRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexXSSFromEscapeFalse"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexxssfromescapefalse">
<description> <description>
Reports on calls to `addError` with disabled escaping. The message passed to `addError` Reports on calls to `addError` with disabled escaping. The message passed to `addError`
will be displayed directly to the user in the UI, making it prime ground for XSS will be displayed directly to the user in the UI, making it prime ground for XSS
@ -99,47 +103,48 @@ attacks if unescaped.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public without sharing class Foo { public without sharing class Foo {
Trigger.new[0].addError(vulnerableHTMLGoesHere, false); Trigger.new[0].addError(vulnerableHTMLGoesHere, false);
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexBadCrypto" since="5.5.3" <rule name="ApexBadCrypto"
since="5.5.3"
message="Apex classes should use random IV/key" message="Apex classes should use random IV/key"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexBadCryptoRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexBadCryptoRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexBadCrypto"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexbadcrypto">
<description> <description>
The rule makes sure you are using randomly generated IVs and keys for `Crypto` calls. The rule makes sure you are using randomly generated IVs and keys for `Crypto` calls.
Hard-wiring these values greatly compromises the security of encrypted data. Hard-wiring these values greatly compromises the security of encrypted data.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public without sharing class Foo { public without sharing class Foo {
Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123'); Blob hardCodedIV = Blob.valueOf('Hardcoded IV 123');
Blob hardCodedKey = Blob.valueOf('0000000000000000'); Blob hardCodedKey = Blob.valueOf('0000000000000000');
Blob data = Blob.valueOf('Data to be encrypted'); Blob data = Blob.valueOf('Data to be encrypted');
Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data); Blob encrypted = Crypto.encrypt('AES128', hardCodedKey, hardCodedIV, data);
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexCSRF"
<rule name="ApexCSRF" since="5.5.3" since="5.5.3"
message="Avoid making DML operations in Apex class constructor/init method" message="Avoid making DML operations in Apex class constructor/init method"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCSRFRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexCSRFRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexCSRF"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexcsrf">
<description> <description>
Check to avoid making DML operations in Apex class constructor/init method. This prevents Check to avoid making DML operations in Apex class constructor/init method. This prevents
modification of the database just by accessing a page. modification of the database just by accessing a page.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public class Foo { public class Foo {
public init() { public init() {
insert data; insert data;
@ -149,33 +154,35 @@ public class Foo {
insert data; insert data;
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexSOQLInjection" since="5.5.3" <rule name="ApexSOQLInjection"
since="5.5.3"
message="Avoid untrusted/unescaped variables in DML query" message="Avoid untrusted/unescaped variables in DML query"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSOQLInjectionRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexSOQLInjectionRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexSOQLInjection"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexsoqlinjection">
<description> <description>
Detects the usage of untrusted / unescaped variables in DML queries. Detects the usage of untrusted / unescaped variables in DML queries.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public class Foo { public class Foo {
public void test1(String t1) { public void test1(String t1) {
Database.query('SELECT Id FROM Account' + t1); Database.query('SELECT Id FROM Account' + t1);
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexCRUDViolation" since="5.5.3" <rule name="ApexCRUDViolation"
since="5.5.3"
message="Validate CRUD permission before SOQL/DML operation" message="Validate CRUD permission before SOQL/DML operation"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexCRUDViolationRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexCRUDViolationRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexCRUDViolationRule"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexcrudviolation">
<description> <description>
The rule validates you are checking for access permissions before a SOQL/SOSL/DML operation. The rule validates you are checking for access permissions before a SOQL/SOSL/DML operation.
Since Apex runs in system mode not having proper permissions checks results in escalation of Since Apex runs in system mode not having proper permissions checks results in escalation of
@ -183,7 +190,7 @@ privilege and may produce runtime errors. This check forces you to handle such s
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public class Foo { public class Foo {
public Contact foo(String status, String ID) { public Contact foo(String status, String ID) {
Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID]; Contact c = [SELECT Status__c FROM Contact WHERE Id=:ID];
@ -198,14 +205,15 @@ public class Foo {
return c; return c;
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexDangerousMethods" since="5.5.3" <rule name="ApexDangerousMethods"
since="5.5.3"
message="Calling potentially dangerous method" message="Calling potentially dangerous method"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexDangerousMethodsRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexDangerousMethodsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexDangerousMethodsRule"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexdangerousmethods">
<description><![CDATA[ <description><![CDATA[
Checks against calling dangerous methods. Checks against calling dangerous methods.
@ -215,23 +223,25 @@ For the time being, it reports:
opens the door to several attacks and requires manual validation, which is unreliable. opens the door to several attacks and requires manual validation, which is unreliable.
* Calling `System.debug` passing sensitive data as parameter, which could lead to exposure * Calling `System.debug` passing sensitive data as parameter, which could lead to exposure
of private data. of private data.
]]></description> ]]>
</description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public class Foo { public class Foo {
public Foo() { public Foo() {
Configuration.disableTriggerCRUDSecurity(); Configuration.disableTriggerCRUDSecurity();
} }
} }
]]> ]]>
</example> </example>
</rule> </rule>
<rule name="ApexSuggestUsingNamedCred" since="5.5.3" <rule name="ApexSuggestUsingNamedCred"
since="5.5.3"
message="Suggest named credentials for authentication" message="Suggest named credentials for authentication"
class="net.sourceforge.pmd.lang.apex.rule.security.ApexSuggestUsingNamedCredRule" class="net.sourceforge.pmd.lang.apex.rule.security.ApexSuggestUsingNamedCredRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/security.html#ApexSuggestUsingNamedCredRule"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_security.html#apexsuggestusingnamedcred">
<description><![CDATA[ <description><![CDATA[
Detects hardcoded credentials used in requests to an endpoint. Detects hardcoded credentials used in requests to an endpoint.
@ -246,10 +256,11 @@ You should refrain from hardcoding credentials:
Instead, you should use *Named Credentials* and a callout endpoint. Instead, you should use *Named Credentials* and a callout endpoint.
For more information, you can check [this](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials.htm) For more information, you can check [this](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_named_credentials.htm)
]]></description> ]]>
</description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[ <![CDATA[
public class Foo { public class Foo {
public void foo(String username, String password) { public void foo(String username, String password) {
Blob headerValue = Blob.valueOf(username + ':' + password); Blob headerValue = Blob.valueOf(username + ':' + password);
@ -261,5 +272,4 @@ public class Foo {
</example> </example>
</rule> </rule>
</ruleset> </ruleset>

View File

@ -12,7 +12,7 @@ The Style Ruleset contains rules regarding preferred usage of names and identifi
since="5.5.0" since="5.5.0"
message="{0} variable {1} should begin with {2}" message="{0} variable {1} should begin with {2}"
class="net.sourceforge.pmd.lang.apex.rule.style.VariableNamingConventionsRule" class="net.sourceforge.pmd.lang.apex.rule.style.VariableNamingConventionsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#VariableNamingConventions"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#variablenamingconventions">
<description> <description>
A variable naming conventions rule - customize this to your liking. Currently, it A variable naming conventions rule - customize this to your liking. Currently, it
checks for final variables that should be fully capitalized and non-final variables checks for final variables that should be fully capitalized and non-final variables
@ -20,7 +20,8 @@ that should not include underscores.
</description> </description>
<priority>1</priority> <priority>1</priority>
<example> <example>
<![CDATA[public class Foo { <![CDATA[
public class Foo {
public static final Integer MY_NUM = 0; public static final Integer MY_NUM = 0;
public String myTest = ''; public String myTest = '';
DataModule dmTest = new DataModule(); DataModule dmTest = new DataModule();
@ -33,13 +34,14 @@ that should not include underscores.
since="5.5.0" since="5.5.0"
message="Method name does not begin with a lower case character." message="Method name does not begin with a lower case character."
class="net.sourceforge.pmd.lang.apex.rule.style.MethodNamingConventionsRule" class="net.sourceforge.pmd.lang.apex.rule.style.MethodNamingConventionsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#MethodNamingConventions"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#methodnamingconventions">
<description> <description>
Method names should always begin with a lower case character, and should not contain underscores. Method names should always begin with a lower case character, and should not contain underscores.
</description> </description>
<priority>1</priority> <priority>1</priority>
<example> <example>
<![CDATA[public class Foo { <![CDATA[
public class Foo {
public void fooStuff() { public void fooStuff() {
} }
} }
@ -51,13 +53,14 @@ Method names should always begin with a lower case character, and should not con
since="5.5.0" since="5.5.0"
message="Class names should begin with an uppercase character" message="Class names should begin with an uppercase character"
class="net.sourceforge.pmd.lang.apex.rule.style.ClassNamingConventionsRule" class="net.sourceforge.pmd.lang.apex.rule.style.ClassNamingConventionsRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#ClassNamingConventions"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#classnamingconventions">
<description> <description>
Class names should always begin with an upper case character. Class names should always begin with an upper case character.
</description> </description>
<priority>1</priority> <priority>1</priority>
<example> <example>
<![CDATA[public class Foo {} <![CDATA[
public class Foo {}
]]> ]]>
</example> </example>
</rule> </rule>
@ -66,13 +69,14 @@ Class names should always begin with an upper case character.
since="5.5.0" since="5.5.0"
message="Classes should not have non-constructor methods with the same name as the class" message="Classes should not have non-constructor methods with the same name as the class"
class="net.sourceforge.pmd.lang.apex.rule.style.MethodWithSameNameAsEnclosingClassRule" class="net.sourceforge.pmd.lang.apex.rule.style.MethodWithSameNameAsEnclosingClassRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#MethodWithSameNameAsEnclosingClass"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#methodwithsamenameasenclosingclass">
<description> <description>
Non-constructor methods should not have the same name as the enclosing class. Non-constructor methods should not have the same name as the enclosing class.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[public class MyClass { <![CDATA[
public class MyClass {
// this is OK because it is a constructor // this is OK because it is a constructor
public MyClass() {} public MyClass() {}
// this is bad because it is a method // this is bad because it is a method
@ -86,7 +90,7 @@ Non-constructor methods should not have the same name as the enclosing class.
since="5.5.0" since="5.5.0"
message="Avoid logic in triggers" message="Avoid logic in triggers"
class="net.sourceforge.pmd.lang.apex.rule.style.AvoidLogicInTriggerRule" class="net.sourceforge.pmd.lang.apex.rule.style.AvoidLogicInTriggerRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#AvoidLogicInTrigger"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#avoidlogicintrigger">
<description> <description>
As triggers do not allow methods like regular classes they are less flexible and suited to apply good encapsulation style. As triggers do not allow methods like regular classes they are less flexible and suited to apply good encapsulation style.
Therefore delegate the triggers work to a regular class (often called Trigger handler class). Therefore delegate the triggers work to a regular class (often called Trigger handler class).
@ -95,16 +99,17 @@ See more here: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[trigger Accounts on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) { <![CDATA[
trigger Accounts on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
for(Account acc : Trigger.new) { for(Account acc : Trigger.new) {
if(Trigger.isInsert) { if(Trigger.isInsert) {
... // ...
} }
... // ...
if(Trigger.isDelete) { if(Trigger.isDelete) {
... // ...
} }
} }
} }
@ -116,14 +121,15 @@ See more here: https://developer.salesforce.com/page/Trigger_Frameworks_and_Apex
since="5.5.0" since="5.5.0"
message="Avoid using global modifier" message="Avoid using global modifier"
class="net.sourceforge.pmd.lang.apex.rule.style.AvoidGlobalModifierRule" class="net.sourceforge.pmd.lang.apex.rule.style.AvoidGlobalModifierRule"
externalInfoUrl="${pmd.website.baseurl}/rules/apex/style.html#AvoidGlobalModifier"> externalInfoUrl="${pmd.website.baseurl}/pmd_rules_apex_style.html#avoidglobalmodifier">
<description> <description>
Global classes should be avoided (especially in managed packages) as they can never be deleted or changed in signature. Always check twice if something needs to be global. Global classes should be avoided (especially in managed packages) as they can never be deleted or changed in signature. Always check twice if something needs to be global.
Many interfaces (e.g. Batch) required global modifiers in the past but don't require this anymore. Don't lock yourself in. Many interfaces (e.g. Batch) required global modifiers in the past but don't require this anymore. Don't lock yourself in.
</description> </description>
<priority>3</priority> <priority>3</priority>
<example> <example>
<![CDATA[global class Unchangeable { <![CDATA[
global class Unchangeable {
global UndeletableType unchangable(UndeletableType param) { global UndeletableType unchangable(UndeletableType param) {
// ... // ...
} }

View File

@ -0,0 +1,15 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.apex;
import net.sourceforge.pmd.AbstractRuleSetFactoryTest;
import net.sourceforge.pmd.lang.apex.rule.ApexXPathRule;
public class RuleSetFactoryTest extends AbstractRuleSetFactoryTest {
public RuleSetFactoryTest() {
super();
validXPathClassNames.add(ApexXPathRule.class.getName());
}
}

View File

@ -17,10 +17,13 @@ import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Properties; import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
@ -49,6 +52,12 @@ public abstract class AbstractRuleSetFactoryTest {
private static ValidateDefaultHandler validateDefaultHandlerDtd; private static ValidateDefaultHandler validateDefaultHandlerDtd;
private static SAXParser saxParser; private static SAXParser saxParser;
protected Set<String> validXPathClassNames = new HashSet<>();
public AbstractRuleSetFactoryTest() {
validXPathClassNames.add(XPathRule.class.getName());
}
/** /**
* Setups the XML parser with validation. * Setups the XML parser with validation.
* *
@ -134,7 +143,7 @@ public abstract class AbstractRuleSetFactoryTest {
String expectedClassName = "net.sourceforge.pmd.lang." + language.getTerseName() + ".rule." + group String expectedClassName = "net.sourceforge.pmd.lang." + language.getTerseName() + ".rule." + group
+ "." + rule.getName() + "Rule"; + "." + rule.getName() + "Rule";
if (!rule.getRuleClass().equals(expectedClassName) if (!rule.getRuleClass().equals(expectedClassName)
&& !rule.getRuleClass().equals(XPathRule.class.getName())) { && !validXPathClassNames.contains(rule.getRuleClass())) {
invalidClassName++; invalidClassName++;
messages += "Rule " + fileName + "/" + rule.getName() + " seems to have an invalid 'class' value (" messages += "Rule " + fileName + "/" + rule.getName() + " seems to have an invalid 'class' value ("
+ rule.getRuleClass() + "), it should be:" + expectedClassName + PMD.EOL; + rule.getRuleClass() + "), it should be:" + expectedClassName + PMD.EOL;