package org.sonar.xoo;
import org.sonar.api.SonarPlugin;
-import org.sonar.xoo.lang.MeasureSensor;
-import org.sonar.xoo.lang.ScmActivitySensor;
-import org.sonar.xoo.lang.SymbolReferencesSensor;
-import org.sonar.xoo.lang.SyntaxHighlightingSensor;
-import org.sonar.xoo.lang.XooTokenizerSensor;
-import org.sonar.xoo.rule.CreateIssueByInternalKeySensor;
-import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor;
-import org.sonar.xoo.rule.OneIssuePerLineSensor;
-import org.sonar.xoo.rule.XooQualityProfile;
-import org.sonar.xoo.rule.XooRulesDefinition;
+import org.sonar.xoo.lang.*;
+import org.sonar.xoo.rule.*;
import java.util.Arrays;
import java.util.List;
XooRulesDefinition.class,
XooQualityProfile.class,
+ XooFakeExporter.class,
+ XooFakeImporter.class,
+ XooFakeImporterWithMessages.class,
+
// sensors
MeasureSensor.class,
ScmActivitySensor.class,
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.xoo.rule;
+
+import org.sonar.api.profiles.ProfileExporter;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.xoo.Xoo;
+
+import java.io.IOException;
+import java.io.Writer;
+
+/**
+ * Fake exporter just for test
+ */
+public class XooFakeExporter extends ProfileExporter {
+ public XooFakeExporter() {
+ super("XooFakeExporter", "Xoo Fake Exporter");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[]{Xoo.KEY};
+ }
+
+ @Override
+ public String getMimeType() {
+ return "plain/custom";
+ }
+
+ @Override
+ public void exportProfile(RulesProfile profile, Writer writer) {
+ try {
+ writer.write("xoo -> " + profile.getName() + " -> " + profile.getActiveRules().size());
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.xoo.rule;
+
+import org.sonar.api.profiles.ProfileImporter;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.api.utils.ValidationMessages;
+import org.sonar.xoo.Xoo;
+
+import java.io.Reader;
+
+/**
+ * Fake importer just for test, it will NOT take into account the given file but will create some hard-coded rules
+ */
+public class XooFakeImporter extends ProfileImporter {
+ public XooFakeImporter() {
+ super("XooProfileImporter", "Xoo Profile Importer");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[] {Xoo.KEY};
+ }
+
+ @Override
+ public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
+ RulesProfile rulesProfile = RulesProfile.create();
+ rulesProfile.activateRule(Rule.create(XooRulesDefinition.XOO_REPOSITORY, "x1"), RulePriority.CRITICAL);
+ return rulesProfile;
+ }
+}
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube 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.
+ *
+ * SonarQube 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 this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.xoo.rule;
+
+import org.sonar.api.profiles.ProfileImporter;
+import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.utils.ValidationMessages;
+
+import java.io.Reader;
+
+/**
+ * Fake importer just for test, it will NOT take into account the given file but will display some info and warning messages
+ */
+public class XooFakeImporterWithMessages extends ProfileImporter {
+ public XooFakeImporterWithMessages() {
+ super("XooFakeImporterWithMessages", "Xoo Profile Importer With Messages");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[] {};
+ }
+
+ @Override
+ public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
+ messages.addWarningText("a warning");
+ messages.addInfoText("an info");
+ return RulesProfile.create();
+ }
+}
@Test
public void provide_extensions() {
- assertThat(new XooPlugin().getExtensions()).hasSize(11);
+ assertThat(new XooPlugin().getExtensions()).hasSize(14);
}
}
pico.addSingleton(QProfileLookup.class);
pico.addSingleton(QProfileProjectOperations.class);
pico.addSingleton(QProfileProjectLookup.class);
- pico.addSingleton(QProfileRepositoryExporter.class);
pico.addSingleton(BuiltInProfiles.class);
pico.addSingleton(QProfileRestoreBuiltInAction.class);
pico.addSingleton(QProfilesWs.class);
package org.sonar.server.qualityprofile;
import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
import org.sonar.api.ServerComponent;
import org.sonar.api.profiles.ProfileExporter;
+import org.sonar.api.profiles.ProfileImporter;
import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rules.ActiveRuleParam;
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.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
+import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
private final QProfileLoader loader;
private final RuleFinder ruleFinder;
+ private final RuleActivator ruleActivator;
private final ProfileExporter[] exporters;
+ private final ProfileImporter[] importers;
- public QProfileExporters(QProfileLoader loader, RuleFinder ruleFinder, ProfileExporter[] exporters) {
+ public QProfileExporters(QProfileLoader loader, RuleFinder ruleFinder, RuleActivator ruleActivator, ProfileExporter[] exporters, ProfileImporter[] importers) {
this.loader = loader;
this.ruleFinder = ruleFinder;
+ this.ruleActivator = ruleActivator;
this.exporters = exporters;
+ this.importers = importers;
}
- public QProfileExporters(QProfileLoader loader, RuleFinder ruleFinder) {
- this(loader, ruleFinder, new ProfileExporter[0]);
+ public QProfileExporters(QProfileLoader loader, RuleFinder ruleFinder, RuleActivator ruleActivator) {
+ this(loader, ruleFinder, ruleActivator, new ProfileExporter[0], new ProfileImporter[0]);
}
public List<ProfileExporter> exportersForLanguage(String language) {
}
throw new NotFoundException("Unknown quality profile exporter: " + exporterKey);
}
+
+ /**
+ * Used by rails
+ */
+ public List<ProfileImporter> findProfileImportersForLanguage(String language) {
+ List<ProfileImporter> result = new ArrayList<ProfileImporter>();
+ for (ProfileImporter importer : importers) {
+ if (importer.getSupportedLanguages() == null || importer.getSupportedLanguages().length == 0 || ArrayUtils.contains(importer.getSupportedLanguages(), language)) {
+ result.add(importer);
+ }
+ }
+ return result;
+ }
+
+ public QProfileResult importXml(QualityProfileDto profileDto, String importerKey, String xml, DbSession dbSession) {
+ QProfileResult result = new QProfileResult();
+ ValidationMessages messages = ValidationMessages.create();
+ ProfileImporter importer = getProfileImporter(importerKey);
+ RulesProfile rulesProfile = importer.importProfile(new StringReader(xml), messages);
+ importProfile(profileDto, rulesProfile, dbSession);
+ processValidationMessages(messages, result);
+ return result;
+ }
+
+ private void importProfile(QualityProfileDto profileDto, RulesProfile rulesProfile, DbSession dbSession) {
+ for (org.sonar.api.rules.ActiveRule activeRule : rulesProfile.getActiveRules()) {
+ ruleActivator.activate(dbSession, toRuleActivation(activeRule), profileDto);
+ }
+ }
+
+ private ProfileImporter getProfileImporter(String importerKey) {
+ for (ProfileImporter importer : importers) {
+ if (StringUtils.equals(importerKey, importer.getKey())) {
+ return importer;
+ }
+ }
+ throw new BadRequestException("No such importer : " + importerKey);
+ }
+
+ private void processValidationMessages(ValidationMessages messages, QProfileResult result) {
+ if (!messages.getErrors().isEmpty()) {
+ throw new BadRequestException(messages);
+ }
+ result.addWarnings(messages.getWarnings());
+ result.addInfos(messages.getInfos());
+ }
+
+ private RuleActivation toRuleActivation(org.sonar.api.rules.ActiveRule activeRule) {
+ RuleActivation ruleActivation = new RuleActivation(activeRule.getRule().ruleKey());
+ ruleActivation.setSeverity(activeRule.getSeverity().name());
+ for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) {
+ ruleActivation.setParameter(activeRuleParam.getKey(), activeRuleParam.getValue());
+ }
+ return ruleActivation;
+ }
+
}
return name;
}
+ public static QProfileName createFor(String lang, String name){
+ return new QProfileName(lang, name);
+ }
+
@Override
public boolean equals(@Nullable Object o) {
if (this == o) {
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.qualityprofile;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Multimap;
-import org.apache.commons.lang.ArrayUtils;
-import org.apache.commons.lang.StringUtils;
-import org.apache.ibatis.session.SqlSession;
-import org.sonar.api.ServerComponent;
-import org.sonar.api.profiles.ProfileImporter;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rules.ActiveRule;
-import org.sonar.api.rules.ActiveRuleParam;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.utils.ValidationMessages;
-import org.sonar.core.qualityprofile.db.ActiveRuleDao;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.server.exceptions.BadRequestException;
-
-import java.io.StringReader;
-import java.util.ArrayList;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-
-/**
- * Used through ruby code <pre>Internal.profile_exporter</pre>
- */
-public class QProfileRepositoryExporter implements ServerComponent {
-
- private final ActiveRuleDao activeRuleDao;
- private final List<ProfileImporter> importers;
-
- /**
- * Used by pico when no plugin provide profile exporter / importer
- */
- public QProfileRepositoryExporter(ActiveRuleDao activeRuleDao) {
- this(activeRuleDao, Lists.<ProfileImporter>newArrayList());
- }
-
- public QProfileRepositoryExporter(ActiveRuleDao activeRuleDao, List<ProfileImporter> importers) {
- this.activeRuleDao = activeRuleDao;
- this.importers = importers;
- }
-
- public QProfileResult importXml(QProfile profile, String pluginKey, String xml, SqlSession session) {
- QProfileResult result = new QProfileResult();
- ValidationMessages messages = ValidationMessages.create();
- ProfileImporter importer = getProfileImporter(pluginKey);
- RulesProfile rulesProfile = importer.importProfile(new StringReader(xml), messages);
- importProfile(profile.id(), rulesProfile, session);
- processValidationMessages(messages, result);
- return result;
- }
-
- private void importProfile(int profileId, RulesProfile rulesProfile, SqlSession sqlSession) {
- List<ActiveRuleDto> activeRuleDtos = newArrayList();
- Multimap<Integer, ActiveRuleParamDto> paramsByActiveRule = ArrayListMultimap.create();
- for (ActiveRule activeRule : rulesProfile.getActiveRules()) {
- ActiveRuleDto activeRuleDto = toActiveRuleDto(activeRule, profileId);
- activeRuleDao.insert(activeRuleDto, sqlSession);
- activeRuleDtos.add(activeRuleDto);
- for (ActiveRuleParam activeRuleParam : activeRule.getActiveRuleParams()) {
- ActiveRuleParamDto activeRuleParamDto = toActiveRuleParamDto(activeRuleParam, activeRuleDto);
- activeRuleDao.insert(activeRuleParamDto, sqlSession);
- paramsByActiveRule.put(activeRuleDto.getId(), activeRuleParamDto);
- }
- }
- // TODO use RuleActivator to benefit from changelog and preview cache cleanup
- }
-
- private void processValidationMessages(ValidationMessages messages, QProfileResult result) {
- if (!messages.getErrors().isEmpty()) {
- throw new BadRequestException(messages);
- }
- result.addWarnings(messages.getWarnings());
- result.addInfos(messages.getInfos());
- }
-
- private ActiveRuleDto toActiveRuleDto(ActiveRule activeRule, int profileId) {
- return new ActiveRuleDto()
- .setProfileId(profileId)
- .setRuleId(activeRule.getRule().getId())
- .setSeverity(toSeverityLevel(activeRule.getSeverity()));
- }
-
- private String toSeverityLevel(RulePriority rulePriority) {
- return rulePriority.name();
- }
-
- private ActiveRuleParamDto toActiveRuleParamDto(ActiveRuleParam activeRuleParam, ActiveRuleDto activeRuleDto) {
- return new ActiveRuleParamDto()
- .setActiveRuleId(activeRuleDto.getId())
- .setRulesParameterId(activeRuleParam.getRuleParam().getId())
- .setKey(activeRuleParam.getKey())
- .setValue(activeRuleParam.getValue());
- }
-
- private ProfileImporter getProfileImporter(String importerKey) {
- for (ProfileImporter importer : importers) {
- if (StringUtils.equals(importerKey, importer.getKey())) {
- return importer;
- }
- }
- throw new BadRequestException("No such importer : " + importerKey);
- }
-
- public List<ProfileImporter> getProfileImportersForLanguage(String language) {
- List<ProfileImporter> result = new ArrayList<ProfileImporter>();
- for (ProfileImporter importer : importers) {
- if (importer.getSupportedLanguages() == null || importer.getSupportedLanguages().length == 0 || ArrayUtils.contains(importer.getSupportedLanguages(), language)) {
- result.add(importer);
- }
- }
- return result;
- }
-
-}
package org.sonar.server.qualityprofile;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
+
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
private List<String> warnings;
private List<String> infos;
- private QProfile profile;
+ private QualityProfileDto profile;
public QProfileResult() {
warnings = newArrayList();
return this;
}
- public QProfile profile() {
+ public QualityProfileDto profile() {
return profile;
}
- public QProfileResult setProfile(QProfile profile) {
+ public QProfileResult setProfile(QualityProfileDto profile) {
this.profile = profile;
return this;
}
import java.io.Writer;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
public class QProfileService implements ServerComponent {
private final QProfileBackuper backuper;
private final QProfileCopier copier;
private final QProfileReset reset;
+ private final QProfileExporters exporters;
public QProfileService(DbClient db, IndexClient index, RuleActivator ruleActivator, QProfileFactory factory,
- QProfileBackuper backuper, QProfileCopier copier, QProfileReset reset) {
+ QProfileBackuper backuper, QProfileCopier copier, QProfileReset reset, QProfileExporters exporters) {
this.db = db;
this.index = index;
this.ruleActivator = ruleActivator;
this.backuper = backuper;
this.copier = copier;
this.reset = reset;
+ this.exporters = exporters;
}
- public QualityProfileDto create(QProfileName name) {
+ public QProfileResult create(QProfileName name, @Nullable Map<String, String> xmlQProfilesByPlugin) {
verifyAdminPermission();
DbSession dbSession = db.openSession(false);
try {
+ QProfileResult result = new QProfileResult();
QualityProfileDto profile = factory.create(dbSession, name);
+ result.setProfile(profile);
+ if (xmlQProfilesByPlugin != null) {
+ for (Map.Entry<String, String> entry : xmlQProfilesByPlugin.entrySet()) {
+ result.add(exporters.importXml(profile, entry.getKey(), entry.getValue(), dbSession));
+ }
+ }
dbSession.commit();
- return profile;
+ return result;
} finally {
dbSession.close();
}
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
-import org.apache.commons.lang.StringUtils;
import org.sonar.api.ServerComponent;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.core.activity.Activity;
return doActivate(dbSession, activation, context);
}
+ List<ActiveRuleChange> activate(DbSession dbSession, RuleActivation activation, QualityProfileDto profileDto) {
+ RuleActivatorContext context = contextFactory.create(profileDto, activation.getRuleKey(), dbSession);
+ return doActivate(dbSession, activation, context);
+ }
+
private List<ActiveRuleChange> doActivate(DbSession dbSession, RuleActivation activation, RuleActivatorContext context) {
context.verifyForActivation();
List<ActiveRuleChange> changes = Lists.newArrayList();
throw new BadRequestException("Quality profile not found: " + profileKey);
}
context.setProfile(profile);
- return create(profile, ruleKey, session, context);
+ return create(ruleKey, session, context);
}
RuleActivatorContext create(QProfileName profileName, RuleKey ruleKey, DbSession session) {
throw new BadRequestException("Quality profile not found: " + profileName);
}
context.setProfile(profile);
- return create(profile, ruleKey, session, context);
+ return create(ruleKey, session, context);
}
- private RuleActivatorContext create(QualityProfileDto profile, RuleKey ruleKey, DbSession session, RuleActivatorContext context) {
+ RuleActivatorContext create(QualityProfileDto profile, RuleKey ruleKey, DbSession session) {
+ return create(ruleKey, session, new RuleActivatorContext().setProfile(profile));
+ }
+
+ private RuleActivatorContext create(RuleKey ruleKey, DbSession session, RuleActivatorContext context) {
initRule(ruleKey, context, session);
- initActiveRules(profile.getKey(), ruleKey, context, session, false);
- String parentKee = profile.getParentKee();
+ initActiveRules(context.profile().getKey(), ruleKey, context, session, false);
+ String parentKee = context.profile().getParentKee();
if (parentKee != null) {
initActiveRules(parentKee, ruleKey, context, session, true);
}
*/
package org.sonar.server.qualityprofile;
+import org.junit.After;
+import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
import org.sonar.api.profiles.ProfileDefinition;
import org.sonar.api.profiles.ProfileExporter;
+import org.sonar.api.profiles.ProfileImporter;
import org.sonar.api.profiles.RulesProfile;
+import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.Severity;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RulePriority;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.utils.ValidationMessages;
+import org.sonar.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.QualityProfileDto;
+import org.sonar.server.db.DbClient;
+import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.NotFoundException;
import org.sonar.server.tester.ServerTester;
import java.io.IOException;
+import java.io.Reader;
import java.io.Writer;
+import java.util.List;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
@ClassRule
public static ServerTester tester = new ServerTester().addXoo().addComponents(
XooRulesDefinition.class, XooProfileDefinition.class,
- XooExporter.class, StandardExporter.class);
+ XooExporter.class, StandardExporter.class,
+ XooProfileImporter.class, XooProfileImporterWithMessages.class, XooProfileImporterWithError.class);
- QProfileExporters exporters = tester.get(QProfileExporters.class);
+ DbClient db;
+ DbSession dbSession;
+ QProfileExporters exporters;
+ QProfileLoader loader;
+
+ @Before
+ public void before() {
+ db = tester.get(DbClient.class);
+ dbSession = db.openSession(false);
+ exporters = tester.get(QProfileExporters.class);
+ loader = tester.get(QProfileLoader.class);
+ }
+
+ @After
+ public void after() throws Exception {
+ dbSession.close();
+ }
@Test
public void exportersForLanguage() throws Exception {
}
}
+ @Test
+ public void profile_importers_for_language() throws Exception {
+ assertThat(exporters.findProfileImportersForLanguage("xoo")).hasSize(3);
+ }
+
+ @Test
+ public void import_xml() throws Exception {
+ QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor("xoo", "import_xml"), "import_xml");
+ db.qualityProfileDao().insert(dbSession, profileDto);
+ dbSession.commit();
+
+ assertThat(loader.findActiveRulesByProfile(profileDto.getKey())).isEmpty();
+
+ exporters.importXml(profileDto, "XooProfileImporter", "<xml/>", dbSession);
+ dbSession.commit();
+
+ List<ActiveRule> activeRules = loader.findActiveRulesByProfile(profileDto.getKey());
+ assertThat(activeRules).hasSize(1);
+ ActiveRule activeRule = activeRules.get(0);
+ assertThat(activeRule.key().ruleKey()).isEqualTo(RuleKey.of("xoo", "R1"));
+ assertThat(activeRule.severity()).isEqualTo(Severity.CRITICAL);
+ }
+
+ @Test
+ public void import_xml_return_messages() throws Exception {
+ QProfileResult result = exporters.importXml(QProfileTesting.newXooP1(), "XooProfileImporterWithMessages", "<xml/>", dbSession);
+ dbSession.commit();
+
+ assertThat(result.infos()).containsOnly("an info");
+ assertThat(result.warnings()).containsOnly("a warning");
+ }
+
+ @Test
+ public void fail_to_import_xml_when_error_in_importer() throws Exception {
+ try {
+ exporters.importXml(QProfileTesting.newXooP1(), "XooProfileImporterWithError", "<xml/>", dbSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("error!");
+ }
+ }
+
+ @Test
+ public void fail_to_import_xml_on_unknown_importer() throws Exception {
+ try {
+ exporters.importXml(QProfileTesting.newXooP1(), "Unknown", "<xml/>", dbSession);
+ fail();
+ } catch (Exception e) {
+ assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("No such importer : Unknown");
+ }
+ }
+
public static class XooExporter extends ProfileExporter {
public XooExporter() {
super("xootool", "Xoo Tool");
}
}
+ public static class XooProfileImporter extends ProfileImporter {
+ public XooProfileImporter() {
+ super("XooProfileImporter", "Xoo Profile Importer");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[] {"xoo"};
+ }
+
+ @Override
+ public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
+ RulesProfile rulesProfile = RulesProfile.create();
+ rulesProfile.activateRule(Rule.create("xoo", "R1"), RulePriority.CRITICAL);
+ return rulesProfile;
+ }
+ }
+
+ public static class XooProfileImporterWithMessages extends ProfileImporter {
+ public XooProfileImporterWithMessages() {
+ super("XooProfileImporterWithMessages", "Xoo Profile Importer With Message");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[] {};
+ }
+
+ @Override
+ public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
+ messages.addWarningText("a warning");
+ messages.addInfoText("an info");
+ return RulesProfile.create();
+ }
+ }
+
+ public static class XooProfileImporterWithError extends ProfileImporter {
+ public XooProfileImporterWithError() {
+ super("XooProfileImporterWithError", "Xoo Profile Importer With Error");
+ }
+
+ @Override
+ public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
+ messages.addErrorText("error!");
+ return RulesProfile.create();
+ }
+ }
+
}
+++ /dev/null
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2014 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube 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.
- *
- * SonarQube 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 this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-package org.sonar.server.qualityprofile;
-
-import org.apache.ibatis.session.SqlSession;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.runners.MockitoJUnitRunner;
-import org.mockito.stubbing.Answer;
-import org.sonar.api.database.DatabaseSession;
-import org.sonar.api.profiles.ProfileImporter;
-import org.sonar.api.profiles.RulesProfile;
-import org.sonar.api.rule.Severity;
-import org.sonar.api.rules.ActiveRule;
-import org.sonar.api.rules.Rule;
-import org.sonar.api.rules.RulePriority;
-import org.sonar.api.utils.ValidationMessages;
-import org.sonar.core.qualityprofile.db.ActiveRuleDao;
-import org.sonar.core.qualityprofile.db.ActiveRuleDto;
-import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
-import org.sonar.server.exceptions.BadRequestException;
-
-import java.io.Reader;
-import java.util.List;
-
-import static com.google.common.collect.Lists.newArrayList;
-import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.assertions.Fail.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-@RunWith(MockitoJUnitRunner.class)
-public class QProfileRepositoryExporterTest {
-
- @Mock
- SqlSession session;
-
- @Mock
- DatabaseSession hibernateSession;
-
- @Mock
- ActiveRuleDao activeRuleDao;
-
- List<ProfileImporter> importers = newArrayList();
-
- Integer currentId = 1;
-
- QProfileRepositoryExporter operations;
-
- @Before
- public void setUp() throws Exception {
- // Associate an id when inserting an object to simulate the db id generator
- doAnswer(new Answer() {
- public Object answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- ActiveRuleDto dto = (ActiveRuleDto) args[0];
- dto.setId(currentId++);
- return null;
- }
- }).when(activeRuleDao).insert(any(ActiveRuleDto.class), any(SqlSession.class));
-
- operations = new QProfileRepositoryExporter(activeRuleDao, importers);
- }
-
- @Test
- public void import_from_xml_plugin() throws Exception {
- RulesProfile profile = RulesProfile.create("Default", "java");
- Rule rule = Rule.create("pmd", "rule1");
- rule.createParameter("max");
- rule.setId(10);
- ActiveRule activeRule = profile.activateRule(rule, RulePriority.BLOCKER);
- activeRule.setParameter("max", "10");
-
- ProfileImporter importer = mock(ProfileImporter.class);
- when(importer.getKey()).thenReturn("pmd");
- when(importer.importProfile(any(Reader.class), any(ValidationMessages.class))).thenReturn(profile);
- importers.add(importer);
-
- operations.importXml(new QProfile().setId(1), "pmd", "<xml/>", session);
-
- verify(importer).importProfile(any(Reader.class), any(ValidationMessages.class));
-
- ArgumentCaptor<ActiveRuleDto> activeRuleArgument = ArgumentCaptor.forClass(ActiveRuleDto.class);
- verify(activeRuleDao).insert(activeRuleArgument.capture(), eq(session));
- assertThat(activeRuleArgument.getValue().getRuleId()).isEqualTo(10);
- assertThat(activeRuleArgument.getValue().getSeverityString()).isEqualTo(Severity.BLOCKER);
-
- ArgumentCaptor<ActiveRuleParamDto> activeRuleParamArgument = ArgumentCaptor.forClass(ActiveRuleParamDto.class);
- verify(activeRuleDao).insert(activeRuleParamArgument.capture(), eq(session));
- assertThat(activeRuleParamArgument.getValue().getKey()).isEqualTo("max");
- assertThat(activeRuleParamArgument.getValue().getValue()).isEqualTo("10");
- }
-
- @Test
- public void import_from_xml_plugin_add_infos_and_warnings() throws Exception {
- final RulesProfile profile = RulesProfile.create("Default", "java");
- Rule rule = Rule.create("pmd", "rule1");
- rule.createParameter("max");
- rule.setId(10);
- ActiveRule activeRule = profile.activateRule(rule, RulePriority.BLOCKER);
- activeRule.setParameter("max", "10");
-
- ProfileImporter importer = mock(ProfileImporter.class);
- when(importer.getKey()).thenReturn("pmd");
- doAnswer(new Answer() {
- public Object answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- ValidationMessages validationMessages = (ValidationMessages) args[1];
- validationMessages.addInfoText("an info message");
- validationMessages.addWarningText("a warning message");
- return profile;
- }
- }).when(importer).importProfile(any(Reader.class), any(ValidationMessages.class));
- importers.add(importer);
-
- QProfileResult result = operations.importXml(new QProfile().setId(1), "pmd", "<xml/>", session);
- ;
- assertThat(result.infos()).hasSize(1);
- assertThat(result.warnings()).hasSize(1);
- }
-
- @Test
- public void fail_to_import_profile_from_xml_plugin_if_error() throws Exception {
- final RulesProfile profile = RulesProfile.create("Default", "java");
- Rule rule = Rule.create("pmd", "rule1");
- rule.createParameter("max");
- rule.setId(10);
- ActiveRule activeRule = profile.activateRule(rule, RulePriority.BLOCKER);
- activeRule.setParameter("max", "10");
-
- ProfileImporter importer = mock(ProfileImporter.class);
- when(importer.getKey()).thenReturn("pmd");
- importers.add(importer);
-
- doAnswer(new Answer() {
- public Object answer(InvocationOnMock invocation) {
- Object[] args = invocation.getArguments();
- ValidationMessages validationMessages = (ValidationMessages) args[1];
- validationMessages.addErrorText("error!");
- return profile;
- }
- }).when(importer).importProfile(any(Reader.class), any(ValidationMessages.class));
-
- try {
- operations.importXml(new QProfile().setId(1), "pmd", "<xml/>", session);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(BadRequestException.class);
- }
- }
-
- @Test
- public void fail_to_import_profile_when_missing_importer() throws Exception {
- final RulesProfile profile = RulesProfile.create("Default", "java");
- Rule rule = Rule.create("pmd", "rule1");
- rule.createParameter("max");
- rule.setId(10);
- ActiveRule activeRule = profile.activateRule(rule, RulePriority.BLOCKER);
- activeRule.setParameter("max", "10");
-
- ProfileImporter importer = mock(ProfileImporter.class);
- when(importer.getKey()).thenReturn("pmd");
- importers.add(importer);
-
- when(importer.importProfile(any(Reader.class), any(ValidationMessages.class))).thenReturn(profile);
-
- try {
- operations.importXml(new QProfile().setId(1), "unknown", "<xml/>", session);
- fail();
- } catch (Exception e) {
- assertThat(e).isInstanceOf(BadRequestException.class).hasMessage("No such importer : unknown");
- }
- verify(importer, never()).importProfile(any(Reader.class), any(ValidationMessages.class));
- }
-
- @Test
- public void get_profile_importers_for_language() throws Exception {
- // 2 importers not declaring supported languages -> match all languages -> to be include in result
- ProfileImporter importersWithEmptySupportedLanguagesList = mock(ProfileImporter.class);
- when(importersWithEmptySupportedLanguagesList.getSupportedLanguages()).thenReturn(new String[] {});
- importers.add(importersWithEmptySupportedLanguagesList);
- importers.add(mock(ProfileImporter.class));
-
- // 1 importers supporting the java language -> to be include in result
- ProfileImporter importerSupportingJava = mock(ProfileImporter.class);
- when(importerSupportingJava.getSupportedLanguages()).thenReturn(new String[] {"java"});
- importers.add(importerSupportingJava);
-
- // 1 importers supporting another language -> not to be include in result
- ProfileImporter importerSupportingAnotherLanguage = mock(ProfileImporter.class);
- when(importerSupportingAnotherLanguage.getSupportedLanguages()).thenReturn(new String[] {"js"});
- importers.add(importerSupportingAnotherLanguage);
-
- assertThat(operations.getProfileImportersForLanguage("java")).hasSize(3);
- }
-
-}
*/
package org.sonar.server.qualityprofile;
+import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import org.junit.After;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Test;
+import org.sonar.api.profiles.ProfileExporter;
+import org.sonar.api.profiles.ProfileImporter;
+import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RulePriority;
+import org.sonar.api.utils.ValidationMessages;
import org.sonar.core.activity.Activity;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.core.persistence.DbSession;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.user.UserDto;
import org.sonar.server.activity.ActivityService;
import org.sonar.server.tester.ServerTester;
import org.sonar.server.user.MockUserSession;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class QProfileServiceMediumTest {
@ClassRule
- public static ServerTester tester = new ServerTester();
+ public static ServerTester tester = new ServerTester().addComponents(XooProfileImporter.class, XooExporter.class);
DbClient db;
DbSession dbSession;
dbSession.close();
}
+ @Test
+ public void create_profile() throws Exception {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("me");
+
+ QualityProfileDto profile = service.create(QProfileName.createFor("xoo", "New Profile"), null).profile();
+
+ assertThat(loader.getByKey(profile.getKey())).isNotNull();
+ assertThat(loader.getByKey(profile.getKey()).getLanguage()).isEqualTo("xoo");
+ assertThat(loader.getByKey(profile.getKey()).getName()).isEqualTo("New Profile");
+ }
+
+ @Test
+ public void create_profile_with_xml() throws Exception {
+ MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("me");
+
+ db.ruleDao().insert(dbSession, RuleTesting.newDto(RuleKey.of("xoo", "R1")).setLanguage("xoo").setSeverity("MINOR"));
+ dbSession.commit();
+
+ QProfileResult result = service.create(QProfileName.createFor("xoo", "New Profile"), ImmutableMap.of("XooProfileImporter", "<xml/>"));
+ QualityProfileDto profile = result.profile();
+
+ assertThat(loader.getByKey(profile.getKey())).isNotNull();
+ assertThat(loader.getByKey(profile.getKey()).getLanguage()).isEqualTo("xoo");
+ assertThat(loader.getByKey(profile.getKey()).getName()).isEqualTo("New Profile");
+
+ List<ActiveRule> activeRules = loader.findActiveRulesByProfile(profile.getKey());
+ assertThat(activeRules).hasSize(1);
+ }
+
@Test
public void count_by_all_profiles() throws Exception {
MockUserSession.set().setGlobalPermissions(GlobalPermissions.QUALITY_PROFILE_ADMIN).setLogin("me");
assertThat(service.getDefault("xoo").getKey()).isEqualTo(XOO_P1_KEY);
}
+
+ public static class XooExporter extends ProfileExporter {
+ public XooExporter() {
+ super("xootool", "Xoo Tool");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[]{"xoo"};
+ }
+
+ @Override
+ public String getMimeType() {
+ return "plain/custom";
+ }
+
+ @Override
+ public void exportProfile(RulesProfile profile, Writer writer) {
+ try {
+ writer.write("xoo -> " + profile.getName() + " -> " + profile.getActiveRules().size());
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+
+ public static class XooProfileImporter extends ProfileImporter {
+ public XooProfileImporter() {
+ super("XooProfileImporter", "Xoo Profile Importer");
+ }
+
+ @Override
+ public String[] getSupportedLanguages() {
+ return new String[]{"xoo"};
+ }
+
+ @Override
+ public RulesProfile importProfile(Reader reader, ValidationMessages messages) {
+ RulesProfile rulesProfile = RulesProfile.create();
+ Rule rule = Rule.create("xoo", "R1");
+ rule.createParameter("acceptWhitespace");
+ org.sonar.api.rules.ActiveRule activeRule = rulesProfile.activateRule(rule, RulePriority.CRITICAL);
+ activeRule.setParameter("acceptWhitespace", "true");
+ return rulesProfile;
+ }
+ }
+
}
package org.sonar.server.qualityprofile;
import com.google.common.collect.ImmutableMap;
-import org.junit.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.ClassRule;
+import org.junit.Test;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rule.Severity;
import org.sonar.core.qualityprofile.db.ActiveRuleDto;
import org.sonar.core.qualityprofile.db.ActiveRuleKey;
import org.sonar.core.qualityprofile.db.ActiveRuleParamDto;
+import org.sonar.core.qualityprofile.db.QualityProfileDto;
import org.sonar.core.rule.RuleDto;
import org.sonar.core.rule.RuleParamDto;
import org.sonar.server.db.DbClient;
RuleActivator ruleActivator;
ActiveRuleIndex index;
+ QualityProfileDto profileDto;
+
@Before
public void before() {
tester.clearDbAndIndexes();
.setName("format").setDefaultValue("txt").setType(RuleParamType.STRING.type()));
// create pre-defined profile P1
- db.qualityProfileDao().insert(dbSession, QProfileTesting.newXooP1());
+ profileDto = QProfileTesting.newXooP1();
+ db.qualityProfileDao().insert(dbSession, profileDto);
dbSession.commit();
dbSession.clearCache();
}
assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
}
+ @Test
+ public void activate_with_profile_dto() throws Exception {
+ RuleActivation activation = new RuleActivation(RuleTesting.XOO_X1);
+ activation.setSeverity(Severity.BLOCKER);
+ activation.setParameter("max", "7");
+ activation.setParameter("min", "3");
+ List<ActiveRuleChange> changes = ruleActivator.activate(dbSession, activation, profileDto);
+ dbSession.commit();
+ dbSession.clearCache();
+
+ assertThat(countActiveRules(XOO_P1_KEY)).isEqualTo(1);
+ verifyHasActiveRule(ActiveRuleKey.of(XOO_P1_KEY, RuleTesting.XOO_X1), Severity.BLOCKER, null,
+ ImmutableMap.of("max", "7", "min", "3"));
+ assertThat(changes).hasSize(1);
+ assertThat(changes.get(0).getType()).isEqualTo(ActiveRuleChange.Type.ACTIVATED);
+ }
+
@Test
public void activate_with_default_severity_and_parameter() throws Exception {
activate(new RuleActivation(RuleTesting.XOO_X1), XOO_P1_KEY);
end
end
profile_name = Java::OrgSonarServerQualityprofile::QProfileName.new(params[:language], params[:name])
- Internal.qprofile_service.create(profile_name)
- # TODO use files_by_key
- #flash[:notice] = message('quality_profiles.profile_x_created', :params => result.profile.name)
- #flash_result(result)
+ result = Internal.qprofile_service.create(profile_name, files_by_key)
+ flash[:notice] = message('quality_profiles.profile_x_created', :params => result.profile().getName())
+ flash_result(result)
end
redirect_to :action => 'index'
end
def flash_result(result)
# only 4 messages are kept each time to avoid cookie overflow.
unless result.infos.empty?
- flash[:notice] += result.infos.to_a[0...4].join('<br/>')
+ flash[:notice] += '<br/>' + result.infos.to_a[0...4].join('<br/>')
end
unless result.warnings.empty?
flash[:warning] = result.warnings.to_a[0...4].join('<br/>')
<%
language = controller.java_facade.getLanguages().find { |l| l.getKey()==language_key }
- importers = Internal.component(Java::OrgSonarServerQualityprofile::QProfileRepositoryExporter.java_class).getProfileImportersForLanguage(language_key)
+ importers = Internal.component(Java::OrgSonarServerQualityprofile::QProfileExporters.java_class).findProfileImportersForLanguage(language_key)
%>
<form id="create-profile-form" action="profiles/create" enctype="multipart/form-data" method="POST">
<fieldset>