From 57d65f6558db8aa88c545344620c659d58a2b46a Mon Sep 17 00:00:00 2001 From: Godin Date: Sat, 23 Oct 2010 22:11:39 +0000 Subject: [PATCH] SONAR-1832: Use new rules api --- .../bytecode/check/ArchitectureCheck.java | 12 +++--- .../check/CallToDeprecatedMethodCheck.java | 6 +-- .../check/UnusedPrivateMethodCheck.java | 20 +++++----- .../check/UnusedProtectedMethodCheck.java | 12 +++--- .../sonar/plugins/squid/SquidConstants.java | 10 +++++ .../sonar/plugins/squid/SquidExecutor.java | 23 ++++++----- .../org/sonar/plugins/squid/SquidPlugin.java | 38 ++++++++---------- .../plugins/squid/SquidRuleRepository.java | 24 ++++++++++++ .../org/sonar/plugins/squid/SquidSensor.java | 35 +++++++---------- .../sonar/plugins/squid/bridges/Bridge.java | 8 ++-- .../plugins/squid/bridges/BridgeFactory.java | 14 +++---- .../plugins/squid/bridges/ChecksBridge.java | 14 +++++-- .../plugins/squid/SquidExecutorTest.java | 39 ++++++++++--------- .../plugins/squid/bridges/BridgeTestCase.java | 19 +++++---- 14 files changed, 153 insertions(+), 121 deletions(-) create mode 100644 plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidConstants.java create mode 100644 plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidRuleRepository.java diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/ArchitectureCheck.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/ArchitectureCheck.java index 2ca7f47ee4f..e7c189830ab 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/ArchitectureCheck.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/ArchitectureCheck.java @@ -21,10 +21,11 @@ package org.sonar.java.bytecode.check; import org.apache.commons.lang.StringUtils; import org.sonar.api.utils.WildcardPattern; -import org.sonar.check.Check; -import org.sonar.check.CheckProperty; +import org.sonar.check.Cardinality; import org.sonar.check.IsoCategory; import org.sonar.check.Priority; +import org.sonar.check.Rule; +import org.sonar.check.RuleProperty; import org.sonar.java.bytecode.asm.AsmClass; import org.sonar.java.bytecode.asm.AsmEdge; import org.sonar.squid.api.CheckMessage; @@ -36,13 +37,13 @@ import com.google.common.collect.Sets; import java.util.List; import java.util.Set; -@Check(key = "Dependency", title = "Respect rule architecture", isoCategory = IsoCategory.Portability, priority = Priority.MINOR, description = "

Links between classes must respect defined architecture rules.

") +@Rule(key = "Dependency", name = "Respect rule architecture", cardinality = Cardinality.MULTIPLE, isoCategory = IsoCategory.Portability, priority = Priority.MINOR, description = "

Links between classes must respect defined architecture rules.

") public class ArchitectureCheck extends BytecodeCheck { - @CheckProperty(title = "Pattern forbidden for from classes", key = "fromPatterns") + @RuleProperty(description = "Pattern forbidden for from classes") private String fromPatterns = new String(); - @CheckProperty(title = "Pattern forbidden for to classes", key = "toPatterns") + @RuleProperty(description = "Pattern forbidden for to classes") private String toPatterns = new String(); private List fromMatchers; @@ -78,6 +79,7 @@ public class ArchitectureCheck extends BytecodeCheck { String internalNameTargetClass = edge.getTargetAsmClass().getInternalName(); if ( !internalNames.contains(internalNameTargetClass)) { String nameAsmClass = asmClass.getInternalName(); + System.out.println("Checking : " + nameAsmClass + " -> " + internalNameTargetClass); if (matches(nameAsmClass, getFromMatchers()) && matches(internalNameTargetClass, getToMatchers())) { SourceFile sourceFile = getSourceFile(asmClass); CheckMessage message = new CheckMessage(this, nameAsmClass + " shouldn't directly use " + internalNameTargetClass); diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/CallToDeprecatedMethodCheck.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/CallToDeprecatedMethodCheck.java index 99364ac2669..11ae1c00432 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/CallToDeprecatedMethodCheck.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/CallToDeprecatedMethodCheck.java @@ -19,18 +19,16 @@ */ package org.sonar.java.bytecode.check; -import org.sonar.check.Check; import org.sonar.check.IsoCategory; import org.sonar.check.Priority; +import org.sonar.check.Rule; import org.sonar.java.bytecode.asm.AsmClass; import org.sonar.java.bytecode.asm.AsmEdge; import org.sonar.java.bytecode.asm.AsmMethod; import org.sonar.squid.api.CheckMessage; import org.sonar.squid.api.SourceFile; -@Check(key = "CallToDeprecatedMethod", title = "Avoid use of deprecated method", - isoCategory = IsoCategory.Portability, priority = Priority.MINOR, - description = "

Once deprecated, a method should no longer be used as it means that the method might be removed sooner or later.

") +@Rule(key = "CallToDeprecatedMethod", name = "Avoid use of deprecated method", isoCategory = IsoCategory.Portability, priority = Priority.MINOR, description = "

Once deprecated, a method should no longer be used as it means that the method might be removed sooner or later.

") public class CallToDeprecatedMethodCheck extends BytecodeCheck { private AsmClass asmClass; diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedPrivateMethodCheck.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedPrivateMethodCheck.java index 71e763d66f5..cd519199837 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedPrivateMethodCheck.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedPrivateMethodCheck.java @@ -19,24 +19,23 @@ */ package org.sonar.java.bytecode.check; -import org.sonar.check.Check; import org.sonar.check.IsoCategory; import org.sonar.check.Priority; +import org.sonar.check.Rule; import org.sonar.java.bytecode.asm.AsmClass; import org.sonar.java.bytecode.asm.AsmMethod; import org.sonar.squid.api.CheckMessage; import org.sonar.squid.api.SourceFile; import org.sonar.squid.api.SourceMethod; -@Check(key = "UnusedPrivateMethod", title = "Unused private method", isoCategory = IsoCategory.Maintainability, priority = Priority.MAJOR, - description = "

Private methods that are never executed are dead code. " + - "Dead code means unnecessary, inoperative code that should be removed. " + - "This helps in maintenance by decreasing the maintained code size, " + - "making it easier to understand the program and preventing bugs from being introduced.

" + - "

In the following two cases, private methods are not considered as dead code by Sonar :

" + - "") +@Rule(key = "UnusedPrivateMethod", name = "Unused private method", isoCategory = IsoCategory.Maintainability, priority = Priority.MAJOR, description = "

Private methods that are never executed are dead code. " + + "Dead code means unnecessary, inoperative code that should be removed. " + + "This helps in maintenance by decreasing the maintained code size, " + + "making it easier to understand the program and preventing bugs from being introduced.

" + + "

In the following two cases, private methods are not considered as dead code by Sonar :

" + + "") public class UnusedPrivateMethodCheck extends BytecodeCheck { private AsmClass asmClass; @@ -46,6 +45,7 @@ public class UnusedPrivateMethodCheck extends BytecodeCheck { this.asmClass = asmClass; } + @Override public void visitMethod(AsmMethod asmMethod) { if ( !asmMethod.isUsed() && asmMethod.isPrivate() && !asmMethod.isDefaultConstructor() && !SerializableContract.methodMatch(asmMethod)) { CheckMessage message = new CheckMessage(this, "Private method '" + asmMethod.getName() + "(...)' is never used."); diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedProtectedMethodCheck.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedProtectedMethodCheck.java index 7a19c85b87d..a0eee668c22 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedProtectedMethodCheck.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/bytecode/check/UnusedProtectedMethodCheck.java @@ -19,26 +19,23 @@ w * Sonar, open source software quality management tool. */ package org.sonar.java.bytecode.check; -import org.sonar.check.Check; import org.sonar.check.IsoCategory; import org.sonar.check.Priority; +import org.sonar.check.Rule; import org.sonar.java.bytecode.asm.AsmClass; import org.sonar.java.bytecode.asm.AsmMethod; import org.sonar.squid.api.CheckMessage; import org.sonar.squid.api.SourceFile; import org.sonar.squid.api.SourceMethod; -@Check(key = "UnusedProtectedMethod", title = "Unused protected method", - isoCategory = IsoCategory.Maintainability, priority = Priority.MAJOR, - description = "

Protected methods that are never used by any classes " + - "in the same project are strongly suspected to be dead code. " +@Rule(key = "UnusedProtectedMethod", name = "Unused protected method", isoCategory = IsoCategory.Maintainability, priority = Priority.MAJOR, description = "

Protected methods that are never used by any classes " + + "in the same project are strongly suspected to be dead code. " + "Dead code means unnecessary, inoperative code that should be removed. " + "This helps in maintenance by decreasing the maintained code size, " + "making it easier to understand the program and preventing bugs from being introduced.

" + "

In the following case, unused protected methods are not considered as dead code by Sonar :

" + "" - + "" - ) + + "") public class UnusedProtectedMethodCheck extends BytecodeCheck { private AsmClass asmClass; @@ -48,6 +45,7 @@ public class UnusedProtectedMethodCheck extends BytecodeCheck { this.asmClass = asmClass; } + @Override public void visitMethod(AsmMethod asmMethod) { if ( !asmMethod.isUsed() && asmMethod.isProtected() && !asmClass.isAbstract() && !SerializableContract.methodMatch(asmMethod) && !asmMethod.isInherited()) { diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidConstants.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidConstants.java new file mode 100644 index 00000000000..86916bdb3f5 --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidConstants.java @@ -0,0 +1,10 @@ +package org.sonar.plugins.squid; + +import org.sonar.api.CoreProperties; + +public final class SquidConstants { + + public static final String REPOSITORY_KEY = CoreProperties.SQUID_PLUGIN; + public static final String REPOSITORY_NAME = "Squid"; + +} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidExecutor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidExecutor.java index 0fd99b49c4f..d151511bb9f 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidExecutor.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidExecutor.java @@ -19,15 +19,10 @@ */ package org.sonar.plugins.squid; -import java.io.File; -import java.nio.charset.Charset; -import java.util.Collection; -import java.util.List; - import org.apache.commons.lang.StringUtils; import org.sonar.api.batch.SensorContext; +import org.sonar.api.checks.CheckFactory; import org.sonar.api.checks.NoSonarFilter; -import org.sonar.api.checks.checkers.MessageDispatcher; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.api.utils.TimeProfiler; @@ -45,19 +40,23 @@ import org.sonar.squid.api.SourcePackage; import org.sonar.squid.indexer.QueryByType; import org.sonar.squid.measures.Metric; +import java.io.File; +import java.nio.charset.Charset; +import java.util.Collection; +import java.util.List; + public final class SquidExecutor { private Squid squid; private boolean sourceScanned = false; private boolean bytecodeScanned = false; - private MessageDispatcher messageDispatcher; + private CheckFactory checkFactory; - public SquidExecutor(boolean analyzePropertyAccessors, String fieldNamesToExcludeFromLcom4Computation, - MessageDispatcher messageDispatcher, Charset sourcesCharset) { + public SquidExecutor(boolean analyzePropertyAccessors, String fieldNamesToExcludeFromLcom4Computation, CheckFactory checkFactory, Charset sourcesCharset) { JavaSquidConfiguration conf = createJavaSquidConfiguration(analyzePropertyAccessors, fieldNamesToExcludeFromLcom4Computation, sourcesCharset); squid = new Squid(conf); - this.messageDispatcher = messageDispatcher; + this.checkFactory = checkFactory; } private JavaSquidConfiguration createJavaSquidConfiguration(boolean analyzePropertyAccessors, @@ -82,7 +81,7 @@ public final class SquidExecutor { public void scan(Collection sourceFiles, Collection bytecodeFilesOrDirectories) { scanSources(sourceFiles); if (sourceScanned) { - for (Object checker : messageDispatcher.getCheckers()) { + for (Object checker : checkFactory.getChecks()) { squid.registerVisitor((BytecodeCheck) checker); } scanBytecode(bytecodeFilesOrDirectories); @@ -94,7 +93,7 @@ public final class SquidExecutor { if (sourceScanned) { TimeProfiler profiler = new TimeProfiler(getClass()).start("Squid extraction"); ResourceIndex resourceIndex = new ResourceIndex().loadSquidResources(squid, context, project); - List bridges = BridgeFactory.create(bytecodeScanned, context, messageDispatcher, resourceIndex, squid, noSonarFilter); + List bridges = BridgeFactory.create(bytecodeScanned, context, checkFactory, resourceIndex, squid, noSonarFilter); saveProject(resourceIndex, bridges); savePackages(resourceIndex, bridges); saveFiles(resourceIndex, bridges); diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java index 2269a6a16e1..16ba011d56d 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidPlugin.java @@ -19,33 +19,30 @@ */ package org.sonar.plugins.squid; -import java.util.ArrayList; -import java.util.List; - import org.sonar.api.CoreProperties; import org.sonar.api.Plugin; import org.sonar.api.Properties; import org.sonar.api.Property; -import org.sonar.api.checks.templates.CheckTemplateRepository; -import org.sonar.api.resources.Java; -import org.sonar.java.bytecode.check.BytecodeChecks; + +import java.util.ArrayList; +import java.util.List; @Properties( { @Property(key = SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_PROPERTY, - defaultValue = SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_DEFAULT_VALUE - + "", - name = "Separate accessors", - description = "Flag whether Squid should separate accessors (getters/setters) from methods. " + - "In that case, accessors are not counted in metrics such as complexity or API documentation.", - project = true, global = true), + defaultValue = SquidPluginProperties.SQUID_ANALYSE_ACCESSORS_DEFAULT_VALUE + + "", + name = "Separate accessors", + description = "Flag whether Squid should separate accessors (getters/setters) from methods. " + + "In that case, accessors are not counted in metrics such as complexity or API documentation.", + project = true, global = true), @Property(key = SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION, - defaultValue = SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION_DEFAULT_VALUE, - name = "List of fields to exclude from LCOM4 computation", - description = "Some fields should not be taken into account when computing LCOM4 measure as they " + - "unexpectedly and artificially decrease the LCOM4 measure. " - + "The best example is a logger used by all methods of a class. " + - "All field names to exclude from LCOM4 computation must be separated by a comma.", - project = true, global = true) }) + defaultValue = SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION_DEFAULT_VALUE, + name = "List of fields to exclude from LCOM4 computation", + description = "Some fields should not be taken into account when computing LCOM4 measure as they " + + "unexpectedly and artificially decrease the LCOM4 measure. " + + "The best example is a logger used by all methods of a class. " + + "All field names to exclude from LCOM4 computation must be separated by a comma.", + project = true, global = true) }) public class SquidPlugin implements Plugin { public String getKey() { @@ -65,8 +62,7 @@ public class SquidPlugin implements Plugin { list.add(SquidSearchProxy.class); list.add(SquidSensor.class); - list.add(CheckTemplateRepository.createFromAnnotatedClasses(CoreProperties.SQUID_PLUGIN, Java.INSTANCE, BytecodeChecks - .getCheckClasses())); + list.add(SquidRuleRepository.class); return list; } diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidRuleRepository.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidRuleRepository.java new file mode 100644 index 00000000000..5ad41629d5c --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidRuleRepository.java @@ -0,0 +1,24 @@ +package org.sonar.plugins.squid; + +import org.sonar.api.resources.Java; +import org.sonar.api.rules.AnnotationRuleParser; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleRepository; +import org.sonar.java.bytecode.check.BytecodeChecks; + +import java.util.List; + +public final class SquidRuleRepository extends RuleRepository { + private AnnotationRuleParser ruleParser; + + public SquidRuleRepository(AnnotationRuleParser ruleParser) { + super(SquidConstants.REPOSITORY_KEY, Java.KEY); + setName(SquidConstants.REPOSITORY_NAME); + this.ruleParser = new AnnotationRuleParser(); // TODO bug? + } + + @Override + public List createRules() { + return ruleParser.parse(SquidConstants.REPOSITORY_KEY, BytecodeChecks.getCheckClasses()); + } +} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java index eade90a88f9..4804d306d4a 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/SquidSensor.java @@ -19,13 +19,6 @@ */ package org.sonar.plugins.squid; -import java.io.File; -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; - import org.apache.commons.io.FileUtils; import org.apache.maven.artifact.Artifact; import org.apache.maven.project.MavenProject; @@ -37,15 +30,21 @@ import org.sonar.api.batch.DependedUpon; import org.sonar.api.batch.Phase; import org.sonar.api.batch.Sensor; import org.sonar.api.batch.SensorContext; +import org.sonar.api.checks.AnnotationCheckFactory; import org.sonar.api.checks.NoSonarFilter; -import org.sonar.api.checks.checkers.AnnotationCheckerFactory; -import org.sonar.api.checks.checkers.MessageDispatcher; -import org.sonar.api.checks.profiles.CheckProfile; +import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Java; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; import org.sonar.java.bytecode.check.BytecodeChecks; +import java.io.File; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Set; + @Phase(name = Phase.Name.PRE) /* TODO is the flag still used ? */ @DependedUpon(value = Sensor.FLAG_SQUID_ANALYSIS, classes = NoSonarFilter.class) @@ -53,9 +52,9 @@ public class SquidSensor implements Sensor { private SquidSearchProxy proxy; private NoSonarFilter noSonarFilter; - private CheckProfile profile; + private RulesProfile profile; - public SquidSensor(CheckProfile profile, SquidSearchProxy proxy, NoSonarFilter noSonarFilter) { + public SquidSensor(RulesProfile profile, SquidSearchProxy proxy, NoSonarFilter noSonarFilter) { this.proxy = proxy; this.noSonarFilter = noSonarFilter; this.profile = profile; @@ -74,22 +73,14 @@ public class SquidSensor implements Sensor { SquidPluginProperties.FIELDS_TO_EXCLUDE_FROM_LCOM4_COMPUTATION_DEFAULT_VALUE); Charset charset = project.getFileSystem().getSourceCharset(); - MessageDispatcher messageDispatcher = initMessageDispatcher(context); + AnnotationCheckFactory factory = AnnotationCheckFactory.create(profile, SquidConstants.REPOSITORY_KEY, BytecodeChecks.getCheckClasses()); - SquidExecutor squidExecutor = new SquidExecutor(analyzePropertyAccessors, fieldNamesToExcludeFromLcom4Computation, messageDispatcher, - charset); + SquidExecutor squidExecutor = new SquidExecutor(analyzePropertyAccessors, fieldNamesToExcludeFromLcom4Computation, factory, charset); squidExecutor.scan(getSourceFiles(project), getBytecodeFiles(project)); squidExecutor.save(project, context, noSonarFilter); squidExecutor.initSonarProxy(proxy); } - private MessageDispatcher initMessageDispatcher(SensorContext context) { - MessageDispatcher messageDispatcher = new MessageDispatcher(context); - AnnotationCheckerFactory factory = new AnnotationCheckerFactory(profile, CoreProperties.SQUID_PLUGIN, BytecodeChecks.getCheckClasses()); - messageDispatcher.registerCheckers(factory); - return messageDispatcher; - } - private List getSourceFiles(Project project) { return project.getFileSystem().getJavaSourceFiles(); } diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Bridge.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Bridge.java index 3ad6ba9a6b8..278e9a6cb29 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Bridge.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/Bridge.java @@ -20,7 +20,7 @@ package org.sonar.plugins.squid.bridges; import org.sonar.api.batch.SensorContext; -import org.sonar.api.checks.checkers.MessageDispatcher; +import org.sonar.api.checks.CheckFactory; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.squid.Squid; @@ -37,7 +37,7 @@ public abstract class Bridge { Squid squid; ResourceIndex resourceIndex; SensorContext context; - MessageDispatcher messageDispatcher; + CheckFactory checkFactory; protected Bridge(boolean needsBytecode) { this.needsBytecode = needsBytecode; @@ -51,8 +51,8 @@ public abstract class Bridge { this.squid = squid; } - protected final void setMessageDispatcher(MessageDispatcher messageDispatcher) { - this.messageDispatcher = messageDispatcher; + protected final void setCheckFactory(CheckFactory checkFactory) { + this.checkFactory = checkFactory; } protected final void setResourceIndex(ResourceIndex resourceIndex) { diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/BridgeFactory.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/BridgeFactory.java index bde8f1fac48..f3c822ca2a2 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/BridgeFactory.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/BridgeFactory.java @@ -19,15 +19,15 @@ */ package org.sonar.plugins.squid.bridges; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - import org.sonar.api.batch.SensorContext; +import org.sonar.api.checks.CheckFactory; import org.sonar.api.checks.NoSonarFilter; -import org.sonar.api.checks.checkers.MessageDispatcher; import org.sonar.squid.Squid; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public final class BridgeFactory { private BridgeFactory() { @@ -41,11 +41,11 @@ public final class BridgeFactory { new Lcom4BlocksBridge(), new ChecksBridge()); } - public static List create(boolean bytecodeScanned, SensorContext context, MessageDispatcher messageDispatcher, + public static List create(boolean bytecodeScanned, SensorContext context, CheckFactory checkFactory, ResourceIndex resourceIndex, Squid squid, NoSonarFilter noSonarFilter) { List result = new ArrayList(); for (Bridge bridge : create(noSonarFilter)) { - bridge.setMessageDispatcher(messageDispatcher); + bridge.setCheckFactory(checkFactory); if ( !bridge.needsBytecode() || bytecodeScanned) { bridge.setContext(context); bridge.setSquid(squid); diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/ChecksBridge.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/ChecksBridge.java index b65e21926ba..0d083d2a77f 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/ChecksBridge.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/plugins/squid/bridges/ChecksBridge.java @@ -19,12 +19,15 @@ */ package org.sonar.plugins.squid.bridges; -import java.util.Set; - import org.sonar.api.resources.Resource; +import org.sonar.api.rules.ActiveRule; +import org.sonar.api.rules.Violation; import org.sonar.squid.api.CheckMessage; import org.sonar.squid.api.SourceFile; +import java.util.Locale; +import java.util.Set; + public class ChecksBridge extends Bridge { protected ChecksBridge() { @@ -36,9 +39,12 @@ public class ChecksBridge extends Bridge { Set messages = squidFile.getCheckMessages(); if (messages != null) { for (CheckMessage checkMessage : messages) { - messageDispatcher.log(sonarFile, checkMessage); + ActiveRule rule = checkFactory.getActiveRule(checkMessage.getChecker()); + Violation violation = Violation.create(rule, sonarFile); + violation.setLineId(checkMessage.getLine()); + violation.setMessage(checkMessage.getText(Locale.ENGLISH)); + context.saveViolation(violation); } } } - } diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidExecutorTest.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidExecutorTest.java index 767be2009dd..d8c39f388c6 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidExecutorTest.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/SquidExecutorTest.java @@ -29,27 +29,28 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; -import java.io.File; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.util.Arrays; -import java.util.Collections; - import org.junit.Test; import org.sonar.api.batch.SensorContext; -import org.sonar.api.checks.checkers.MessageDispatcher; +import org.sonar.api.checks.AnnotationCheckFactory; +import org.sonar.api.checks.CheckFactory; +import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.squid.Squid; import org.sonar.squid.measures.Metric; +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collections; + public class SquidExecutorTest { @Test public void scanSources() throws IOException, URISyntaxException { - SquidExecutor executor = new SquidExecutor(true, "LOG, logger", new MessageDispatcher(mock(SensorContext.class)), Charset - .defaultCharset()); + SquidExecutor executor = new SquidExecutor(true, "LOG, logger", createCheckFactory(), Charset.defaultCharset()); executor.scan(SquidTestUtils.getStrutsCoreSources(), Collections. emptyList()); assertThat(executor.isSourceScanned(), is(true)); @@ -58,8 +59,7 @@ public class SquidExecutorTest { @Test public void doNotScanBytecodeIfNoSources() throws IOException, URISyntaxException { - SquidExecutor executor = new SquidExecutor(true, "LOG, logger", new MessageDispatcher(mock(SensorContext.class)), Charset - .defaultCharset()); + SquidExecutor executor = new SquidExecutor(true, "LOG, logger", createCheckFactory(), Charset.defaultCharset()); executor.scan(Collections. emptyList(), Arrays.asList(SquidTestUtils.getStrutsCoreJar())); assertThat(executor.isSourceScanned(), is(false)); @@ -68,8 +68,7 @@ public class SquidExecutorTest { @Test public void scanBytecode() throws IOException, URISyntaxException { - SquidExecutor executor = new SquidExecutor(true, "LOG, logger", new MessageDispatcher(mock(SensorContext.class)), Charset - .defaultCharset()); + SquidExecutor executor = new SquidExecutor(true, "LOG, logger", createCheckFactory(), Charset.defaultCharset()); executor.scan(SquidTestUtils.getStrutsCoreSources(), Arrays.asList(SquidTestUtils.getStrutsCoreJar())); assertThat(executor.isSourceScanned(), is(true)); @@ -79,8 +78,7 @@ public class SquidExecutorTest { @Test public void doNotSaveMeasuresIfSourceNotScanned() { - SquidExecutor executor = new SquidExecutor(true, "LOG, logger", new MessageDispatcher(mock(SensorContext.class)), Charset - .defaultCharset()); + SquidExecutor executor = new SquidExecutor(true, "LOG, logger", createCheckFactory(), Charset.defaultCharset()); SensorContext context = mock(SensorContext.class); assertThat(executor.isSourceScanned(), is(false)); @@ -91,8 +89,7 @@ public class SquidExecutorTest { @Test public void scanThenSaveMeasures() throws IOException, URISyntaxException { - SquidExecutor executor = new SquidExecutor(true, "LOG, logger", new MessageDispatcher(mock(SensorContext.class)), Charset - .defaultCharset()); + SquidExecutor executor = new SquidExecutor(true, "LOG, logger", createCheckFactory(), Charset.defaultCharset()); SensorContext context = mock(SensorContext.class); executor.scan(SquidTestUtils.getStrutsCoreSources(), Collections. emptyList()); @@ -112,4 +109,10 @@ public class SquidExecutorTest { verify(squid).flush(); } + + private CheckFactory createCheckFactory() { + RulesProfile profile = RulesProfile.create(); + CheckFactory checkFactory = AnnotationCheckFactory.create(profile, "repo", Collections. emptyList()); + return checkFactory; + } } diff --git a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/bridges/BridgeTestCase.java b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/bridges/BridgeTestCase.java index f77a06e13c2..608d6a5a996 100644 --- a/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/bridges/BridgeTestCase.java +++ b/plugins/sonar-squid-java-plugin/src/test/java/org/sonar/plugins/squid/bridges/BridgeTestCase.java @@ -4,22 +4,25 @@ import static org.mockito.Matchers.anyObject; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import java.io.IOException; -import java.net.URISyntaxException; -import java.nio.charset.Charset; -import java.util.Arrays; - import org.junit.Before; import org.junit.BeforeClass; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.sonar.api.batch.SensorContext; -import org.sonar.api.checks.checkers.MessageDispatcher; +import org.sonar.api.checks.AnnotationCheckFactory; +import org.sonar.api.checks.CheckFactory; +import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Project; import org.sonar.api.resources.Resource; import org.sonar.plugins.squid.SquidExecutor; import org.sonar.plugins.squid.SquidTestUtils; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Collections; + public abstract class BridgeTestCase { protected SensorContext context; @@ -28,7 +31,9 @@ public abstract class BridgeTestCase { @BeforeClass public static void scanStruts() throws IOException, URISyntaxException { - executor = new SquidExecutor(true, "LOG, logger", new MessageDispatcher(mock(SensorContext.class)), Charset.forName("UTF8")); + RulesProfile profile = RulesProfile.create(); + CheckFactory checkFactory = AnnotationCheckFactory.create(profile, "repo", Collections. emptyList()); + executor = new SquidExecutor(true, "LOG, logger", checkFactory, Charset.forName("UTF8")); executor.scan(SquidTestUtils.getStrutsCoreSources(), Arrays.asList(SquidTestUtils.getStrutsCoreJar())); project = new Project("project"); } -- 2.39.5