diff --git a/builder/pom.xml b/builder/pom.xml
index 1d0ffbf..73294ba 100644
--- a/builder/pom.xml
+++ b/builder/pom.xml
@@ -42,6 +42,8 @@
2.3.5
1.0.0
4.3.0
+ 7.8
+ 1.24.0
@@ -92,6 +94,19 @@
${map-builder.version}
test
+
+
+ com.puppycrawl.tools
+ checkstyle
+ ${checkstyle.version}
+ compile
+
+
+ com.github.sevntu-checkstyle
+ sevntu-checks
+ ${sevntu.version}
+
+
diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleClassNotFoundException.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleClassNotFoundException.java
new file mode 100644
index 0000000..ffa297c
--- /dev/null
+++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleClassNotFoundException.java
@@ -0,0 +1,39 @@
+/**
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Paul Campbell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.kemitix.checkstyle.ruleset.builder;
+
+/**
+ * Raised when a Class to implement a Rule is not found.
+ *
+ * @author Paul Campbell (pcampbell@kemitix.net).
+ */
+public class CheckstyleClassNotFoundException extends RuntimeException {
+
+ /**
+ * Constructor.
+ *
+ * @param name the name of the unimplemented rule
+ */
+ public CheckstyleClassNotFoundException(final String name) {
+ super("No class found to implement " + name);
+ }
+}
diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleSourceLoadException.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleSourceLoadException.java
new file mode 100644
index 0000000..ef9b959
--- /dev/null
+++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleSourceLoadException.java
@@ -0,0 +1,42 @@
+/**
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Paul Campbell
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies
+ * or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
+ * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
+ * AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+package net.kemitix.checkstyle.ruleset.builder;
+
+import java.io.IOException;
+
+/**
+ * Raised when there is an error scanning for check classes.
+ *
+ * @author Paul Campbell (pcampbell@kemitix.net).
+ */
+public class CheckstyleSourceLoadException extends RuntimeException {
+
+ /**
+ * Constructor.
+ *
+ * @param basePackage the base package classes were being loaded from
+ * @param cause the cause
+ */
+ public CheckstyleSourceLoadException(final String basePackage, final IOException cause) {
+ super("Error loading checkstyle rules from package: " + basePackage, cause);
+ }
+}
diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java
index 0619a7d..5e3558a 100644
--- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java
+++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriter.java
@@ -101,9 +101,9 @@ class CheckstyleWriter implements CommandLineRunner {
private String formatRuleAsModule(final Rule rule) {
if (rule.getProperties()
.isEmpty()) {
- return String.format("", rule.getName());
+ return String.format("", rule.getCanonicalClassName());
}
- return String.format("%n %s%n", rule.getName(),
+ return String.format("%n %s%n", rule.getCanonicalClassName(),
formatProperties(rule.getProperties())
);
}
diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java
index 6e6798e..70f9ae7 100644
--- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java
+++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/Rule.java
@@ -40,6 +40,11 @@ public class Rule {
private static final Locale LOCALE = Locale.ENGLISH;
+ /**
+ * Configuration properties.
+ */
+ private final Map properties = new HashMap<>();
+
/**
* The name of the rule's Check class.
*/
@@ -80,11 +85,6 @@ public class Rule {
*/
private String reason;
- /**
- * Configuration properties.
- */
- private final Map properties = new HashMap<>();
-
/**
* Compare two Rules lexicographically for sorting by rule name, ignoring case.
*
@@ -104,4 +104,21 @@ public class Rule {
return getName().toLowerCase(LOCALE);
}
+ /**
+ * Returns the canonical name of the class that implements this rule.
+ *
+ * @return the canonical name of the implementing class
+ */
+ public String getCanonicalClassName() {
+ return source.getCheckClasses()
+ .filter(this::byRuleName)
+ .findFirst()
+ .orElseThrow(() -> new CheckstyleClassNotFoundException(name));
+ }
+
+ private boolean byRuleName(final String classname) {
+ final String classNameWithDelimiter = "." + name;
+ return classname.endsWith(classNameWithDelimiter) || classname.endsWith(classNameWithDelimiter + "Check");
+ }
+
}
diff --git a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/RuleSource.java b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/RuleSource.java
index d675310..e10cb95 100644
--- a/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/RuleSource.java
+++ b/builder/src/main/java/net/kemitix/checkstyle/ruleset/builder/RuleSource.java
@@ -21,6 +21,14 @@
package net.kemitix.checkstyle.ruleset.builder;
+import com.google.common.reflect.ClassPath;
+import lombok.Getter;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
/**
* The origin of the rule.
*
@@ -28,6 +36,34 @@ package net.kemitix.checkstyle.ruleset.builder;
*/
public enum RuleSource {
- CHECKSTYLE,
- SEVNTU,
+ CHECKSTYLE("com.puppycrawl.tools.checkstyle"),
+ SEVNTU("com.github.sevntu.checkstyle.checks");
+
+ @Getter
+ private final String basePackage;
+
+ private final List checkClasses;
+
+ /**
+ * Constructor.
+ *
+ * @param basePackage the base package that contains all checks from this source
+ */
+ RuleSource(final String basePackage) {
+ this.basePackage = basePackage;
+ try {
+ checkClasses = ClassPath.from(getClass().getClassLoader())
+ .getTopLevelClassesRecursive(basePackage)
+ .stream()
+ .map(ClassPath.ClassInfo::getName)
+ .collect(Collectors.toList());
+ } catch (IOException e) {
+ throw new CheckstyleSourceLoadException(basePackage, e);
+ }
+ }
+
+ public Stream getCheckClasses() {
+ return checkClasses.stream()
+ .sorted();
+ }
}
diff --git a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleClassNotFoundExceptionTest.java b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleClassNotFoundExceptionTest.java
new file mode 100644
index 0000000..eadf0a5
--- /dev/null
+++ b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleClassNotFoundExceptionTest.java
@@ -0,0 +1,24 @@
+package net.kemitix.checkstyle.ruleset.builder;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Tests for {@link CheckstyleClassNotFoundException}.
+ *
+ * @author Paul Campbell (pcampbell@kemitix.net).
+ */
+public class CheckstyleClassNotFoundExceptionTest {
+
+ @Test
+ public void canRaiseException() {
+ //given
+ final String classname = "class name";
+ //when
+ final CheckstyleClassNotFoundException exception = new CheckstyleClassNotFoundException(classname);
+ //then
+ assertThat(exception.getMessage()).startsWith("No class found to implement ")
+ .endsWith(classname);
+ }
+}
diff --git a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleSourceLoadExceptionTest.java b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleSourceLoadExceptionTest.java
new file mode 100644
index 0000000..cb3d1b1
--- /dev/null
+++ b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleSourceLoadExceptionTest.java
@@ -0,0 +1,28 @@
+package net.kemitix.checkstyle.ruleset.builder;
+
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
+
+/**
+ * Tests for {@link CheckstyleSourceLoadException}.
+ *
+ * @author Paul Campbell (pcampbell@kemitix.net).
+ */
+public class CheckstyleSourceLoadExceptionTest {
+
+ @Test
+ public void canRaiseException() {
+ //given
+ final String basePackage = "base package";
+ final IOException cause = new IOException();
+ //when
+ final CheckstyleSourceLoadException exception = new CheckstyleSourceLoadException(basePackage, cause);
+ //then
+ assertThat(exception).hasCause(cause)
+ .hasMessageStartingWith("Error loading checkstyle rules from package: ")
+ .hasMessageEndingWith(basePackage);
+ }
+}
diff --git a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java
index da7d873..4c7547b 100644
--- a/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java
+++ b/builder/src/test/java/net/kemitix/checkstyle/ruleset/builder/CheckstyleWriterTest.java
@@ -17,7 +17,6 @@ import java.nio.file.StandardOpenOption;
import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
-import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
@@ -42,6 +41,8 @@ public class CheckstyleWriterTest {
private String ruleName;
+ private String ruleClassname;
+
private Map outputFiles;
private Path outputDirectory;
@@ -57,8 +58,8 @@ public class CheckstyleWriterTest {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- ruleName = UUID.randomUUID()
- .toString();
+ ruleName = "RegexpOnFilename";
+ ruleClassname = "com.puppycrawl.tools.checkstyle.checks.regexp.RegexpOnFilenameCheck";
outputProperties = new OutputProperties();
outputFiles = new MapBuilder().put(getOutputFile(RuleLevel.LAYOUT))
.put(getOutputFile(RuleLevel.NAMING))
@@ -91,7 +92,7 @@ public class CheckstyleWriterTest {
checkstyleWriter.run();
//then
val lines = loadOutputFile(RuleLevel.LAYOUT);
- assertThat(lines).containsExactly("C:", String.format("TW:", ruleName));
+ assertThat(lines).containsExactly("C:", String.format("TW:", ruleClassname));
}
// write rule that is below current level
@@ -105,7 +106,7 @@ public class CheckstyleWriterTest {
checkstyleWriter.run();
//then
val lines = loadOutputFile(RuleLevel.NAMING);
- assertThat(lines).containsExactly("C:", String.format("TW:", ruleName));
+ assertThat(lines).containsExactly("C:", String.format("TW:", ruleClassname));
}
// write rule with checker parent
@@ -119,7 +120,7 @@ public class CheckstyleWriterTest {
checkstyleWriter.run();
//then
val lines = loadOutputFile(RuleLevel.LAYOUT);
- assertThat(lines).containsExactly(String.format("C:", ruleName), "TW:");
+ assertThat(lines).containsExactly(String.format("C:", ruleClassname), "TW:");
}
// write rule with properties
@@ -135,7 +136,7 @@ public class CheckstyleWriterTest {
checkstyleWriter.run();
//then
val lines = loadOutputFile(RuleLevel.LAYOUT);
- assertThat(lines).containsExactly("C:", String.format("TW:", ruleName),
+ assertThat(lines).containsExactly("C:", String.format("TW:", ruleClassname),
" ", ""
);
}
@@ -207,6 +208,7 @@ public class CheckstyleWriterTest {
private Rule enabledRule(final RuleLevel level, final RuleParent parent) {
val rule = new Rule();
rule.setName(ruleName);
+ rule.setSource(RuleSource.CHECKSTYLE);
rule.setEnabled(true);
rule.setLevel(level);
rule.setParent(parent);
diff --git a/ruleset/src/main/resources/net/kemitix/checkstyle-1-layout.xml b/ruleset/src/main/resources/net/kemitix/checkstyle-1-layout.xml
index c7c3f72..7dd6341 100644
--- a/ruleset/src/main/resources/net/kemitix/checkstyle-1-layout.xml
+++ b/ruleset/src/main/resources/net/kemitix/checkstyle-1-layout.xml
@@ -4,62 +4,63 @@
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
+
-
-
+
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/ruleset/src/main/resources/net/kemitix/checkstyle-2-naming.xml b/ruleset/src/main/resources/net/kemitix/checkstyle-2-naming.xml
index 040fe94..8388113 100644
--- a/ruleset/src/main/resources/net/kemitix/checkstyle-2-naming.xml
+++ b/ruleset/src/main/resources/net/kemitix/checkstyle-2-naming.xml
@@ -4,94 +4,95 @@
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
+
-
-
+
+
-
+
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruleset/src/main/resources/net/kemitix/checkstyle-3-javadoc.xml b/ruleset/src/main/resources/net/kemitix/checkstyle-3-javadoc.xml
index 811e021..4b469d9 100644
--- a/ruleset/src/main/resources/net/kemitix/checkstyle-3-javadoc.xml
+++ b/ruleset/src/main/resources/net/kemitix/checkstyle-3-javadoc.xml
@@ -4,120 +4,121 @@
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruleset/src/main/resources/net/kemitix/checkstyle-4-tweaks.xml b/ruleset/src/main/resources/net/kemitix/checkstyle-4-tweaks.xml
index 2e27c90..a6ad5cc 100644
--- a/ruleset/src/main/resources/net/kemitix/checkstyle-4-tweaks.xml
+++ b/ruleset/src/main/resources/net/kemitix/checkstyle-4-tweaks.xml
@@ -4,179 +4,180 @@
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml b/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml
index bc2b68b..f486e8c 100644
--- a/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml
+++ b/ruleset/src/main/resources/net/kemitix/checkstyle-5-complexity.xml
@@ -4,232 +4,233 @@
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
-
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
+
-
-
-
-
+
+
+
+
-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+