From: Gustavo Martin Morcuende Date: Sun, 7 Aug 2016 17:08:03 +0000 (+0200) Subject: sonar java plugin: renaming packages X-Git-Url: https://git.gumartinm.name/?a=commitdiff_plain;h=eeb1fc63f75b572db94b049604be137974a77a32;p=JavaForFun sonar java plugin: renaming packages --- diff --git a/Sonar/Plugins/sonar-custom-java-plugin/pom.xml b/Sonar/Plugins/sonar-custom-java-plugin/pom.xml index f8fe112..1b83a66 100644 --- a/Sonar/Plugins/sonar-custom-java-plugin/pom.xml +++ b/Sonar/Plugins/sonar-custom-java-plugin/pom.xml @@ -153,7 +153,7 @@ 1.17 true - de.example.plugins.custom.CustomPlugin + de.example.plugins.custom.java.CustomPlugin diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/CheckList.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/CheckList.java deleted file mode 100644 index 058b016..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/CheckList.java +++ /dev/null @@ -1,45 +0,0 @@ -package de.example.custom.checks; - -import java.util.List; - -import org.sonar.plugins.java.api.JavaCheck; - -import com.google.common.collect.ImmutableList; - -public final class CheckList { - public static final String REPOSITORY_KEY = "customjava"; - public static final String REPOSITORY_NAME = "Custom Java"; - - private CheckList() { - } - - public static List getChecks() { - return ImmutableList.builder() - .addAll(getJavaChecks()) - .addAll(getJavaTestChecks()) - .addAll(getXmlChecks()) - .build(); - } - - public static List> getJavaChecks() { - return ImmutableList.>builder() - .add(ParameterCheck.class) - .add(SpringServiceInstanceFieldCheck.class) - .build(); - } - - public static List> getJavaTestChecks() { - return ImmutableList.>builder() - .build(); - } - - public static List> getXmlChecks() { - return ImmutableList.>builder() - .build(); - } - - private static List> getMavenChecks() { - return ImmutableList.>builder() - .build(); - } -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/ParameterCheck.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/ParameterCheck.java deleted file mode 100644 index d27cf79..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/ParameterCheck.java +++ /dev/null @@ -1,43 +0,0 @@ -package de.example.custom.checks; - -import java.util.List; - -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.check.Rule; -import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; -import org.sonar.plugins.java.api.semantic.Symbol.MethodSymbol; -import org.sonar.plugins.java.api.semantic.Type; -import org.sonar.plugins.java.api.tree.MethodTree; -import org.sonar.plugins.java.api.tree.Tree; -import org.sonar.plugins.java.api.tree.Tree.Kind; - -import com.google.common.collect.ImmutableList; - -@Rule(key = "GU0001") -public class ParameterCheck extends IssuableSubscriptionVisitor { - private static final Logger LOG = Loggers.get(ParameterCheck.class); - - - @Override - public List nodesToVisit() { - return ImmutableList.of(Kind.METHOD); - } - - @Override - public void visitNode(Tree tree) { - LOG.info("Visiting Node"); - - MethodTree method = (MethodTree) tree; - - if (method.parameters().size() == 1) { - MethodSymbol symbol = method.symbol(); - Type firstParameterType = symbol.parameterTypes().get(0); - Type returnType = symbol.returnType().type(); - if(returnType.is(firstParameterType.fullyQualifiedName())) { - reportIssue(method.simpleName(), "Never do that!"); - } - } - - } -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/SpringServiceInstanceFieldCheck.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/SpringServiceInstanceFieldCheck.java deleted file mode 100644 index 8e0df34..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/checks/SpringServiceInstanceFieldCheck.java +++ /dev/null @@ -1,51 +0,0 @@ -package de.example.custom.checks; - -import java.util.List; - -import org.sonar.api.utils.log.Logger; -import org.sonar.api.utils.log.Loggers; -import org.sonar.check.Rule; -import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; -import org.sonar.plugins.java.api.JavaFileScannerContext; -import org.sonar.plugins.java.api.semantic.Symbol; -import org.sonar.plugins.java.api.tree.ClassTree; -import org.sonar.plugins.java.api.tree.Tree; -import org.sonar.plugins.java.api.tree.Tree.Kind; -import org.sonar.plugins.java.api.tree.VariableTree; - -import com.google.common.collect.ImmutableList; - -@Rule(key = "GU0002") -public class SpringServiceInstanceFieldCheck extends IssuableSubscriptionVisitor { - private static final Logger LOG = Loggers.get(SpringServiceInstanceFieldCheck.class); - - private JavaFileScannerContext context; - - - @Override - public List nodesToVisit() { - return ImmutableList.of(Kind.CLASS, Kind.VARIABLE); - } - - @Override - public void visitNode(Tree tree) { - if (tree.is(Kind.CLASS) && isSpringService((ClassTree) tree)) { - - } - - } - - - private static boolean isOwnedByASpringService(VariableTree variable) { - Symbol owner = variable.symbol().owner(); - return owner.isTypeSymbol() && (owner.type().isSubtypeOf("javax.servlet.http.HttpServlet") || owner.type().isSubtypeOf("org.apache.struts.action.Action")); - } - - private static boolean isSpringService(ClassTree tree) { - tree.symbol().metadata().isAnnotatedWith("javax.inject.Inject"); - return true; - - } - - -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/CheckList.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/CheckList.java new file mode 100644 index 0000000..4ced8a5 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/CheckList.java @@ -0,0 +1,45 @@ +package de.example.custom.java.checks; + +import java.util.List; + +import org.sonar.plugins.java.api.JavaCheck; + +import com.google.common.collect.ImmutableList; + +public final class CheckList { + public static final String REPOSITORY_KEY = "customjava"; + public static final String REPOSITORY_NAME = "Custom Java"; + + private CheckList() { + } + + public static List getChecks() { + return ImmutableList.builder() + .addAll(getJavaChecks()) + .addAll(getJavaTestChecks()) + .addAll(getXmlChecks()) + .build(); + } + + public static List> getJavaChecks() { + return ImmutableList.>builder() + .add(ParameterCheck.class) + .add(SpringServiceInstanceFieldCheck.class) + .build(); + } + + public static List> getJavaTestChecks() { + return ImmutableList.>builder() + .build(); + } + + public static List> getXmlChecks() { + return ImmutableList.>builder() + .build(); + } + + private static List> getMavenChecks() { + return ImmutableList.>builder() + .build(); + } +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/ParameterCheck.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/ParameterCheck.java new file mode 100644 index 0000000..a5ed7b8 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/ParameterCheck.java @@ -0,0 +1,43 @@ +package de.example.custom.java.checks; + +import java.util.List; + +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.check.Rule; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.semantic.Symbol.MethodSymbol; +import org.sonar.plugins.java.api.semantic.Type; +import org.sonar.plugins.java.api.tree.MethodTree; +import org.sonar.plugins.java.api.tree.Tree; +import org.sonar.plugins.java.api.tree.Tree.Kind; + +import com.google.common.collect.ImmutableList; + +@Rule(key = "GU0001") +public class ParameterCheck extends IssuableSubscriptionVisitor { + private static final Logger LOG = Loggers.get(ParameterCheck.class); + + + @Override + public List nodesToVisit() { + return ImmutableList.of(Kind.METHOD); + } + + @Override + public void visitNode(Tree tree) { + LOG.info("Visiting Node"); + + MethodTree method = (MethodTree) tree; + + if (method.parameters().size() == 1) { + MethodSymbol symbol = method.symbol(); + Type firstParameterType = symbol.parameterTypes().get(0); + Type returnType = symbol.returnType().type(); + if(returnType.is(firstParameterType.fullyQualifiedName())) { + reportIssue(method.simpleName(), "Never do that!"); + } + } + + } +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheck.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheck.java new file mode 100644 index 0000000..c3fc929 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheck.java @@ -0,0 +1,51 @@ +package de.example.custom.java.checks; + +import java.util.List; + +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; +import org.sonar.check.Rule; +import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; +import org.sonar.plugins.java.api.JavaFileScannerContext; +import org.sonar.plugins.java.api.semantic.Symbol; +import org.sonar.plugins.java.api.tree.ClassTree; +import org.sonar.plugins.java.api.tree.Tree; +import org.sonar.plugins.java.api.tree.Tree.Kind; +import org.sonar.plugins.java.api.tree.VariableTree; + +import com.google.common.collect.ImmutableList; + +@Rule(key = "GU0002") +public class SpringServiceInstanceFieldCheck extends IssuableSubscriptionVisitor { + private static final Logger LOG = Loggers.get(SpringServiceInstanceFieldCheck.class); + + private JavaFileScannerContext context; + + + @Override + public List nodesToVisit() { + return ImmutableList.of(Kind.CLASS, Kind.VARIABLE); + } + + @Override + public void visitNode(Tree tree) { + if (tree.is(Kind.CLASS) && isSpringService((ClassTree) tree)) { + + } + + } + + + private static boolean isOwnedByASpringService(VariableTree variable) { + Symbol owner = variable.symbol().owner(); + return owner.isTypeSymbol() && (owner.type().isSubtypeOf("javax.servlet.http.HttpServlet") || owner.type().isSubtypeOf("org.apache.struts.action.Action")); + } + + private static boolean isSpringService(ClassTree tree) { + tree.symbol().metadata().isAnnotatedWith("javax.inject.Inject"); + return true; + + } + + +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomPlugin.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomPlugin.java deleted file mode 100644 index 79e245d..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomPlugin.java +++ /dev/null @@ -1,20 +0,0 @@ -package de.example.plugins.custom; - -import org.sonar.api.Plugin; - -import com.google.common.collect.ImmutableList; - - -public class CustomPlugin implements Plugin { - - @Override - public void define(Context context) { - - ImmutableList.Builder builder = ImmutableList.builder(); - builder.add( - CustomRulesDefinition.class, - CustomRulesCheckRegistrar.class); - - context.addExtensions(builder.build()); - } -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomProfile.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomProfile.java deleted file mode 100644 index 11ff95a..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomProfile.java +++ /dev/null @@ -1,70 +0,0 @@ -package de.example.plugins.custom; - -import java.io.IOException; -import java.net.URL; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.sonar.api.profiles.ProfileDefinition; -import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.utils.AnnotationUtils; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.java.checks.CheckList; -import org.sonar.plugins.java.Java; -import org.sonar.plugins.java.JavaRulesDefinition; - -import com.google.common.base.Charsets; -import com.google.common.io.Resources; -import com.google.gson.Gson; - -public class CustomProfile extends ProfileDefinition { - - private final Gson gson = new Gson(); - private final RuleFinder ruleFinder; - public CustomProfile(RuleFinder ruleFinder) { - this.ruleFinder = ruleFinder; - } - - @Override - public RulesProfile createProfile(ValidationMessages messages) { - RulesProfile profile = RulesProfile.create("Sonar way", Java.KEY); - URL resource = JavaRulesDefinition.class.getResource("/org/sonar/l10n/java/rules/custom/Custom_profile.json"); - Profile jsonProfile = gson.fromJson(readResource(resource), Profile.class); - Map keys = legacyKeys(); - for (String key : jsonProfile.ruleKeys) { - profile.activateRule(ruleFinder.findByKey(CheckList.REPOSITORY_KEY, keys.get(key)), null); - } - return profile; - } - - private static String readResource(URL resource) { - try { - return Resources.toString(resource, Charsets.UTF_8); - } catch (IOException e) { - throw new IllegalStateException("Failed to read: " + resource, e); - } - } - - private static Map legacyKeys() { - Map result = new HashMap<>(); - for (Class checkClass : CheckList.getChecks()) { - org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(checkClass, org.sonar.check.Rule.class); - String key = ruleAnnotation.key(); - org.sonar.java.RspecKey rspecKeyAnnotation = AnnotationUtils.getAnnotation(checkClass, org.sonar.java.RspecKey.class); - String rspecKey = key; - if(rspecKeyAnnotation != null) { - rspecKey = rspecKeyAnnotation.value(); - } - result.put(rspecKey, key); - } - return result; - } - - private static class Profile { - String name; - List ruleKeys; - } - - } diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomRulesCheckRegistrar.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomRulesCheckRegistrar.java deleted file mode 100644 index 670b1c1..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomRulesCheckRegistrar.java +++ /dev/null @@ -1,14 +0,0 @@ -package de.example.plugins.custom; - -import org.sonar.plugins.java.api.CheckRegistrar; - -import de.example.custom.checks.CheckList; - -public class CustomRulesCheckRegistrar implements CheckRegistrar { - - @Override - public void register(RegistrarContext registrarContext) { - registrarContext.registerClassesForRepository(CheckList.REPOSITORY_KEY, CheckList.getJavaChecks(), CheckList.getJavaTestChecks()); - } - -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomRulesDefinition.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomRulesDefinition.java deleted file mode 100644 index 012763b..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomRulesDefinition.java +++ /dev/null @@ -1,141 +0,0 @@ -package de.example.plugins.custom; - -import java.io.IOException; -import java.net.URL; -import java.util.List; - -import javax.annotation.Nullable; - -import org.apache.commons.lang.StringUtils; -import org.sonar.api.rule.RuleStatus; -import org.sonar.api.server.debt.DebtRemediationFunction; -import org.sonar.api.server.rule.RulesDefinition; -import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; -import org.sonar.api.utils.AnnotationUtils; -import org.sonar.check.Cardinality; -import org.sonar.plugins.java.Java; -import org.sonar.squidbridge.annotations.RuleTemplate; -import org.sonar.squidbridge.rules.ExternalDescriptionLoader; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Charsets; -import com.google.common.collect.Iterables; -import com.google.common.io.Resources; -import com.google.gson.Gson; - -import de.example.custom.checks.CheckList; - -/** - * Definition of rules. - */ -public class CustomRulesDefinition implements RulesDefinition { - private static final String RESOURCE_BASE_PATH = "/de/example/l10n/java/rules/custom"; - - private final Gson gson = new Gson(); - - @Override - public void define(Context context) { - NewRepository repository = context - .createRepository(CheckList.REPOSITORY_KEY, Java.KEY) - .setName(CheckList.REPOSITORY_NAME); - List checks = CheckList.getChecks(); - new RulesDefinitionAnnotationLoader().load(repository, Iterables.toArray(checks, Class.class)); - for (Class ruleClass : checks) { - newRule(ruleClass, repository); - } - repository.done(); - } - - @VisibleForTesting - protected void newRule(Class ruleClass, NewRepository repository) { - - org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.check.Rule.class); - if (ruleAnnotation == null) { - throw new IllegalArgumentException("No Rule annotation was found on " + ruleClass); - } - String ruleKey = ruleAnnotation.key(); - if (StringUtils.isEmpty(ruleKey)) { - throw new IllegalArgumentException("No key is defined in Rule annotation of " + ruleClass); - } - NewRule rule = repository.rule(ruleKey); - if (rule == null) { - throw new IllegalStateException("No rule was created for " + ruleClass + " in " + repository.key()); - } - rule.setTemplate(AnnotationUtils.getAnnotation(ruleClass, RuleTemplate.class) != null); - if (ruleAnnotation.cardinality() == Cardinality.MULTIPLE) { - throw new IllegalArgumentException("Cardinality is not supported, use the RuleTemplate annotation instead for " + ruleClass); - } - ruleMetadata(ruleClass, rule); - } - - private void ruleMetadata(Class ruleClass, NewRule rule) { - String metadataKey = rule.key(); - org.sonar.java.RspecKey rspecKeyAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.java.RspecKey.class); - if (rspecKeyAnnotation != null) { - metadataKey = rspecKeyAnnotation.value(); - rule.setInternalKey(metadataKey); - } - addHtmlDescription(rule, metadataKey); - addMetadata(rule, metadataKey); - - } - - private void addMetadata(NewRule rule, String metadataKey) { - URL resource = ExternalDescriptionLoader.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.json"); - if (resource != null) { - RuleMetatada metatada = gson.fromJson(readResource(resource), RuleMetatada.class); - rule.setSeverity(metatada.defaultSeverity.toUpperCase()); - rule.setName(metatada.title); - rule.addTags(metatada.tags); - rule.setStatus(RuleStatus.valueOf(metatada.status.toUpperCase())); - if(metatada.remediation != null) { - rule.setDebtRemediationFunction(metatada.remediation.remediationFunction(rule.debtRemediationFunctions())); - rule.setGapDescription(metatada.remediation.linearDesc); - } - } - } - - private static void addHtmlDescription(NewRule rule, String metadataKey) { - URL resource = CustomRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.html"); - if (resource != null) { - rule.setHtmlDescription(readResource(resource)); - } - } - - private static String readResource(URL resource) { - try { - return Resources.toString(resource, Charsets.UTF_8); - } catch (IOException e) { - throw new IllegalStateException("Failed to read: " + resource, e); - } - } - - private static class RuleMetatada { - String title; - String status; - @Nullable - Remediation remediation; - - String[] tags; - String defaultSeverity; - } - - private static class Remediation { - String func; - String constantCost; - String linearDesc; - String linearOffset; - String linearFactor; - - public DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) { - if(func.startsWith("Constant")) { - return drf.constantPerIssue(constantCost.replace("mn", "min")); - } - if("Linear".equals(func)) { - return drf.linear(linearFactor.replace("mn", "min")); - } - return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); - } - } - -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomSensor.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomSensor.java deleted file mode 100644 index 6d43f00..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/CustomSensor.java +++ /dev/null @@ -1,21 +0,0 @@ -package de.example.plugins.custom; - -import org.sonar.api.batch.sensor.Sensor; -import org.sonar.api.batch.sensor.SensorContext; -import org.sonar.api.batch.sensor.SensorDescriptor; -import org.sonar.plugins.java.Java; - -public class CustomSensor implements Sensor { - - @Override - public void describe(SensorDescriptor descriptor) { - descriptor.onlyOnLanguage(Java.KEY); - descriptor.name("Custom Sensor"); - } - - @Override - public void execute(SensorContext context) { - - } - -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomPlugin.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomPlugin.java new file mode 100644 index 0000000..399cfd7 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomPlugin.java @@ -0,0 +1,20 @@ +package de.example.plugins.custom.java; + +import org.sonar.api.Plugin; + +import com.google.common.collect.ImmutableList; + + +public class CustomPlugin implements Plugin { + + @Override + public void define(Context context) { + + ImmutableList.Builder builder = ImmutableList.builder(); + builder.add( + CustomRulesDefinition.class, + CustomRulesCheckRegistrar.class); + + context.addExtensions(builder.build()); + } +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomProfile.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomProfile.java new file mode 100644 index 0000000..a493c5d --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomProfile.java @@ -0,0 +1,70 @@ +package de.example.plugins.custom.java; + +import java.io.IOException; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.sonar.api.profiles.ProfileDefinition; +import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.rules.RuleFinder; +import org.sonar.api.utils.AnnotationUtils; +import org.sonar.api.utils.ValidationMessages; +import org.sonar.java.checks.CheckList; +import org.sonar.plugins.java.Java; +import org.sonar.plugins.java.JavaRulesDefinition; + +import com.google.common.base.Charsets; +import com.google.common.io.Resources; +import com.google.gson.Gson; + +public class CustomProfile extends ProfileDefinition { + + private final Gson gson = new Gson(); + private final RuleFinder ruleFinder; + public CustomProfile(RuleFinder ruleFinder) { + this.ruleFinder = ruleFinder; + } + + @Override + public RulesProfile createProfile(ValidationMessages messages) { + RulesProfile profile = RulesProfile.create("Sonar way", Java.KEY); + URL resource = JavaRulesDefinition.class.getResource("/org/sonar/l10n/java/rules/custom/Custom_profile.json"); + Profile jsonProfile = gson.fromJson(readResource(resource), Profile.class); + Map keys = legacyKeys(); + for (String key : jsonProfile.ruleKeys) { + profile.activateRule(ruleFinder.findByKey(CheckList.REPOSITORY_KEY, keys.get(key)), null); + } + return profile; + } + + private static String readResource(URL resource) { + try { + return Resources.toString(resource, Charsets.UTF_8); + } catch (IOException e) { + throw new IllegalStateException("Failed to read: " + resource, e); + } + } + + private static Map legacyKeys() { + Map result = new HashMap<>(); + for (Class checkClass : CheckList.getChecks()) { + org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(checkClass, org.sonar.check.Rule.class); + String key = ruleAnnotation.key(); + org.sonar.java.RspecKey rspecKeyAnnotation = AnnotationUtils.getAnnotation(checkClass, org.sonar.java.RspecKey.class); + String rspecKey = key; + if(rspecKeyAnnotation != null) { + rspecKey = rspecKeyAnnotation.value(); + } + result.put(rspecKey, key); + } + return result; + } + + private static class Profile { + String name; + List ruleKeys; + } + + } diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesCheckRegistrar.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesCheckRegistrar.java new file mode 100644 index 0000000..f17f649 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesCheckRegistrar.java @@ -0,0 +1,14 @@ +package de.example.plugins.custom.java; + +import org.sonar.plugins.java.api.CheckRegistrar; + +import de.example.custom.java.checks.CheckList; + +public class CustomRulesCheckRegistrar implements CheckRegistrar { + + @Override + public void register(RegistrarContext registrarContext) { + registrarContext.registerClassesForRepository(CheckList.REPOSITORY_KEY, CheckList.getJavaChecks(), CheckList.getJavaTestChecks()); + } + +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesDefinition.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesDefinition.java new file mode 100644 index 0000000..3b783d0 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomRulesDefinition.java @@ -0,0 +1,141 @@ +package de.example.plugins.custom.java; + +import java.io.IOException; +import java.net.URL; +import java.util.List; + +import javax.annotation.Nullable; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.rule.RuleStatus; +import org.sonar.api.server.debt.DebtRemediationFunction; +import org.sonar.api.server.rule.RulesDefinition; +import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; +import org.sonar.api.utils.AnnotationUtils; +import org.sonar.check.Cardinality; +import org.sonar.plugins.java.Java; +import org.sonar.squidbridge.annotations.RuleTemplate; +import org.sonar.squidbridge.rules.ExternalDescriptionLoader; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Charsets; +import com.google.common.collect.Iterables; +import com.google.common.io.Resources; +import com.google.gson.Gson; + +import de.example.custom.java.checks.CheckList; + +/** + * Definition of rules. + */ +public class CustomRulesDefinition implements RulesDefinition { + private static final String RESOURCE_BASE_PATH = "/de/example/l10n/java/rules/custom"; + + private final Gson gson = new Gson(); + + @Override + public void define(Context context) { + NewRepository repository = context + .createRepository(CheckList.REPOSITORY_KEY, Java.KEY) + .setName(CheckList.REPOSITORY_NAME); + List checks = CheckList.getChecks(); + new RulesDefinitionAnnotationLoader().load(repository, Iterables.toArray(checks, Class.class)); + for (Class ruleClass : checks) { + newRule(ruleClass, repository); + } + repository.done(); + } + + @VisibleForTesting + protected void newRule(Class ruleClass, NewRepository repository) { + + org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.check.Rule.class); + if (ruleAnnotation == null) { + throw new IllegalArgumentException("No Rule annotation was found on " + ruleClass); + } + String ruleKey = ruleAnnotation.key(); + if (StringUtils.isEmpty(ruleKey)) { + throw new IllegalArgumentException("No key is defined in Rule annotation of " + ruleClass); + } + NewRule rule = repository.rule(ruleKey); + if (rule == null) { + throw new IllegalStateException("No rule was created for " + ruleClass + " in " + repository.key()); + } + rule.setTemplate(AnnotationUtils.getAnnotation(ruleClass, RuleTemplate.class) != null); + if (ruleAnnotation.cardinality() == Cardinality.MULTIPLE) { + throw new IllegalArgumentException("Cardinality is not supported, use the RuleTemplate annotation instead for " + ruleClass); + } + ruleMetadata(ruleClass, rule); + } + + private void ruleMetadata(Class ruleClass, NewRule rule) { + String metadataKey = rule.key(); + org.sonar.java.RspecKey rspecKeyAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.java.RspecKey.class); + if (rspecKeyAnnotation != null) { + metadataKey = rspecKeyAnnotation.value(); + rule.setInternalKey(metadataKey); + } + addHtmlDescription(rule, metadataKey); + addMetadata(rule, metadataKey); + + } + + private void addMetadata(NewRule rule, String metadataKey) { + URL resource = ExternalDescriptionLoader.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.json"); + if (resource != null) { + RuleMetatada metatada = gson.fromJson(readResource(resource), RuleMetatada.class); + rule.setSeverity(metatada.defaultSeverity.toUpperCase()); + rule.setName(metatada.title); + rule.addTags(metatada.tags); + rule.setStatus(RuleStatus.valueOf(metatada.status.toUpperCase())); + if(metatada.remediation != null) { + rule.setDebtRemediationFunction(metatada.remediation.remediationFunction(rule.debtRemediationFunctions())); + rule.setGapDescription(metatada.remediation.linearDesc); + } + } + } + + private static void addHtmlDescription(NewRule rule, String metadataKey) { + URL resource = CustomRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.html"); + if (resource != null) { + rule.setHtmlDescription(readResource(resource)); + } + } + + private static String readResource(URL resource) { + try { + return Resources.toString(resource, Charsets.UTF_8); + } catch (IOException e) { + throw new IllegalStateException("Failed to read: " + resource, e); + } + } + + private static class RuleMetatada { + String title; + String status; + @Nullable + Remediation remediation; + + String[] tags; + String defaultSeverity; + } + + private static class Remediation { + String func; + String constantCost; + String linearDesc; + String linearOffset; + String linearFactor; + + public DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) { + if(func.startsWith("Constant")) { + return drf.constantPerIssue(constantCost.replace("mn", "min")); + } + if("Linear".equals(func)) { + return drf.linear(linearFactor.replace("mn", "min")); + } + return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); + } + } + +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomSensor.java b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomSensor.java new file mode 100644 index 0000000..d34c92f --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/main/java/de/example/plugins/custom/java/CustomSensor.java @@ -0,0 +1,21 @@ +package de.example.plugins.custom.java; + +import org.sonar.api.batch.sensor.Sensor; +import org.sonar.api.batch.sensor.SensorContext; +import org.sonar.api.batch.sensor.SensorDescriptor; +import org.sonar.plugins.java.Java; + +public class CustomSensor implements Sensor { + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.onlyOnLanguage(Java.KEY); + descriptor.name("Custom Sensor"); + } + + @Override + public void execute(SensorContext context) { + + } + +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/checks/ParameterCheckTest.java b/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/checks/ParameterCheckTest.java deleted file mode 100644 index 9ef2880..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/checks/ParameterCheckTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package de.example.custom.checks; - -import org.junit.Test; -import org.sonar.java.checks.verifier.JavaCheckVerifier; - -public class ParameterCheckTest { - - @Test - public void test() { - JavaCheckVerifier.verify("src/test/files/checks/ParameterCheck.java", new ParameterCheck()); - } -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/checks/SpringServiceInstanceFieldCheckTest.java b/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/checks/SpringServiceInstanceFieldCheckTest.java deleted file mode 100644 index 973e3c7..0000000 --- a/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/checks/SpringServiceInstanceFieldCheckTest.java +++ /dev/null @@ -1,13 +0,0 @@ -package de.example.custom.checks; - -import org.junit.Test; -import org.sonar.java.checks.verifier.JavaCheckVerifier; - -public class SpringServiceInstanceFieldCheckTest { - private static final String FILENAME = "src/test/files/checks/SpringServiceInstanceFieldCheck.java"; - - //@Test - public void test() { - JavaCheckVerifier.verify(FILENAME, new SpringServiceInstanceFieldCheck()); - } -} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/java/checks/ParameterCheckTest.java b/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/java/checks/ParameterCheckTest.java new file mode 100644 index 0000000..4c60044 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/java/checks/ParameterCheckTest.java @@ -0,0 +1,12 @@ +package de.example.custom.java.checks; + +import org.junit.Test; +import org.sonar.java.checks.verifier.JavaCheckVerifier; + +public class ParameterCheckTest { + + @Test + public void test() { + JavaCheckVerifier.verify("src/test/files/checks/ParameterCheck.java", new ParameterCheck()); + } +} diff --git a/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheckTest.java b/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheckTest.java new file mode 100644 index 0000000..aab3549 --- /dev/null +++ b/Sonar/Plugins/sonar-custom-java-plugin/src/test/java/de/example/custom/java/checks/SpringServiceInstanceFieldCheckTest.java @@ -0,0 +1,13 @@ +package de.example.custom.java.checks; + +import org.junit.Test; +import org.sonar.java.checks.verifier.JavaCheckVerifier; + +public class SpringServiceInstanceFieldCheckTest { + private static final String FILENAME = "src/test/files/checks/SpringServiceInstanceFieldCheck.java"; + + //@Test + public void test() { + JavaCheckVerifier.verify(FILENAME, new SpringServiceInstanceFieldCheck()); + } +}