From 6d6a15f11a58b03d3942cd9e237460cdc2393ed2 Mon Sep 17 00:00:00 2001 From: Godin Date: Fri, 26 Nov 2010 15:02:43 +0000 Subject: [PATCH] SONAR-1817: Squid rule to create violation on each NOSONAR tag occurence --- .../org/sonar/java/squid/SquidScanner.java | 12 +++--- .../java/squid/SquidVisitorNotifier.java | 35 +++++++++++---- .../sonar/java/squid/check/NoSonarCheck.java | 43 +++++++++++++++++++ .../sonar/java/squid/check/SquidCheck.java | 4 ++ .../java/squid/visitor/SquidVisitor.java | 3 ++ .../plugins/squid/SquidRuleRepository.java | 5 ++- .../plugins/squid/bridges/ChecksBridge.java | 2 +- .../org/sonar/squid/api/CheckMessage.java | 10 +++++ .../java/org/sonar/squid/api/SourceCode.java | 2 +- 9 files changed, 97 insertions(+), 19 deletions(-) create mode 100644 plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/NoSonarCheck.java diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidScanner.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidScanner.java index 42cba38d6ca..f3ecbc425e2 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidScanner.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidScanner.java @@ -27,8 +27,8 @@ import org.sonar.java.squid.check.SquidCheck; import org.sonar.java.squid.visitor.SquidVisitor; import org.sonar.squid.api.CodeScanner; import org.sonar.squid.api.CodeVisitor; -import org.sonar.squid.api.SourceClass; import org.sonar.squid.api.SourceCode; +import org.sonar.squid.api.SourceFile; import org.sonar.squid.indexer.QueryByType; import org.sonar.squid.indexer.SquidIndex; @@ -41,14 +41,14 @@ public class SquidScanner extends CodeScanner { } public void scan() { - Collection classes = indexer.search(new QueryByType(SourceClass.class)); - notifySquidVisitors(classes); + Collection files = indexer.search(new QueryByType(SourceFile.class)); + notifySquidVisitors(files); } - private void notifySquidVisitors(Collection classes) { + private void notifySquidVisitors(Collection files) { SquidVisitor[] visitorArray = getVisitors().toArray(new SquidVisitor[getVisitors().size()]); - for (SourceCode sourceClass : classes) { - SquidVisitorNotifier visitorNotifier = new SquidVisitorNotifier((SourceClass) sourceClass, visitorArray); + for (SourceCode sourceFile : files) { + SquidVisitorNotifier visitorNotifier = new SquidVisitorNotifier((SourceFile) sourceFile, visitorArray); visitorNotifier.notifyVisitors(indexer); } } diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidVisitorNotifier.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidVisitorNotifier.java index 98ef164fca4..59eb5af86f7 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidVisitorNotifier.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/SquidVisitorNotifier.java @@ -3,33 +3,49 @@ package org.sonar.java.squid; import org.sonar.java.squid.visitor.SquidVisitor; import org.sonar.squid.api.SourceClass; import org.sonar.squid.api.SourceCode; +import org.sonar.squid.api.SourceFile; import org.sonar.squid.api.SourceMethod; import org.sonar.squid.indexer.SquidIndex; public class SquidVisitorNotifier { - private final SourceClass sourceClass; + private final SourceFile sourceFile; private final SquidVisitor[] squidVisitors; - public SquidVisitorNotifier(SourceClass sourceClass, SquidVisitor[] squidVisitors) { - this.sourceClass = sourceClass; + public SquidVisitorNotifier(SourceFile sourceFile, SquidVisitor[] squidVisitors) { + this.sourceFile = sourceFile; this.squidVisitors = new SquidVisitor[squidVisitors.length]; System.arraycopy(squidVisitors, 0, this.squidVisitors, 0, squidVisitors.length); } public void notifyVisitors(SquidIndex indexer) { - callVisitClass(); - callVisitMethod(); + callVisitFile(); } - private void callVisitClass() { + private void callVisitFile() { for (SquidVisitor visitor : squidVisitors) { - visitor.visitClass(sourceClass); + visitor.visitFile(sourceFile); } + callVisitClass(sourceFile); } - private void callVisitMethod() { - if (sourceClass.getChildren() == null) { // TODO Most probably SourceCode#hasChildren() shouldn't be protected + private void callVisitClass(SourceFile sourceFile) { + if ( !sourceFile.hasChildren()) { + return; + } + for (SourceCode sourceCode : sourceFile.getChildren()) { + if (sourceCode instanceof SourceClass) { + SourceClass sourceClass = (SourceClass) sourceCode; + for (SquidVisitor visitor : squidVisitors) { + visitor.visitClass(sourceClass); + } + callVisitMethod(sourceClass); + } + } + } + + private void callVisitMethod(SourceClass sourceClass) { + if ( !sourceClass.hasChildren()) { return; } for (SourceCode sourceCode : sourceClass.getChildren()) { @@ -41,4 +57,5 @@ public class SquidVisitorNotifier { } } } + } diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/NoSonarCheck.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/NoSonarCheck.java new file mode 100644 index 00000000000..add1a0cd6eb --- /dev/null +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/NoSonarCheck.java @@ -0,0 +1,43 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2009 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * Sonar is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * Sonar is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ + +package org.sonar.java.squid.check; + +import org.sonar.check.IsoCategory; +import org.sonar.check.Priority; +import org.sonar.check.Rule; +import org.sonar.squid.api.CheckMessage; +import org.sonar.squid.api.SourceFile; + +@Rule(key = "NoSonarCheck", name = "NOSONAR occurence", isoCategory = IsoCategory.Maintainability, priority = Priority.INFO, + description = "") +public class NoSonarCheck extends SquidCheck { + + @Override + public void visitFile(SourceFile sourceFile) { + for (Integer line : sourceFile.getNoSonarTagLines()) { + CheckMessage message = new CheckMessage(this, "NOSONAR occurence"); + message.setForced(true); + message.setLine(line); + sourceFile.log(message); + } + } + +} diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/SquidCheck.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/SquidCheck.java index 2bbdfd3f274..4cf44a75a9a 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/SquidCheck.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/check/SquidCheck.java @@ -23,6 +23,7 @@ package org.sonar.java.squid.check; import org.sonar.java.squid.visitor.SquidVisitor; import org.sonar.squid.api.CodeCheck; import org.sonar.squid.api.SourceClass; +import org.sonar.squid.api.SourceFile; import org.sonar.squid.api.SourceMethod; public class SquidCheck implements SquidVisitor, CodeCheck { @@ -31,6 +32,9 @@ public class SquidCheck implements SquidVisitor, CodeCheck { return getClass().getSimpleName(); } + public void visitFile(SourceFile sourceFile) { + } + public void visitClass(SourceClass sourceClass) { } diff --git a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/visitor/SquidVisitor.java b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/visitor/SquidVisitor.java index 5d02669df5b..e5b9bcd3ede 100644 --- a/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/visitor/SquidVisitor.java +++ b/plugins/sonar-squid-java-plugin/src/main/java/org/sonar/java/squid/visitor/SquidVisitor.java @@ -21,10 +21,13 @@ package org.sonar.java.squid.visitor; import org.sonar.squid.api.CodeVisitor; import org.sonar.squid.api.SourceClass; +import org.sonar.squid.api.SourceFile; import org.sonar.squid.api.SourceMethod; public interface SquidVisitor extends CodeVisitor { + void visitFile(SourceFile sourceFile); + void visitClass(SourceClass sourceClass); void visitMethod(SourceMethod sourceMethod); 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 index 3b47ff28e18..ef9fa2e531e 100644 --- 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 @@ -37,6 +37,7 @@ import org.sonar.java.bytecode.check.UnusedProtectedMethodCheck; import org.sonar.java.squid.check.ClassComplexityCheck; import org.sonar.java.squid.check.DITCheck; import org.sonar.java.squid.check.MethodComplexityCheck; +import org.sonar.java.squid.check.NoSonarCheck; public final class SquidRuleRepository extends RuleRepository { private AnnotationRuleParser ruleParser; @@ -58,8 +59,8 @@ public final class SquidRuleRepository extends RuleRepository { (Class) CallToDeprecatedMethodCheck.class, UnusedPrivateMethodCheck.class, UnusedProtectedMethodCheck.class, ArchitectureCheck.class, // AST checks - UndocumentedApiCheck.class, ContinueCheck.class, BreakCheck.class, ClassComplexityCheck.class, MethodComplexityCheck.class, + UndocumentedApiCheck.class, ContinueCheck.class, BreakCheck.class, // Squid checks - DITCheck.class); + DITCheck.class, ClassComplexityCheck.class, MethodComplexityCheck.class, NoSonarCheck.class); } } 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 60530fc5fd9..9caf6f482c2 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 @@ -44,7 +44,7 @@ public class ChecksBridge extends Bridge { violation.setLineId(checkMessage.getLine()); violation.setMessage(checkMessage.getText(Locale.ENGLISH)); violation.setCost(checkMessage.getCost()); - context.saveViolation(violation); + context.saveViolation(violation, checkMessage.isForced()); } } } diff --git a/sonar-squid/src/main/java/org/sonar/squid/api/CheckMessage.java b/sonar-squid/src/main/java/org/sonar/squid/api/CheckMessage.java index e9caeb3e2af..1c56f8a4fb9 100644 --- a/sonar-squid/src/main/java/org/sonar/squid/api/CheckMessage.java +++ b/sonar-squid/src/main/java/org/sonar/squid/api/CheckMessage.java @@ -33,6 +33,7 @@ public class CheckMessage implements Message { private CodeCheck codeCheck; private String defaultMessage; private Object[] messageArguments; + private Boolean forced; public CheckMessage(CodeCheck rule, String message, Object... messageArguments) { this.codeCheck = rule; @@ -64,6 +65,14 @@ public class CheckMessage implements Message { return cost; } + public void setForced(boolean forced) { + this.forced = forced; + } + + public boolean isForced() { + return forced == null ? false : forced; + } + public CodeCheck getChecker() { return codeCheck; } @@ -93,4 +102,5 @@ public class CheckMessage implements Message { return MessageFormat.format(defaultMessage, messageArguments); } } + } diff --git a/sonar-squid/src/main/java/org/sonar/squid/api/SourceCode.java b/sonar-squid/src/main/java/org/sonar/squid/api/SourceCode.java index 0cedaf8bc03..03d3ce8fc8a 100644 --- a/sonar-squid/src/main/java/org/sonar/squid/api/SourceCode.java +++ b/sonar-squid/src/main/java/org/sonar/squid/api/SourceCode.java @@ -262,7 +262,7 @@ public abstract class SourceCode implements Measurable, Comparable { return false; } - protected boolean hasChildren() { + public boolean hasChildren() { return children != null && children.size() != 0; } -- 2.39.5