From 7ca495d67492c6b3dbb653102e345f8fc43f09ae Mon Sep 17 00:00:00 2001 From: simonbrandhof Date: Fri, 8 Oct 2010 14:38:32 +0000 Subject: [PATCH] API: improve the pattern to define quality profiles. The extension point is org.sonar.api.profiles.ProfileDefinition, whereas XMLProfileParser and AnnotationProfileParser are components that can be used but not extended. --- .../plugins/checkstyle/SonarWayProfile.java | 18 ++- .../SonarWayWithFindbugsProfile.java | 3 - .../checkstyle/SunConventionsProfile.java | 20 ++- .../checkstyle/SonarWayProfileTest.java | 5 +- .../SonarWayWithFindbugsProfileTest.java | 7 +- .../checkstyle/SunConventionsProfileTest.java | 5 +- .../findbugs/FindbugsRuleRepository.java | 10 +- .../SonarWayWithFindbugsProfileTest.java | 2 +- .../plugins/pmd/SonarWayProfileTest.java | 2 +- .../pmd/SonarWayWithFindbugsProfileTest.java | 2 +- .../pmd/SunConventionsProfileTest.java | 2 +- ...tion.java => AnnotationProfileParser.java} | 37 ++--- .../sonar/api/profiles/ProfileDefinition.java | 3 + .../api/profiles/XMLProfileDefinition.java | 58 -------- ...ileImporter.java => XMLProfileParser.java} | 21 ++- ...xporter.java => XMLProfileSerializer.java} | 9 +- .../api/qualitymodel/ModelDefinition.java | 2 +- .../AnnotationProfileDefinitionTest.java | 74 ---------- .../profiles/AnnotationProfileParserTest.java | 85 ++++++++++++ .../api/profiles/XMLProfileImporterTest.java | 131 ------------------ .../api/profiles/XMLProfileParserTest.java | 104 ++++++++++++++ ...est.java => XMLProfileSerializerTest.java} | 16 +-- .../importProfile.xml | 0 .../importProfileWithRuleParameters.xml | 0 .../importProfileWithUnknownRuleParameter.xml | 0 .../nameAndLanguageShouldBeMandatory.xml | 0 .../exportEmptyProfile.xml | 0 .../exportProfile.xml | 0 .../exportRuleParameters.xml | 0 .../org/sonar/server/platform/Platform.java | 6 + .../qualitymodel/DefaultModelManager.java | 4 +- .../sonar/server/rules/ProfilesConsole.java | 12 +- .../startup/RegisterProvidedProfiles.java | 5 +- .../qualitymodel/DefaultModelManagerTest.java | 2 +- .../server/rules/DeprecatedProfilesTest.java | 3 +- 35 files changed, 297 insertions(+), 351 deletions(-) rename sonar-plugin-api/src/main/java/org/sonar/api/profiles/{AnnotationProfileDefinition.java => AnnotationProfileParser.java} (55%) delete mode 100644 sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileDefinition.java rename sonar-plugin-api/src/main/java/org/sonar/api/profiles/{XMLProfileImporter.java => XMLProfileParser.java} (89%) rename sonar-plugin-api/src/main/java/org/sonar/api/profiles/{XMLProfileExporter.java => XMLProfileSerializer.java} (94%) delete mode 100644 sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileDefinitionTest.java create mode 100644 sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileParserTest.java delete mode 100644 sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileImporterTest.java create mode 100644 sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileParserTest.java rename sonar-plugin-api/src/test/java/org/sonar/api/profiles/{XMLProfileExporterTest.java => XMLProfileSerializerTest.java} (82%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileImporterTest => XMLProfileParserTest}/importProfile.xml (100%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileImporterTest => XMLProfileParserTest}/importProfileWithRuleParameters.xml (100%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileImporterTest => XMLProfileParserTest}/importProfileWithUnknownRuleParameter.xml (100%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileImporterTest => XMLProfileParserTest}/nameAndLanguageShouldBeMandatory.xml (100%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileExporterTest => XMLProfileSerializerTest}/exportEmptyProfile.xml (100%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileExporterTest => XMLProfileSerializerTest}/exportProfile.xml (100%) rename sonar-plugin-api/src/test/resources/org/sonar/api/profiles/{XMLProfileExporterTest => XMLProfileSerializerTest}/exportRuleParameters.xml (100%) diff --git a/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayProfile.java b/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayProfile.java index a189560a695..a0cf3410ce0 100644 --- a/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayProfile.java +++ b/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayProfile.java @@ -19,14 +19,20 @@ */ package org.sonar.plugins.checkstyle; +import org.sonar.api.profiles.ProfileDefinition; import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.profiles.XMLProfileDefinition; -import org.sonar.api.resources.Java; -import org.sonar.api.rules.RuleFinder; +import org.sonar.api.profiles.XMLProfileParser; +import org.sonar.api.utils.ValidationMessages; -public final class SonarWayProfile extends XMLProfileDefinition { +public final class SonarWayProfile extends ProfileDefinition { - public SonarWayProfile(RuleFinder ruleFinder) { - super(SunConventionsProfile.class.getClassLoader(), "org/sonar/plugins/checkstyle/profile-sonar-way.xml", ruleFinder); + private XMLProfileParser xmlProfileParser; + + public SonarWayProfile(XMLProfileParser xmlProfileParser) { + this.xmlProfileParser = xmlProfileParser; + } + + public RulesProfile createProfile(ValidationMessages messages) { + return xmlProfileParser.parseResource(getClass().getClassLoader(), "org/sonar/plugins/checkstyle/profile-sonar-way.xml", messages); } } diff --git a/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfile.java b/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfile.java index 398f137c451..d9b26e2b43f 100644 --- a/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfile.java +++ b/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfile.java @@ -21,9 +21,6 @@ package org.sonar.plugins.checkstyle; import org.sonar.api.profiles.ProfileDefinition; import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.profiles.XMLProfileDefinition; -import org.sonar.api.resources.Java; -import org.sonar.api.rules.RuleFinder; import org.sonar.api.utils.ValidationMessages; public class SonarWayWithFindbugsProfile extends ProfileDefinition { diff --git a/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SunConventionsProfile.java b/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SunConventionsProfile.java index 6351afed31c..82b0e8b7177 100644 --- a/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SunConventionsProfile.java +++ b/plugins/sonar-checkstyle-plugin/src/main/java/org/sonar/plugins/checkstyle/SunConventionsProfile.java @@ -19,14 +19,22 @@ */ package org.sonar.plugins.checkstyle; +import org.sonar.api.profiles.ProfileDefinition; import org.sonar.api.profiles.RulesProfile; -import org.sonar.api.profiles.XMLProfileDefinition; -import org.sonar.api.resources.Java; -import org.sonar.api.rules.RuleFinder; +import org.sonar.api.profiles.XMLProfileParser; +import org.sonar.api.utils.ValidationMessages; -public final class SunConventionsProfile extends XMLProfileDefinition { +public final class SunConventionsProfile extends ProfileDefinition { - public SunConventionsProfile(RuleFinder ruleFinder) { - super(SunConventionsProfile.class.getClassLoader(), "org/sonar/plugins/checkstyle/profile-sun-conventions.xml", ruleFinder); + private XMLProfileParser xmlProfileParser; + + public SunConventionsProfile(XMLProfileParser xmlProfileParser) { + this.xmlProfileParser = xmlProfileParser; } + + + public RulesProfile createProfile(ValidationMessages messages) { + return xmlProfileParser.parseResource(getClass().getClassLoader(), "org/sonar/plugins/checkstyle/profile-sun-conventions.xml", messages); + } + } diff --git a/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayProfileTest.java b/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayProfileTest.java index 268f94fe15b..23a39650517 100644 --- a/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayProfileTest.java +++ b/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayProfileTest.java @@ -24,6 +24,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.sonar.api.profiles.ProfileDefinition; import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.profiles.XMLProfileParser; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.utils.ValidationMessages; @@ -38,8 +39,8 @@ import static org.mockito.Mockito.when; public class SonarWayProfileTest { @Test - public void create() { - ProfileDefinition sonarWay = new SonarWayProfile(newRuleFinder()); + public void shouldCreateProfile() { + ProfileDefinition sonarWay = new SonarWayProfile(new XMLProfileParser(newRuleFinder())); ValidationMessages validation = ValidationMessages.create(); RulesProfile profile = sonarWay.createProfile(validation); assertThat(profile.getActiveRulesByRepository(CheckstyleConstants.REPOSITORY_KEY).size(), greaterThan(1)); diff --git a/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfileTest.java b/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfileTest.java index 6ed6bbca83c..d5af6c0b236 100644 --- a/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfileTest.java +++ b/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SonarWayWithFindbugsProfileTest.java @@ -23,11 +23,12 @@ import org.junit.Test; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.profiles.XMLProfileParser; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.utils.ValidationMessages; -import static org.hamcrest.core.Is.is; +import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.mock; @@ -36,9 +37,9 @@ import static org.mockito.Mockito.when; public class SonarWayWithFindbugsProfileTest { @Test - public void sameAsSonarWay() { + public void shouldBeSameAsSonarWay() { RuleFinder ruleFinder = newRuleFinder(); - SonarWayProfile sonarWay = new SonarWayProfile(ruleFinder); + SonarWayProfile sonarWay = new SonarWayProfile(new XMLProfileParser(ruleFinder)); RulesProfile withoutFindbugs = sonarWay.createProfile(ValidationMessages.create()); RulesProfile withFindbugs = new SonarWayWithFindbugsProfile(sonarWay).createProfile(ValidationMessages.create()); assertThat(withFindbugs.getActiveRules().size(), is(withoutFindbugs.getActiveRules().size())); diff --git a/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SunConventionsProfileTest.java b/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SunConventionsProfileTest.java index ff80d97a02e..147006e30eb 100644 --- a/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SunConventionsProfileTest.java +++ b/plugins/sonar-checkstyle-plugin/src/test/java/org/sonar/plugins/checkstyle/SunConventionsProfileTest.java @@ -25,6 +25,7 @@ import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; import org.sonar.api.profiles.ProfileDefinition; import org.sonar.api.profiles.RulesProfile; +import org.sonar.api.profiles.XMLProfileParser; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.utils.ValidationMessages; @@ -37,8 +38,8 @@ import static org.mockito.Mockito.when; public class SunConventionsProfileTest { @Test - public void create() { - ProfileDefinition definition = new SunConventionsProfile(newRuleFinder()); + public void shouldCreateProfile() { + ProfileDefinition definition = new SunConventionsProfile(new XMLProfileParser(newRuleFinder())); ValidationMessages validation = ValidationMessages.create(); RulesProfile sunProfile = definition.createProfile(validation); assertThat(sunProfile.getActiveRulesByRepository(CheckstyleConstants.REPOSITORY_KEY).size(), greaterThan(1)); diff --git a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsRuleRepository.java b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsRuleRepository.java index bf4b11febb6..0f43b2cd4d2 100644 --- a/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsRuleRepository.java +++ b/plugins/sonar-findbugs-plugin/src/main/java/org/sonar/plugins/findbugs/FindbugsRuleRepository.java @@ -19,15 +19,13 @@ */ package org.sonar.plugins.findbugs; -import java.util.ArrayList; -import java.util.List; - -import org.sonar.api.platform.ServerFileSystem; import org.sonar.api.resources.Java; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleRepository; import org.sonar.api.rules.XMLRuleParser; +import java.util.List; + public final class FindbugsRuleRepository extends RuleRepository { public FindbugsRuleRepository() { @@ -37,8 +35,6 @@ public final class FindbugsRuleRepository extends RuleRepository { @Override public List createRules() { - List rules = new ArrayList(); - rules.addAll(XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/plugins/findbugs/rules.xml"))); - return rules; + return XMLRuleParser.parseXML(getClass().getResourceAsStream("/org/sonar/plugins/findbugs/rules.xml")); } } diff --git a/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/SonarWayWithFindbugsProfileTest.java b/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/SonarWayWithFindbugsProfileTest.java index 0d1e3b73112..881fbf9a36b 100644 --- a/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/SonarWayWithFindbugsProfileTest.java +++ b/plugins/sonar-findbugs-plugin/src/test/java/org/sonar/plugins/findbugs/SonarWayWithFindbugsProfileTest.java @@ -30,7 +30,7 @@ import org.sonar.api.utils.ValidationMessages; public class SonarWayWithFindbugsProfileTest { @Test - public void create() { + public void shouldCreateProfile() { FindbugsProfileImporter importer = new FindbugsProfileImporter(new FindbugsRuleFinder()); SonarWayWithFindbugsProfile sonarWayWithFindbugs = new SonarWayWithFindbugsProfile(importer); ValidationMessages validation = ValidationMessages.create(); diff --git a/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java b/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java index 966021adfc4..844dfa9100e 100644 --- a/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java +++ b/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayProfileTest.java @@ -40,7 +40,7 @@ import org.sonar.api.utils.ValidationMessages; public class SonarWayProfileTest { @Test - public void create() { + public void shouldCreateProfile() { ProfileDefinition sonarWay = new SonarWayProfile(createPmdProfileImporter()); ValidationMessages validation = ValidationMessages.create(); RulesProfile profile = sonarWay.createProfile(validation); diff --git a/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java b/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java index 95f8ffc4592..7f0aa81c969 100644 --- a/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java +++ b/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SonarWayWithFindbugsProfileTest.java @@ -39,7 +39,7 @@ import org.sonar.api.utils.ValidationMessages; public class SonarWayWithFindbugsProfileTest { @Test - public void create() { + public void shouldCreateProfile() { SonarWayWithFindbugsProfile sonarWayWithFindbugs = new SonarWayWithFindbugsProfile(new SonarWayProfile(createPmdProfileImporter())); ValidationMessages validation = ValidationMessages.create(); RulesProfile profile = sonarWayWithFindbugs.createProfile(validation); diff --git a/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java b/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java index bd9a6f9fffb..cdd9f1e396d 100644 --- a/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java +++ b/plugins/sonar-pmd-plugin/src/test/java/org/sonar/plugins/pmd/SunConventionsProfileTest.java @@ -38,7 +38,7 @@ import org.sonar.api.utils.ValidationMessages; public class SunConventionsProfileTest { @Test - public void create() { + public void shouldCreateProfile() { SunConventionsProfile sunConvention = new SunConventionsProfile(createPmdProfileImporter()); ValidationMessages validation = ValidationMessages.create(); RulesProfile profile = sunConvention.createProfile(validation); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/AnnotationProfileDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/AnnotationProfileParser.java similarity index 55% rename from sonar-plugin-api/src/main/java/org/sonar/api/profiles/AnnotationProfileDefinition.java rename to sonar-plugin-api/src/main/java/org/sonar/api/profiles/AnnotationProfileParser.java index a5cbf14f06f..5fc713eecf1 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/AnnotationProfileDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/AnnotationProfileParser.java @@ -19,6 +19,8 @@ */ package org.sonar.api.profiles; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.ServerComponent; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleAnnotationUtils; import org.sonar.api.rules.RuleFinder; @@ -31,45 +33,34 @@ import java.util.Collection; /** * @since 2.3 */ -public abstract class AnnotationProfileDefinition extends ProfileDefinition { +public final class AnnotationProfileParser implements ServerComponent { - private String name; - private String language; - private String repositoryKey; - private Collection annotatedClasses; private RuleFinder ruleFinder; - protected AnnotationProfileDefinition(String repositoryKey, String profileName, String language, Collection annotatedClasses, RuleFinder ruleFinder) { - this.name = profileName; - this.language = language; - this.repositoryKey = repositoryKey; - this.annotatedClasses = annotatedClasses; + public AnnotationProfileParser(RuleFinder ruleFinder) { this.ruleFinder = ruleFinder; } - @Override - public RulesProfile createProfile(ValidationMessages validation) { - RulesProfile profile = RulesProfile.create(name, language); - if (annotatedClasses != null) { - for (Class aClass : annotatedClasses) { - BelongsToProfile belongsToProfile = (BelongsToProfile) aClass.getAnnotation(BelongsToProfile.class); - registerRule(aClass, belongsToProfile, profile, validation); - } + public RulesProfile parse(String repositoryKey, String profileName, String language, Collection annotatedClasses, ValidationMessages messages) { + RulesProfile profile = RulesProfile.create(profileName, language); + for (Class aClass : annotatedClasses) { + BelongsToProfile belongsToProfile = (BelongsToProfile) aClass.getAnnotation(BelongsToProfile.class); + addRule(aClass, belongsToProfile, profile, repositoryKey, messages); } return profile; } - private void registerRule(Class aClass, BelongsToProfile belongsToProfile, RulesProfile profile, ValidationMessages validation) { - if (belongsToProfile != null) { + private void addRule(Class aClass, BelongsToProfile annotation, RulesProfile profile, String repositoryKey, ValidationMessages messages) { + if (annotation != null && StringUtils.equals(annotation.title(), profile.getName())) { String ruleKey = RuleAnnotationUtils.getRuleKey(aClass); Rule rule = ruleFinder.findByKey(repositoryKey, ruleKey); if (rule == null) { - validation.addErrorText("Rule not found: [repository=" + repositoryKey + ", key=" + ruleKey + "]"); + messages.addWarningText("Rule not found: [repository=" + repositoryKey + ", key=" + ruleKey + "]"); } else { RulePriority priority = null; - if (belongsToProfile.priority() != null) { - priority = RulePriority.fromCheckPriority(belongsToProfile.priority()); + if (annotation.priority() != null) { + priority = RulePriority.fromCheckPriority(annotation.priority()); } profile.activateRule(rule, priority); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/ProfileDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/ProfileDefinition.java index e37343a9abf..69aa3c99b73 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/ProfileDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/ProfileDefinition.java @@ -23,6 +23,9 @@ import org.sonar.api.ServerExtension; import org.sonar.api.utils.ValidationMessages; /** + * Define a profile which is automatically registered during sonar startup. + * The components AnnotationProfileParser and XMLProfileParser can be used to help implementing the method create(). + * * @since 2.3 */ public abstract class ProfileDefinition implements ServerExtension { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileDefinition.java deleted file mode 100644 index 9cbbe4eaa1b..00000000000 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileDefinition.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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.api.profiles; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.CharEncoding; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.utils.SonarException; -import org.sonar.api.utils.ValidationMessages; - -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.Charset; -import java.util.List; - -/** - * @since 2.3 - */ -public abstract class XMLProfileDefinition extends ProfileDefinition { - - private RuleFinder ruleFinder; - private ClassLoader classloader; - private String xmlClassPath; - - protected XMLProfileDefinition(ClassLoader classloader, String xmlClassPath, RuleFinder ruleFinder) { - this.ruleFinder = ruleFinder; - this.classloader = classloader; - this.xmlClassPath = xmlClassPath; - } - - @Override - public final RulesProfile createProfile(ValidationMessages validation) { - Reader reader = new InputStreamReader(classloader.getResourceAsStream(xmlClassPath), Charset.forName(CharEncoding.UTF_8)); - try { - return XMLProfileImporter.create(ruleFinder).importProfile(reader, validation); - - } finally { - IOUtils.closeQuietly(reader); - } - } -} diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileImporter.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileParser.java similarity index 89% rename from sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileImporter.java rename to sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileParser.java index 3a13d82b8b0..571e2fd6d9b 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileImporter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileParser.java @@ -19,11 +19,14 @@ */ package org.sonar.api.profiles; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.CharEncoding; import org.apache.commons.lang.StringUtils; import org.codehaus.stax2.XMLInputFactory2; import org.codehaus.staxmate.SMInputFactory; import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; +import org.sonar.api.ServerComponent; import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; @@ -32,26 +35,34 @@ import org.sonar.api.utils.ValidationMessages; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; +import java.io.InputStreamReader; import java.io.Reader; +import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; /** * @since 2.3 */ -public final class XMLProfileImporter { +public final class XMLProfileParser implements ServerComponent { private RuleFinder ruleFinder; - private XMLProfileImporter(RuleFinder ruleFinder) { + public XMLProfileParser(RuleFinder ruleFinder) { this.ruleFinder = ruleFinder; } - public static XMLProfileImporter create(RuleFinder ruleFinder) { - return new XMLProfileImporter(ruleFinder); + public RulesProfile parseResource(ClassLoader classloader, String xmlClassPath, ValidationMessages messages) { + Reader reader = new InputStreamReader(classloader.getResourceAsStream(xmlClassPath), Charset.forName(CharEncoding.UTF_8)); + try { + return parse(reader, messages); + + } finally { + IOUtils.closeQuietly(reader); + } } - public RulesProfile importProfile(Reader reader, ValidationMessages messages) { + public RulesProfile parse(Reader reader, ValidationMessages messages) { RulesProfile profile = RulesProfile.create(); SMInputFactory inputFactory = initStax(); try { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileExporter.java b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileSerializer.java similarity index 94% rename from sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileExporter.java rename to sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileSerializer.java index ee78f365cbe..e670002e968 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileExporter.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/profiles/XMLProfileSerializer.java @@ -21,6 +21,7 @@ package org.sonar.api.profiles; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; +import org.sonar.api.ServerComponent; import org.sonar.api.rules.ActiveRule; import org.sonar.api.rules.ActiveRuleParam; import org.sonar.api.utils.SonarException; @@ -31,13 +32,9 @@ import java.io.Writer; /** * @since 2.3 */ -public final class XMLProfileExporter { +public final class XMLProfileSerializer implements ServerComponent { - public static XMLProfileExporter create() { - return new XMLProfileExporter(); - } - - public void exportProfile(RulesProfile profile, Writer writer) { + public void write(RulesProfile profile, Writer writer) { try { appendHeader(profile, writer); appendRules(profile, writer); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/qualitymodel/ModelDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/qualitymodel/ModelDefinition.java index 416059c0cad..6a8eb7aaf7c 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/qualitymodel/ModelDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/qualitymodel/ModelDefinition.java @@ -41,7 +41,7 @@ public abstract class ModelDefinition implements ServerExtension { return name; } - public abstract Model create(); + public abstract Model createModel(); @Override public final boolean equals(Object o) { diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileDefinitionTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileDefinitionTest.java deleted file mode 100644 index 45e6bee0be0..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileDefinitionTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * 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.api.profiles; - -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.rules.RulePriority; -import org.sonar.api.utils.ValidationMessages; -import org.sonar.check.BelongsToProfile; -import org.sonar.check.Check; -import org.sonar.check.IsoCategory; -import org.sonar.check.Priority; - -import java.util.Arrays; -import java.util.Collection; - -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class AnnotationProfileDefinitionTest { - - @Test - public void importProfile() { - RuleFinder ruleFinder = mock(RuleFinder.class); - when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer(){ - public Rule answer(InvocationOnMock iom) throws Throwable { - return Rule.create((String)iom.getArguments()[0], (String)iom.getArguments()[1], (String)iom.getArguments()[1]); - } - }); - - ProfileDefinition definition = new FakeDefinition(ruleFinder); - ValidationMessages validation = ValidationMessages.create(); - RulesProfile profile = definition.createProfile(validation); - assertThat(profile.getActiveRule("squid", "fake").getPriority(), is(RulePriority.BLOCKER)); - assertThat(validation.hasErrors(), is(false)); - } -} - -@BelongsToProfile(title = "not used !", priority = Priority.BLOCKER) -@Check(key = "fake", isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL) -class FakeRule { - -} - - -class FakeDefinition extends AnnotationProfileDefinition { - - public FakeDefinition(RuleFinder ruleFinder) { - super("squid", "sonar way", "java", Arrays.asList(FakeRule.class), ruleFinder); - } -} \ No newline at end of file diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileParserTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileParserTest.java new file mode 100644 index 00000000000..a6d0c6a0a90 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/AnnotationProfileParserTest.java @@ -0,0 +1,85 @@ +/* + * 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.api.profiles; + +import com.google.common.collect.Lists; +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleFinder; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.utils.ValidationMessages; +import org.sonar.check.BelongsToProfile; +import org.sonar.check.IsoCategory; +import org.sonar.check.Priority; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.*; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class AnnotationProfileParserTest { + + @Test + public void shouldParseAnnotatedClasses() { + RuleFinder ruleFinder = mock(RuleFinder.class); + when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer() { + public Rule answer(InvocationOnMock iom) throws Throwable { + return Rule.create((String) iom.getArguments()[0], (String) iom.getArguments()[1], (String) iom.getArguments()[1]); + } + }); + + ValidationMessages messages = ValidationMessages.create(); + RulesProfile profile = new AnnotationProfileParser(ruleFinder).parse("squid", "Foo way", "java", Lists.newArrayList(FakeRule.class), messages); + + assertThat(profile.getName(), is("Foo way")); + assertThat(profile.getLanguage(), is("java")); + assertThat(profile.getActiveRule("squid", "fake").getPriority(), is(RulePriority.BLOCKER)); + assertThat(messages.hasErrors(), is(false)); + } + + @Test + public void shouldParseOnlyWantedProfile() { + RuleFinder ruleFinder = mock(RuleFinder.class); + when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer() { + public Rule answer(InvocationOnMock iom) throws Throwable { + return Rule.create((String) iom.getArguments()[0], (String) iom.getArguments()[1], (String) iom.getArguments()[1]); + } + }); + + ValidationMessages messages = ValidationMessages.create(); + RulesProfile profile = new AnnotationProfileParser(ruleFinder).parse("squid", "Foo way", "java", Lists.newArrayList(FakeRule.class, RuleOnOtherProfile.class), messages); + + assertNotNull(profile.getActiveRule("squid", "fake")); + assertNull(profile.getActiveRule("squid", "other")); + } +} + +@BelongsToProfile(title = "Other profile", priority = Priority.BLOCKER) +@org.sonar.check.Rule(key = "other", isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL) +class RuleOnOtherProfile { +} + +@BelongsToProfile(title = "Foo way", priority = Priority.BLOCKER) +@org.sonar.check.Rule(key = "fake", isoCategory = IsoCategory.Efficiency, priority = Priority.CRITICAL) +class FakeRule { +} diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileImporterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileImporterTest.java deleted file mode 100644 index 6358f1d08c3..00000000000 --- a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileImporterTest.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * 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.api.profiles; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.CharEncoding; -import org.junit.Test; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.stubbing.Answer; -import org.sonar.api.rules.ActiveRule; -import org.sonar.api.rules.Rule; -import org.sonar.api.rules.RuleFinder; -import org.sonar.api.rules.RulePriority; -import org.sonar.api.utils.ValidationMessages; - -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.UnsupportedEncodingException; - -import static org.hamcrest.CoreMatchers.nullValue; -import static org.hamcrest.Matchers.is; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.StringContains.containsString; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class XMLProfileImporterTest { - - @Test - public void importProfile() throws UnsupportedEncodingException { - Reader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/profiles/XMLProfileImporterTest/importProfile.xml"), CharEncoding.UTF_8); - try { - ValidationMessages validation = ValidationMessages.create(); - RuleFinder ruleFinder = newRuleFinder(); - RulesProfile profile = XMLProfileImporter.create(ruleFinder).importProfile(reader, validation); - - assertThat(profile.getLanguage(), is("java")); - assertThat(profile.getName(), is("sonar way")); - assertThat(validation.hasErrors(), is(false)); - assertNotNull(profile); - assertThat(profile.getActiveRule("checkstyle", "IllegalRegexp").getPriority(), is(RulePriority.CRITICAL)); - - } finally { - IOUtils.closeQuietly(reader); - } - } - - @Test - public void nameAndLanguageShouldBeMandatory() throws UnsupportedEncodingException { - Reader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/profiles/XMLProfileImporterTest/nameAndLanguageShouldBeMandatory.xml"), CharEncoding.UTF_8); - try { - ValidationMessages validation = ValidationMessages.create(); - RuleFinder ruleFinder = newRuleFinder(); - RulesProfile profile = XMLProfileImporter.create(ruleFinder).importProfile(reader, validation); - - assertThat(validation.getErrors().size(), is(2)); - assertThat(validation.getErrors().get(0) , containsString("")); - - } finally { - IOUtils.closeQuietly(reader); - } - } - - @Test - public void importProfileWithRuleParameters() throws UnsupportedEncodingException { - Reader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/profiles/XMLProfileImporterTest/importProfileWithRuleParameters.xml"), CharEncoding.UTF_8); - try { - ValidationMessages validation = ValidationMessages.create(); - RuleFinder ruleFinder = newRuleFinder(); - RulesProfile profile = XMLProfileImporter.create(ruleFinder).importProfile(reader, validation); - - assertThat(validation.hasErrors(), is(false)); - assertThat(validation.hasWarnings(), is(false)); - ActiveRule rule = profile.getActiveRule("checkstyle", "IllegalRegexp"); - assertThat(rule.getParameter("format"), is("foo")); - assertThat(rule.getParameter("message"), is("with special characters < > &")); - - } finally { - IOUtils.closeQuietly(reader); - } - } - - @Test - public void importProfileWithUnknownRuleParameter() throws UnsupportedEncodingException { - Reader reader = new InputStreamReader(getClass().getResourceAsStream("/org/sonar/api/profiles/XMLProfileImporterTest/importProfileWithUnknownRuleParameter.xml"), CharEncoding.UTF_8); - try { - ValidationMessages validation = ValidationMessages.create(); - RuleFinder ruleFinder = newRuleFinder(); - RulesProfile profile = XMLProfileImporter.create(ruleFinder).importProfile(reader, validation); - - assertThat(validation.getWarnings().size(), is(1)); - ActiveRule rule = profile.getActiveRule("checkstyle", "IllegalRegexp"); - assertThat(rule.getParameter("unknown"), nullValue()); - - } finally { - IOUtils.closeQuietly(reader); - } - } - - private RuleFinder newRuleFinder() { - RuleFinder ruleFinder = mock(RuleFinder.class); - when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer(){ - public Rule answer(InvocationOnMock iom) throws Throwable { - Rule rule = Rule.create((String) iom.getArguments()[0], (String) iom.getArguments()[1], (String) iom.getArguments()[1]); - rule.createParameter("format"); - rule.createParameter("message"); - return rule; - } - }); - return ruleFinder; - } -} \ No newline at end of file diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileParserTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileParserTest.java new file mode 100644 index 00000000000..3167cb941b4 --- /dev/null +++ b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileParserTest.java @@ -0,0 +1,104 @@ +/* + * 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.api.profiles; + +import org.junit.Test; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.sonar.api.rules.ActiveRule; +import org.sonar.api.rules.Rule; +import org.sonar.api.rules.RuleFinder; +import org.sonar.api.rules.RulePriority; +import org.sonar.api.utils.ValidationMessages; + +import java.io.UnsupportedEncodingException; + +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; +import static org.junit.internal.matchers.StringContains.containsString; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class XMLProfileParserTest { + + @Test + public void importProfile() throws UnsupportedEncodingException { + ValidationMessages validation = ValidationMessages.create(); + RuleFinder ruleFinder = newRuleFinder(); + RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/importProfile.xml", validation); + + assertThat(profile.getLanguage(), is("java")); + assertThat(profile.getName(), is("sonar way")); + assertThat(validation.hasErrors(), is(false)); + assertNotNull(profile); + assertThat(profile.getActiveRule("checkstyle", "IllegalRegexp").getPriority(), is(RulePriority.CRITICAL)); + } + + @Test + public void nameAndLanguageShouldBeMandatory() throws UnsupportedEncodingException { + ValidationMessages validation = ValidationMessages.create(); + RuleFinder ruleFinder = newRuleFinder(); + RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/nameAndLanguageShouldBeMandatory.xml", validation); + + assertThat(validation.getErrors().size(), is(2)); + assertThat(validation.getErrors().get(0), containsString("")); + + } + + @Test + public void importProfileWithRuleParameters() throws UnsupportedEncodingException { + ValidationMessages validation = ValidationMessages.create(); + RuleFinder ruleFinder = newRuleFinder(); + RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/importProfileWithRuleParameters.xml", validation); + + assertThat(validation.hasErrors(), is(false)); + assertThat(validation.hasWarnings(), is(false)); + ActiveRule rule = profile.getActiveRule("checkstyle", "IllegalRegexp"); + assertThat(rule.getParameter("format"), is("foo")); + assertThat(rule.getParameter("message"), is("with special characters < > &")); + } + + @Test + public void importProfileWithUnknownRuleParameter() throws UnsupportedEncodingException { + ValidationMessages validation = ValidationMessages.create(); + RuleFinder ruleFinder = newRuleFinder(); + RulesProfile profile = new XMLProfileParser(ruleFinder).parseResource(getClass().getClassLoader(), "org/sonar/api/profiles/XMLProfileParserTest/importProfileWithUnknownRuleParameter.xml", validation); + + assertThat(validation.getWarnings().size(), is(1)); + ActiveRule rule = profile.getActiveRule("checkstyle", "IllegalRegexp"); + assertThat(rule.getParameter("unknown"), nullValue()); + } + + private RuleFinder newRuleFinder() { + RuleFinder ruleFinder = mock(RuleFinder.class); + when(ruleFinder.findByKey(anyString(), anyString())).thenAnswer(new Answer() { + public Rule answer(InvocationOnMock iom) throws Throwable { + Rule rule = Rule.create((String) iom.getArguments()[0], (String) iom.getArguments()[1], (String) iom.getArguments()[1]); + rule.createParameter("format"); + rule.createParameter("message"); + return rule; + } + }); + return ruleFinder; + } +} \ No newline at end of file diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileExporterTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileSerializerTest.java similarity index 82% rename from sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileExporterTest.java rename to sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileSerializerTest.java index e43ce06c329..90169f10dab 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileExporterTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/profiles/XMLProfileSerializerTest.java @@ -36,15 +36,15 @@ import java.io.Writer; import static org.junit.Assert.assertTrue; -public class XMLProfileExporterTest { +public class XMLProfileSerializerTest { @Test public void exportEmptyProfile() throws IOException, SAXException { Writer writer = new StringWriter(); RulesProfile profile = RulesProfile.create("sonar way", "java"); - XMLProfileExporter.create().exportProfile(profile, writer); + new XMLProfileSerializer().write(profile, writer); - assertSimilarXml("/org/sonar/api/profiles/XMLProfileExporterTest/exportEmptyProfile.xml", writer.toString()); + assertSimilarXml("/org/sonar/api/profiles/XMLProfileSerializerTest/exportEmptyProfile.xml", writer.toString()); } @Test @@ -52,9 +52,9 @@ public class XMLProfileExporterTest { Writer writer = new StringWriter(); RulesProfile profile = RulesProfile.create("sonar way", "java"); profile.activateRule(Rule.create("checkstyle", "IllegalRegexp", "illegal regexp"), RulePriority.BLOCKER); - XMLProfileExporter.create().exportProfile(profile, writer); + new XMLProfileSerializer().write(profile, writer); - assertSimilarXml("/org/sonar/api/profiles/XMLProfileExporterTest/exportProfile.xml", writer.toString()); + assertSimilarXml("/org/sonar/api/profiles/XMLProfileSerializerTest/exportProfile.xml", writer.toString()); } @Test @@ -70,13 +70,13 @@ public class XMLProfileExporterTest { activeRule.setParameter("format", "foo"); activeRule.setParameter("message", "with special characters < > &"); // the tokens parameter is not set - XMLProfileExporter.create().exportProfile(profile, writer); + new XMLProfileSerializer().write(profile, writer); - assertSimilarXml("/org/sonar/api/profiles/XMLProfileExporterTest/exportRuleParameters.xml", writer.toString()); + assertSimilarXml("/org/sonar/api/profiles/XMLProfileSerializerTest/exportRuleParameters.xml", writer.toString()); } public static void assertSimilarXml(String pathToExpectedXml, String xml) throws IOException, SAXException { - InputStream stream = XMLProfileExporterTest.class.getResourceAsStream(pathToExpectedXml); + InputStream stream = XMLProfileSerializerTest.class.getResourceAsStream(pathToExpectedXml); try { Diff diff = isSimilarXml(IOUtils.toString(stream), xml); String message = "Diff: " + diff.toString() + CharUtils.LF + "XML: " + xml; diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/importProfile.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/importProfile.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/importProfile.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/importProfile.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/importProfileWithRuleParameters.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/importProfileWithRuleParameters.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/importProfileWithRuleParameters.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/importProfileWithRuleParameters.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/importProfileWithUnknownRuleParameter.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/importProfileWithUnknownRuleParameter.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/importProfileWithUnknownRuleParameter.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/importProfileWithUnknownRuleParameter.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/nameAndLanguageShouldBeMandatory.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/nameAndLanguageShouldBeMandatory.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileImporterTest/nameAndLanguageShouldBeMandatory.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileParserTest/nameAndLanguageShouldBeMandatory.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileExporterTest/exportEmptyProfile.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileSerializerTest/exportEmptyProfile.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileExporterTest/exportEmptyProfile.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileSerializerTest/exportEmptyProfile.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileExporterTest/exportProfile.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileSerializerTest/exportProfile.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileExporterTest/exportProfile.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileSerializerTest/exportProfile.xml diff --git a/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileExporterTest/exportRuleParameters.xml b/sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileSerializerTest/exportRuleParameters.xml similarity index 100% rename from sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileExporterTest/exportRuleParameters.xml rename to sonar-plugin-api/src/test/resources/org/sonar/api/profiles/XMLProfileSerializerTest/exportRuleParameters.xml diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 145ba28e3f4..48c321c0c02 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -28,6 +28,9 @@ import org.sonar.api.Plugins; import org.sonar.api.database.configuration.DatabaseConfiguration; import org.sonar.api.platform.Environment; import org.sonar.api.platform.Server; +import org.sonar.api.profiles.AnnotationProfileParser; +import org.sonar.api.profiles.XMLProfileParser; +import org.sonar.api.profiles.XMLProfileSerializer; import org.sonar.api.resources.Languages; import org.sonar.api.rules.DefaultRulesManager; import org.sonar.api.utils.HttpDownloader; @@ -169,6 +172,9 @@ public final class Platform { servicesContainer.as(Characteristics.NO_CACHE).addComponent(Backup.class); servicesContainer.as(Characteristics.CACHE).addComponent(AuthenticatorFactory.class); servicesContainer.as(Characteristics.CACHE).addComponent(ServerLifecycleNotifier.class); + servicesContainer.as(Characteristics.CACHE).addComponent(AnnotationProfileParser.class); + servicesContainer.as(Characteristics.CACHE).addComponent(XMLProfileParser.class); + servicesContainer.as(Characteristics.CACHE).addComponent(XMLProfileSerializer.class); servicesContainer.as(Characteristics.CACHE).addComponent(DefaultRuleFinder.class); servicesContainer.as(Characteristics.CACHE).addComponent(DeprecatedRuleRepositories.class); servicesContainer.as(Characteristics.CACHE).addComponent(DeprecatedProfiles.class); diff --git a/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java b/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java index 84ccb3999bb..0e5290a0012 100644 --- a/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java +++ b/sonar-server/src/main/java/org/sonar/server/qualitymodel/DefaultModelManager.java @@ -57,7 +57,7 @@ public final class DefaultModelManager implements ServerComponent, ModelManager for (ModelDefinition definition : definitions) { if (StringUtils.isNotBlank(definition.getName()) && !exists(session, definition.getName())) { Logs.INFO.info("Register quality model: " + definition.getName()); - Model model = definition.create(); + Model model = definition.createModel(); if (StringUtils.isBlank(model.getName())) { model.setName(definition.getName()); } @@ -75,7 +75,7 @@ public final class DefaultModelManager implements ServerComponent, ModelManager } LoggerFactory.getLogger(getClass()).info("Reset quality model: " + name); - Model model = definition.create(); + Model model = definition.createModel(); return reset(model); } diff --git a/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java b/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java index 64d525939bc..20b9605c863 100644 --- a/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java +++ b/sonar-server/src/main/java/org/sonar/server/rules/ProfilesConsole.java @@ -40,14 +40,16 @@ import java.util.List; public final class ProfilesConsole implements ServerComponent { private DatabaseSessionFactory sessionFactory; - private RuleFinder ruleFinder; + private XMLProfileParser xmlProfileParser; + private XMLProfileSerializer xmlProfileSerializer; private List exporters = new ArrayList(); private List importers = new ArrayList(); - public ProfilesConsole(DatabaseSessionFactory sessionFactory, RuleFinder ruleFinder, + public ProfilesConsole(DatabaseSessionFactory sessionFactory, XMLProfileParser xmlProfileParser, XMLProfileSerializer xmlProfileSerializer, ProfileExporter[] exporters, DeprecatedProfileExporters deprecatedExporters, ProfileImporter[] importers, DeprecatedProfileImporters deprecatedImporters) { - this.ruleFinder = ruleFinder; + this.xmlProfileParser = xmlProfileParser; + this.xmlProfileSerializer = xmlProfileSerializer; this.sessionFactory = sessionFactory; initProfileExporters(exporters, deprecatedExporters); initProfileImporters(importers, deprecatedImporters); @@ -72,7 +74,7 @@ public final class ProfilesConsole implements ServerComponent { RulesProfile profile = loadProfile(session, profileId); if (profile != null) { Writer writer = new StringWriter(); - XMLProfileExporter.create().exportProfile(profile, writer); + xmlProfileSerializer.write(profile, writer); return writer.toString(); } return null; @@ -80,7 +82,7 @@ public final class ProfilesConsole implements ServerComponent { public ValidationMessages restoreProfile(String xmlBackup) { ValidationMessages messages = ValidationMessages.create(); - RulesProfile profile = XMLProfileImporter.create(ruleFinder).importProfile(new StringReader(xmlBackup), messages); + RulesProfile profile = xmlProfileParser.parse(new StringReader(xmlBackup), messages); if (profile != null) { DatabaseSession session = sessionFactory.getSession(); RulesProfile existingProfile = session.getSingleResult(RulesProfile.class, "name", profile.getName(), "language", profile.getLanguage()); diff --git a/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java b/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java index ad5ee2559d2..82f0c94de88 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/RegisterProvidedProfiles.java @@ -19,6 +19,7 @@ */ package org.sonar.server.startup; +import com.google.common.collect.Lists; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,7 +41,7 @@ public final class RegisterProvidedProfiles { private static final Logger LOGGER = LoggerFactory.getLogger(RegisterProvidedProfiles.class); private DatabaseSessionFactory sessionFactory; - private List definitions = new ArrayList(); + private List definitions = Lists.newArrayList(); private DeprecatedProfiles deprecatedProfiles = null; private RuleFinder ruleFinder; @@ -71,7 +72,7 @@ public final class RegisterProvidedProfiles { } List createProfiles() { - List result = new ArrayList(); + List result = Lists.newArrayList(); // this must not be moved in the constructor, because rules are still not saved definitions.addAll(deprecatedProfiles.getProfiles()); diff --git a/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java b/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java index 058e649d5bc..73d2e9b8938 100644 --- a/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java +++ b/sonar-server/src/test/java/org/sonar/server/qualitymodel/DefaultModelManagerTest.java @@ -114,7 +114,7 @@ class FakeDefinition extends ModelDefinition { } @Override - public Model create() { + public Model createModel() { return model; } diff --git a/sonar-server/src/test/java/org/sonar/server/rules/DeprecatedProfilesTest.java b/sonar-server/src/test/java/org/sonar/server/rules/DeprecatedProfilesTest.java index cd5b40f38ab..187a3ed8e1f 100644 --- a/sonar-server/src/test/java/org/sonar/server/rules/DeprecatedProfilesTest.java +++ b/sonar-server/src/test/java/org/sonar/server/rules/DeprecatedProfilesTest.java @@ -23,7 +23,6 @@ import org.junit.Test; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.api.utils.ValidationMessages; -import org.sonar.server.rules.DeprecatedProfiles; import static org.hamcrest.Matchers.is; import static org.hamcrest.core.IsNull.nullValue; @@ -31,7 +30,7 @@ import static org.junit.Assert.assertThat; public class DeprecatedProfilesTest { @Test - public void testCreate() { + public void shouldCreateProfile() { DeprecatedProfiles.DefaultProfileDefinition def = DeprecatedProfiles.DefaultProfileDefinition.create("sonar way", "java"); assertThat(def.createProfile(ValidationMessages.create()).getName(), is("sonar way")); assertThat(def.createProfile(ValidationMessages.create()).getLanguage(), is("java")); -- 2.39.5