Skip to content

Commit

Permalink
gaul#64 new option to ignore by class FQN regexp
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Vorburger <mike@vorburger.ch>
Signed-off-by: Michael Vorburger <vorburger@redhat.com>
  • Loading branch information
vorburger committed Feb 13, 2018
1 parent 0c2e29a commit 6d325ee
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 22 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@ The `<configuration>` stanza can contain several elements:
* `<violationsFiles>` user-specified violations file. The latter files override violations from the former ones, including `violationsFile` and the default violations. Can point to classpath using absolute paths, e.g. `classpath:/your/file.xml`.
* `<exclusionsFile>` disables user-specified violations. This is a text file with one exclusion per line in the javap format: `java/lang/String.getBytes:(Ljava/lang/String;)[B`.
* `<exclusions>` violations to disable. Each exclusion should be in the javap format: `java/lang/String.getBytes:(Ljava/lang/String;)[B`.
* `<exclusionPatterns>` violation patterns to disable. Each exclusion should be a regular expression that matches the javap format: `java/lang/.*`.
* `<exclusionPatterns>` violation patterns to disable, specified using `<exclusionPattern>` child elements. Each exclusion should be a regular expression that matches the javap format: `java/lang/.*` of a violation.
* `<ignorePackages>` package prefixes to ignore, specified using `<ignorePackage>` child elements. Specifying `foo.bar` subsequently ignores `foo.bar.*`, `foo.bar.baz.*` and so on.
* `<ignoreClassNamePatterns>` full qualified class names (incl. package) to ignore, specified using `<ignoreClassNamePattern>` child elements. Each exclusion should be a regular expression that matches a package and/or class; the package will be / not . separated (ASM's format).

To run Modernizer during the verify phase of your build, add the following to
the modernizer `<plugin>` stanza in your pom.xml:
Expand Down
31 changes: 28 additions & 3 deletions src/main/java/org/gaul/modernizer_maven_plugin/Modernizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,13 @@ final class Modernizer {
private final Collection<String> exclusions;
private final Collection<Pattern> exclusionPatterns;
private final Collection<String> ignorePackages;
private final Collection<Pattern> ignoreFullClassNamePatterns;

Modernizer(String javaVersion, Map<String, Violation> violations,
Collection<String> exclusions,
Collection<Pattern> exclusionPatterns,
Collection<String> ignorePackages) {
Collection<String> ignorePackages,
Collection<Pattern> ignoreClassNamePatterns) {
long version;
if (javaVersion.startsWith("1.")) {
version = Long.parseLong(javaVersion.substring(2));
Expand All @@ -65,13 +67,15 @@ final class Modernizer {
this.exclusions = Utils.createImmutableSet(exclusions);
this.exclusionPatterns = Utils.createImmutableSet(exclusionPatterns);
this.ignorePackages = Utils.createImmutableSet(ignorePackages);
this.ignoreFullClassNamePatterns
= Utils.createImmutableSet(ignoreClassNamePatterns);
}

Collection<ViolationOccurrence> check(ClassReader classReader)
throws IOException {
ModernizerClassVisitor classVisitor = new ModernizerClassVisitor(
javaVersion, violations, exclusions, exclusionPatterns,
ignorePackages);
ignorePackages, ignoreFullClassNamePatterns);
classReader.accept(classVisitor, 0);
return classVisitor.getOccurrences();
}
Expand Down Expand Up @@ -121,32 +125,41 @@ final class ModernizerClassVisitor extends ClassVisitor {
private final Collection<String> exclusions;
private final Collection<Pattern> exclusionPatterns;
private final Collection<String> ignorePackages;
private final Collection<Pattern> ignoreFullClassNamePatterns;
private final Collection<ViolationOccurrence> occurrences =
new ArrayList<ViolationOccurrence>();
private String packageName;
private String className;

ModernizerClassVisitor(long javaVersion,
Map<String, Violation> violations, Collection<String> exclusions,
Collection<Pattern> exclusionPatterns,
Collection<String> ignorePackages) {
Collection<String> ignorePackages,
Collection<Pattern> ignoreFullClassNamePatterns) {
super(Opcodes.ASM5);
Utils.checkArgument(javaVersion >= 0);
this.javaVersion = javaVersion;
this.violations = Utils.checkNotNull(violations);
this.exclusions = Utils.checkNotNull(exclusions);
this.exclusionPatterns = Utils.checkNotNull(exclusionPatterns);
this.ignorePackages = Utils.checkNotNull(ignorePackages);
this.ignoreFullClassNamePatterns =
Utils.checkNotNull(ignoreFullClassNamePatterns);
}

@Override
public void visit(int version, int access, String name, String signature,
String superName, String[] interfaces) {
className = name;
if (name.contains("/")) {
packageName = name.substring(0, name.lastIndexOf('/'))
.replace('/', '.');
} else {
packageName = "";
}
if (ignoreClass()) {
return;
}
for (String itr : interfaces) {
Violation violation = violations.get(itr);
checkToken(itr, violation, name, /*lineNumber=*/ -1);
Expand Down Expand Up @@ -210,6 +223,9 @@ private void checkToken(String token, Violation violation, String name,
if (violation != null && !exclusions.contains(token) &&
javaVersion >= violation.getVersion() &&
!ignorePackages.contains(packageName)) {
if (ignoreClass()) {
return;
}
for (Pattern pattern : exclusionPatterns) {
if (pattern.matcher(token).matches()) {
return;
Expand All @@ -225,6 +241,15 @@ private void checkToken(String token, Violation violation, String name,
}
}

private boolean ignoreClass() {
for (Pattern pattern : ignoreFullClassNamePatterns) {
if (pattern.matcher(className).matches()) {
return true;
}
}
return false;
}

Collection<ViolationOccurrence> getOccurrences() {
return occurrences;
}
Expand Down
41 changes: 31 additions & 10 deletions src/main/java/org/gaul/modernizer_maven_plugin/ModernizerMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,16 +76,16 @@ public final class ModernizerMojo extends AbstractMojo {
* 1.2 but not when targeting Java 1.1.
*/
@Parameter(required = true, property = "modernizer.javaVersion")
private String javaVersion = null;
private String javaVersion;

/** Fail phase if Modernizer detects any violations. */
@Parameter(defaultValue = "true", property = "modernizer.failOnViolations")
private boolean failOnViolations = true;
protected boolean failOnViolations = true;

/** Run Modernizer on test classes. */
@Parameter(defaultValue = "true",
property = "modernizer.includeTestClasses")
private boolean includeTestClasses = true;
protected boolean includeTestClasses = true;

/**
* User-specified violation file. Also disables standard violation checks.
Expand All @@ -96,7 +96,7 @@ public final class ModernizerMojo extends AbstractMojo {
* for the default violations file.
*/
@Parameter(property = "modernizer.violationsFile")
private String violationsFile = "classpath:/modernizer.xml";
protected String violationsFile = "classpath:/modernizer.xml";

/**
* User-specified violation files. The violations loaded from
Expand All @@ -111,7 +111,7 @@ public final class ModernizerMojo extends AbstractMojo {
* for the default violations file.
*/
@Parameter(property = "modernizer.violationsFiles")
private List<String> violationsFiles = emptyList();
protected List<String> violationsFiles = emptyList();

/**
* Disables user-specified violations. This is a text file with one
Expand All @@ -120,7 +120,7 @@ public final class ModernizerMojo extends AbstractMojo {
* java/lang/String.getBytes:(Ljava/lang/String;)[B.
*/
@Parameter(property = "modernizer.exclusionsFile")
private String exclusionsFile = null;
private String exclusionsFile;

/**
* Log level to emit violations at, e.g., error, warn, info, debug.
Expand All @@ -135,7 +135,7 @@ public final class ModernizerMojo extends AbstractMojo {
* java/lang/String.getBytes:(Ljava/lang/String;)[B.
*/
@Parameter
private Set<String> exclusions = new HashSet<String>();
protected Set<String> exclusions = new HashSet<String>();

/**
* Violation patterns to disable. Each exclusion should be a
Expand All @@ -144,15 +144,25 @@ public final class ModernizerMojo extends AbstractMojo {
* java/lang/.*
*/
@Parameter
private Set<String> exclusionPatterns = new HashSet<String>();
protected Set<String> exclusionPatterns = new HashSet<String>();

/**
* Package prefixes to ignore, specified using &lt;ignorePackage&gt; child
* elements. Specifying foo.bar subsequently ignores foo.bar.*,
* foo.bar.baz.* and so on.
*/
@Parameter
private Set<String> ignorePackages = new HashSet<String>();
protected Set<String> ignorePackages = new HashSet<String>();

/**
* Fully qualified class names (incl. package) to ignore by regular
* expression, specified using &lt;ignoreClassNamePattern&gt; child
* elements. Specifying .*.bar.* ignores foo.bar.*, foo.bar.baz.* but
* also bar.* and so on; or .*Immutable ignores all class with names
* ending in Immutable in all packages.
*/
@Parameter
protected Set<String> ignoreClassNamePatterns = new HashSet<String>();

private Modernizer modernizer;

Expand Down Expand Up @@ -192,8 +202,19 @@ public void execute() throws MojoExecutionException {
}
}

Set<Pattern> allIgnoreFullClassNamePatterns = new HashSet<Pattern>();
for (String pattern : ignoreClassNamePatterns) {
try {
allIgnoreFullClassNamePatterns.add(Pattern.compile(pattern));
} catch (PatternSyntaxException pse) {
throw new MojoExecutionException(
"Invalid exclusion pattern", pse);
}
}

modernizer = new Modernizer(javaVersion, allViolations, allExclusions,
allExclusionPatterns, ignorePackages);
allExclusionPatterns, ignorePackages,
allIgnoreFullClassNamePatterns);

try {
long count = recurseFiles(outputDirectory);
Expand Down
18 changes: 10 additions & 8 deletions src/test/java/org/gaul/modernizer_maven_plugin/ModernizerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ public void testMethodLegacyApiCurrentJavaWithExclusion() throws Exception {
"java/lang/String.getBytes:(Ljava/lang/String;)[B");
Collection<ViolationOccurrence> occurrences = new Modernizer(
"1.6", violations, exclusions, NO_EXCLUSION_PATTERNS,
NO_IGNORED_PACKAGES).check(cr);
NO_IGNORED_PACKAGES, NO_EXCLUSION_PATTERNS).check(cr);
assertThat(occurrences).hasSize(0);
}

Expand All @@ -217,7 +217,7 @@ public void testMethodLegacyApiCurrentJavaWithExclusionPattern()
Pattern.compile("java/lang/.*"));
Collection<ViolationOccurrence> occurrences = new Modernizer(
"1.6", violations, NO_EXCLUSIONS, exclusionPatterns,
NO_IGNORED_PACKAGES).check(cr);
NO_IGNORED_PACKAGES, NO_EXCLUSION_PATTERNS).check(cr);
assertThat(occurrences).hasSize(0);
}

Expand All @@ -229,7 +229,7 @@ public void testMethodLegacyApiCurrentJavaWithIgnorePackages()
StringGetBytesString.class.getPackage().getName());
Collection<ViolationOccurrence> occurrences = new Modernizer(
"1.6", violations, NO_EXCLUSIONS, NO_EXCLUSION_PATTERNS,
ignorePackages).check(cr);
ignorePackages, NO_EXCLUSION_PATTERNS).check(cr);
assertThat(occurrences).hasSize(0);
}

Expand All @@ -240,7 +240,7 @@ public void testMethodLegacyApiCurrentJavaWithIgnorePackagesPrefix()
Collection<String> ignorePackages = Collections.singleton("org.gaul");
Collection<ViolationOccurrence> occurrences = new Modernizer(
"1.6", violations, NO_EXCLUSIONS, NO_EXCLUSION_PATTERNS,
ignorePackages).check(cr);
ignorePackages, NO_EXCLUSION_PATTERNS).check(cr);
assertThat(occurrences).hasSize(0);
}

Expand All @@ -251,7 +251,7 @@ public void testMethodLegacyApiCurrentJavaWithIgnorePackagesSubprefix()
Collection<String> ignorePackages = Collections.singleton("org");
Collection<ViolationOccurrence> occurrences = new Modernizer(
"1.6", violations, NO_EXCLUSIONS, NO_EXCLUSION_PATTERNS,
ignorePackages).check(cr);
ignorePackages, NO_EXCLUSION_PATTERNS).check(cr);
assertThat(occurrences).hasSize(0);
}

Expand All @@ -262,7 +262,7 @@ public void testMethodLegacyApiCurrentJavaWithIgnorePackagesPartialPrefix()
Collection<String> ignorePackages = Collections.singleton("org.gau");
Collection<ViolationOccurrence> occurrences = new Modernizer(
"1.6", violations, NO_EXCLUSIONS, NO_EXCLUSION_PATTERNS,
ignorePackages).check(cr);
ignorePackages, NO_EXCLUSION_PATTERNS).check(cr);
assertThat(occurrences).hasSize(1);
}

Expand Down Expand Up @@ -293,7 +293,8 @@ public void testAnnotationViolation() throws Exception {
testViolations.put(name,
new Violation(name, 5, ""));
Modernizer modernizer = new Modernizer("1.5", testViolations,
NO_EXCLUSIONS, NO_EXCLUSION_PATTERNS, NO_IGNORED_PACKAGES);
NO_EXCLUSIONS, NO_EXCLUSION_PATTERNS, NO_IGNORED_PACKAGES,
NO_EXCLUSION_PATTERNS);
ClassReader cr = new ClassReader(AnnotatedMethod.class.getName());
Collection<ViolationOccurrence> occurences =
modernizer.check(cr);
Expand Down Expand Up @@ -362,7 +363,8 @@ public void testAllViolations() throws Exception {
/** Helper to create Modernizer object with default parameters. */
private Modernizer createModernizer(String javaVersion) {
return new Modernizer(javaVersion, violations, NO_EXCLUSIONS,
NO_EXCLUSION_PATTERNS, NO_IGNORED_PACKAGES);
NO_EXCLUSION_PATTERNS, NO_IGNORED_PACKAGES,
NO_EXCLUSION_PATTERNS);
}

private static class CharsetsTestClass {
Expand Down

0 comments on commit 6d325ee

Please sign in to comment.