aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--microbenchmark-template/pom.xml2
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java74
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfile.java26
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java179
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchData.java62
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchDataLoader.java215
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java7
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java45
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java8
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java2
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java9
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java133
-rw-r--r--server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json16
-rw-r--r--sonar-db/src/test/java/org/sonar/db/DbTester.java4
-rw-r--r--sonar-db/src/test/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java48
22 files changed, 596 insertions, 248 deletions
diff --git a/microbenchmark-template/pom.xml b/microbenchmark-template/pom.xml
index 9aeaa598e29..3a23a5b48a4 100644
--- a/microbenchmark-template/pom.xml
+++ b/microbenchmark-template/pom.xml
@@ -28,7 +28,7 @@
</dependency>
<dependency>
<groupId>${project.groupId}</groupId>
- <artifactId>sonar-dbClient</artifactId>
+ <artifactId>sonar-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
diff --git a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
index 62a58ce92a4..5a1c1e91476 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
@@ -252,6 +252,7 @@ import org.sonar.server.qualityprofile.ws.RenameAction;
import org.sonar.server.qualityprofile.ws.RestoreAction;
import org.sonar.server.qualityprofile.ws.RestoreBuiltInAction;
import org.sonar.server.qualityprofile.ws.RuleActivationActions;
+import org.sonar.server.qualityprofile.ws.SearchDataLoader;
import org.sonar.server.qualityprofile.ws.SetDefaultAction;
import org.sonar.server.rule.CommonRuleDefinitionsImpl;
import org.sonar.server.rule.DefaultRuleFinder;
@@ -344,16 +345,16 @@ public class PlatformLevel4 extends PlatformLevel {
IndexDefinitions.class,
IndexCreator.class,
- // Activity
+ // Activity
ActivityService.class,
ActivityIndexDefinition.class,
ActivityIndexer.class,
ActivityIndex.class,
- // batch
+ // batch
BatchWsModule.class,
- // Dashboard
+ // Dashboard
DashboardsWs.class,
org.sonar.server.dashboard.ws.ShowAction.class,
ProjectDefaultDashboard.class,
@@ -391,12 +392,12 @@ public class PlatformLevel4 extends PlatformLevel {
ProjectIssueFilterWidget.class,
IssueTagCloudWidget.class,
- // update center
+ // update center
UpdateCenterClient.class,
UpdateCenterMatrixFactory.class,
UpdateCenterWs.class,
- // quality profile
+ // quality profile
XMLProfileParser.class,
XMLProfileSerializer.class,
AnnotationProfileParser.class,
@@ -408,6 +409,7 @@ public class PlatformLevel4 extends PlatformLevel {
BuiltInProfiles.class,
RestoreBuiltInAction.class,
org.sonar.server.qualityprofile.ws.SearchAction.class,
+ SearchDataLoader.class,
SetDefaultAction.class,
ProjectsAction.class,
org.sonar.server.qualityprofile.ws.DeleteAction.class,
@@ -439,7 +441,7 @@ public class PlatformLevel4 extends PlatformLevel {
QProfileReset.class,
RubyQProfileActivityService.class,
- // rule
+ // rule
AnnotationRuleParser.class,
XMLRuleParser.class,
DefaultRuleFinder.class,
@@ -467,17 +469,17 @@ public class PlatformLevel4 extends PlatformLevel {
RepositoriesAction.class,
org.sonar.server.rule.ws.AppAction.class,
- // languages
+ // languages
Languages.class,
LanguageWs.class,
org.sonar.server.language.ws.ListAction.class,
- // activity
+ // activity
ActivitiesWs.class,
org.sonar.server.activity.ws.SearchAction.class,
ActivityMapping.class,
- // measure
+ // measure
MeasureFilterFactory.class,
MeasureFilterExecutor.class,
MeasureFilterEngine.class,
@@ -489,14 +491,14 @@ public class PlatformLevel4 extends PlatformLevel {
DefaultMetricFinder.class,
TimeMachineWs.class,
- // quality gates
+ // quality gates
QualityGateDao.class,
QualityGateConditionDao.class,
QualityGates.class,
ProjectQgateAssociationDao.class,
QgateProjectFinder.class,
- org.sonar.server.qualitygate.ws.ListAction.class,
+ org.sonar.server.qualitygate.ws.ListAction.class,
org.sonar.server.qualitygate.ws.SearchAction.class,
org.sonar.server.qualitygate.ws.ShowAction.class,
org.sonar.server.qualitygate.ws.CreateAction.class,
@@ -513,17 +515,17 @@ public class PlatformLevel4 extends PlatformLevel {
org.sonar.server.qualitygate.ws.AppAction.class,
QGatesWs.class,
- // web services
+ // web services
WebServiceEngine.class,
ListingWs.class,
- // localization
+ // localization
L10nWs.class,
- // authentication
+ // authentication
AuthenticationWs.class,
- // users
+ // users
SecurityRealmFactory.class,
DeprecatedUserFinder.class,
NewUserNotifier.class,
@@ -545,12 +547,12 @@ public class PlatformLevel4 extends PlatformLevel {
UserIndex.class,
UserUpdater.class,
- // groups
+ // groups
GroupMembershipService.class,
GroupMembershipFinder.class,
UserGroupsModule.class,
- // permissions
+ // permissions
PermissionRepository.class,
PermissionService.class,
PermissionUpdater.class,
@@ -558,7 +560,7 @@ public class PlatformLevel4 extends PlatformLevel {
PermissionFinder.class,
PermissionsWsModule.class,
- // components
+ // components
ProjectsWsModule.class,
DefaultComponentFinder.class,
DefaultRubyComponentService.class,
@@ -573,12 +575,12 @@ public class PlatformLevel4 extends PlatformLevel {
NewAlerts.newMetadata(),
ComponentCleanerService.class,
- // views
+ // views
ViewIndexDefinition.class,
ViewIndexer.class,
ViewIndex.class,
- // issues
+ // issues
IssueIndexDefinition.class,
IssueIndexer.class,
IssueAuthorizationIndexer.class,
@@ -612,13 +614,13 @@ public class PlatformLevel4 extends PlatformLevel {
EmailNotificationChannel.class,
AlertsEmailTemplate.class,
- IssueFilterWsModule.class,
+ IssueFilterWsModule.class,
- // action plan
+ // action plan
ActionPlanWs.class,
ActionPlanService.class,
- // issues actions
+ // issues actions
AssignAction.class,
PlanAction.class,
SetSeverityAction.class,
@@ -627,7 +629,7 @@ public class PlatformLevel4 extends PlatformLevel {
AddTagsAction.class,
RemoveTagsAction.class,
- // technical debt
+ // technical debt
DebtModelService.class,
DebtModelOperations.class,
DebtModelLookup.class,
@@ -637,7 +639,7 @@ public class PlatformLevel4 extends PlatformLevel {
DebtRulesXMLImporter.class,
DebtCharacteristicsXMLImporter.class,
- // source
+ // source
HtmlSourceDecorator.class,
SourceService.class,
SourcesWs.class,
@@ -648,23 +650,23 @@ public class PlatformLevel4 extends PlatformLevel {
IndexAction.class,
ScmAction.class,
- // Duplications
+ // Duplications
DuplicationsParser.class,
DuplicationsWs.class,
DuplicationsJsonWriter.class,
org.sonar.server.duplication.ws.ShowAction.class,
- // text
+ // text
MacroInterpreter.class,
RubyTextService.class,
- // Notifications
+ // Notifications
EmailSettings.class,
NotificationService.class,
NotificationCenter.class,
DefaultNotificationManager.class,
- // Tests
+ // Tests
CoverageService.class,
TestsWs.class,
CoveredFilesAction.class,
@@ -673,12 +675,12 @@ public class PlatformLevel4 extends PlatformLevel {
TestIndex.class,
TestIndexer.class,
- // Properties
+ // Properties
PropertiesWs.class,
- TypeValidationModule.class,
+ TypeValidationModule.class,
- // System
+ // System
RestartAction.class,
InfoAction.class,
UpgradesAction.class,
@@ -693,7 +695,7 @@ public class PlatformLevel4 extends PlatformLevel {
MigrateDbAction.class,
DbMigrationStatusAction.class,
- // Plugins WS
+ // Plugins WS
PluginWSCommons.class,
PluginUpdateAggregator.class,
InstalledAction.class,
@@ -706,7 +708,7 @@ public class PlatformLevel4 extends PlatformLevel {
CancelAllAction.class,
PluginsWs.class,
- // Compute engine
+ // Compute engine
CEQueueStatusImpl.class,
ComputeEngineQueueMonitor.class,
ReportQueue.class,
@@ -720,11 +722,11 @@ public class PlatformLevel4 extends PlatformLevel {
ProjectSettingsFactory.class,
IndexPurgeListener.class,
- // Views plugin
+ // Views plugin
ViewsBootstrap.class,
ViewsStopper.class,
- // UI
+ // UI
GlobalNavigationAction.class,
SettingsNavigationAction.class,
ComponentNavigationAction.class,
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfile.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfile.java
index c30b024c0e0..ba1dc1e05bd 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfile.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/QProfile.java
@@ -20,13 +20,12 @@
package org.sonar.server.qualityprofile;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.sonar.db.qualityprofile.QualityProfileDto;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
public class QProfile {
private int id;
@@ -35,6 +34,7 @@ public class QProfile {
private String language;
private String parent;
private boolean isDefault;
+ private String rulesUpdatedAt;
/**
* @deprecated in 4.4
@@ -94,11 +94,24 @@ public class QProfile {
return parent != null;
}
+ public boolean isDefault() {
+ return isDefault;
+ }
+
public QProfile setDefault(boolean isDefault) {
this.isDefault = isDefault;
return this;
}
+ public String getRulesUpdatedAt() {
+ return rulesUpdatedAt;
+ }
+
+ public QProfile setRulesUpdatedAt(String rulesUpdatedAt) {
+ this.rulesUpdatedAt = rulesUpdatedAt;
+ return this;
+ }
+
public static QProfile from(QualityProfileDto dto) {
return new QProfile()
.setId(dto.getId())
@@ -106,15 +119,12 @@ public class QProfile {
.setName(dto.getName())
.setLanguage(dto.getLanguage())
.setParent(dto.getParentKee())
- .setDefault(dto.isDefault());
+ .setDefault(dto.isDefault())
+ .setRulesUpdatedAt(dto.getRulesUpdatedAt());
}
@Override
public String toString() {
return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
}
-
- public boolean isDefault() {
- return isDefault;
- }
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
index e754e15a31c..552f6b07971 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchAction.java
@@ -19,65 +19,36 @@
*/
package org.sonar.server.qualityprofile.ws;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import java.util.Collections;
-import java.util.Comparator;
+import com.google.common.base.Function;
import java.util.List;
import java.util.Map;
-import java.util.Set;
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-import org.apache.commons.lang.builder.CompareToBuilder;
+import javax.annotation.Nonnull;
import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.NewAction;
-import org.sonar.api.server.ws.WebService.Param;
-import org.sonar.core.util.NonNullInputFunction;
-import org.sonar.db.qualityprofile.QualityProfileDao;
import org.sonar.server.qualityprofile.QProfile;
-import org.sonar.server.qualityprofile.QProfileLoader;
-import org.sonar.server.qualityprofile.QProfileLookup;
import org.sonarqube.ws.QualityProfiles.WsSearchResponse;
import org.sonarqube.ws.QualityProfiles.WsSearchResponse.QualityProfile;
+import static com.google.common.collect.Maps.uniqueIndex;
+import static java.lang.String.format;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
public class SearchAction implements QProfileWsAction {
- private static final String FIELD_KEY = "key";
- private static final String FIELD_NAME = "name";
- private static final String FIELD_LANGUAGE = "language";
- private static final String FIELD_LANGUAGE_NAME = "languageName";
- private static final String FIELD_IS_INHERITED = "isInherited";
- private static final String FIELD_IS_DEFAULT = "isDefault";
- private static final String FIELD_PARENT_KEY = "parentKey";
- private static final String FIELD_PARENT_NAME = "parentName";
- private static final String FIELD_ACTIVE_RULE_COUNT = "activeRuleCount";
- private static final String FIELD_PROJECT_COUNT = "projectCount";
- private static final String FIELD_RULES_UPDATED_AT = "rulesUpdatedAt";
-
- private static final Set<String> ALL_FIELDS = ImmutableSet.of(
- FIELD_KEY, FIELD_NAME, FIELD_LANGUAGE, FIELD_LANGUAGE_NAME, FIELD_IS_INHERITED, FIELD_PARENT_KEY, FIELD_PARENT_NAME, FIELD_IS_DEFAULT, FIELD_ACTIVE_RULE_COUNT,
- FIELD_PROJECT_COUNT, FIELD_RULES_UPDATED_AT);
-
- private static final String PARAM_LANGUAGE = FIELD_LANGUAGE;
- private static final String PARAM_COMPONENT_KEY = "componentKey";
- private static final String PARAM_DEFAULT = "default";
- private static final String PARAM_PROFILE_NAME = "profileName";
+ static final String PARAM_LANGUAGE = "language";
+ static final String PARAM_PROJECT_KEY = "projectKey";
+ static final String PARAM_DEFAULTS = "defaults";
+ static final String PARAM_PROFILE_NAME = "profileName";
+ private final SearchDataLoader dataLoader;
private final Languages languages;
- private final QProfileLookup profileLookup;
- private final QProfileLoader profileLoader;
- private final QualityProfileDao qualityProfileDao;
- public SearchAction(Languages languages, QProfileLookup profileLookup, QProfileLoader profileLoader, QualityProfileDao qualityProfileDao) {
+ public SearchAction(SearchDataLoader dataLoader, Languages languages) {
+ this.dataLoader = dataLoader;
this.languages = languages;
- this.profileLookup = profileLookup;
- this.profileLoader = profileLoader;
- this.qualityProfileDao = qualityProfileDao;
}
@Override
@@ -86,137 +57,107 @@ public class SearchAction implements QProfileWsAction {
.setSince("5.2")
.setDescription("List quality profiles.")
.setHandler(this)
- .addFieldsParam(ALL_FIELDS)
.setResponseExample(getClass().getResource("example-search.json"));
- action.createParam(PARAM_LANGUAGE)
- .setDescription("The key of a language supported by the platform. If specified, only profiles for the given language are returned.")
+ action
+ .createParam(PARAM_LANGUAGE)
+ .setDescription(
+ format("Language key. If provided, only profiles for the given language are returned. " +
+ "It should not be used with '%s', '%s or '%s' at the same time.", PARAM_DEFAULTS, PARAM_PROJECT_KEY, PARAM_PROFILE_NAME))
.setPossibleValues(LanguageParamUtils.getLanguageKeys(languages));
- action.createParam(PARAM_COMPONENT_KEY)
- .setDescription("Project or module key")
- .setExampleValue("org.codehaus.sonar:sonar");
-
- action.createParam(PARAM_DEFAULT)
- .setDescription("Return default quality profiles")
+ action.createParam(PARAM_PROJECT_KEY)
+ .setDescription(format("Project or module key. If provided, '%s' and '%s' parameters should not be provided.",
+ PARAM_LANGUAGE, PARAM_DEFAULTS))
+ .setExampleValue("my-project-key");
+
+ action
+ .createParam(PARAM_DEFAULTS)
+ .setDescription(format("Return the quality profile marked as default for each language. " +
+ "If provided, then the parameters '%s', '%s' and '%s' must not be set.",
+ PARAM_LANGUAGE, PARAM_PROJECT_KEY, PARAM_PROFILE_NAME))
+ .setDefaultValue(false)
.setBooleanPossibleValues();
action.createParam(PARAM_PROFILE_NAME)
- .setDescription("Profile name")
+ .setDescription(format("Profile name. It should be always used with the '%s' parameter.", PARAM_PROJECT_KEY))
.setExampleValue("SonarQube Way");
}
@Override
public void handle(Request request, Response response) throws Exception {
- List<String> fields = request.paramAsStrings(Param.FIELDS);
-
- String language = request.param(PARAM_LANGUAGE);
-
- List<QProfile> profiles;
- if (language == null) {
- profiles = profileLookup.allProfiles();
- } else {
- profiles = profileLookup.profiles(language);
- }
-
- Collections.sort(profiles, new Comparator<QProfile>() {
- @Override
- public int compare(QProfile o1, QProfile o2) {
- return new CompareToBuilder()
- .append(o1.language(), o2.language())
- .append(o1.name(), o2.name())
- .toComparison();
- }
- });
- WsSearchResponse protobufResponse = buildResponse(profiles, fields);
-
+ SearchData data = dataLoader.load(request);
+ WsSearchResponse protobufResponse = buildResponse(data);
writeProtobuf(protobufResponse, request, response);
}
- private WsSearchResponse buildResponse(List<QProfile> profiles, List<String> fields) {
- Map<String, QProfile> profilesByKey = Maps.uniqueIndex(profiles, new NonNullInputFunction<QProfile, String>() {
- @Override
- protected String doApply(QProfile input) {
- return input.key();
- }
- });
- Map<String, Long> activeRuleCountByKey = profileLoader.countAllActiveRules();
- Map<String, Long> projectCountByKey = qualityProfileDao.countProjectsByProfileKey();
+ private WsSearchResponse buildResponse(SearchData data) {
+ List<QProfile> profiles = data.getProfiles();
+ Map<String, QProfile> profilesByKey = uniqueIndex(profiles, new QProfileToKey());
WsSearchResponse.Builder response = WsSearchResponse.newBuilder();
QualityProfile.Builder profileBuilder = QualityProfile.newBuilder();
for (QProfile profile : profiles) {
- if (languages.get(profile.language()) == null) {
- // Hide profiles on an unsupported language
- continue;
- }
-
- String key = profile.key();
- Long activeRuleCount = activeRuleCountByKey.containsKey(key) ? activeRuleCountByKey.get(key) : 0L;
- Long projectCount = projectCountByKey.containsKey(key) ? projectCountByKey.get(key) : 0L;
+ String profileKey = profile.key();
profileBuilder.clear();
- if (shouldSetValue(FIELD_KEY, profile.key(), fields)) {
+ if (isNotNull(profile.key())) {
profileBuilder.setKey(profile.key());
}
- if (shouldSetValue(FIELD_NAME, profile.name(), fields)) {
+ if (isNotNull(profile.name())) {
profileBuilder.setName(profile.name());
}
- if (shouldSetValue(FIELD_ACTIVE_RULE_COUNT, activeRuleCount, fields)) {
- profileBuilder.setActiveRuleCount(activeRuleCount);
+ if (isNotNull(profile.getRulesUpdatedAt())) {
+ profileBuilder.setRulesUpdatedAt(profile.getRulesUpdatedAt());
}
- if (!profile.isDefault() && shouldSetValue(FIELD_PROJECT_COUNT, projectCount, fields)) {
- profileBuilder.setProjectCount(projectCount);
- }
-
- writeLanguageFields(profileBuilder, profile, fields);
- writeParentFields(profileBuilder, profile, fields, profilesByKey);
- // Special case for booleans
- if (fieldIsNeeded(FIELD_IS_INHERITED, fields)) {
- profileBuilder.setIsInherited(profile.isInherited());
+ if (isNotNull(data.getActiveRuleCount(profileKey))) {
+ profileBuilder.setActiveRuleCount(data.getActiveRuleCount(profileKey));
}
- if (fieldIsNeeded(FIELD_IS_DEFAULT, fields)) {
- profileBuilder.setIsDefault(profile.isDefault());
+ if (!profile.isDefault() && isNotNull(data.getProjectCount(profileKey))) {
+ profileBuilder.setProjectCount(data.getProjectCount(profileKey));
}
+
+ writeLanguageFields(profileBuilder, profile);
+ writeParentFields(profileBuilder, profile, profilesByKey);
+ profileBuilder.setIsInherited(profile.isInherited());
+ profileBuilder.setIsDefault(profile.isDefault());
response.addProfiles(profileBuilder);
}
return response.build();
}
- private void writeLanguageFields(QualityProfile.Builder profileBuilder, QProfile profile, List<String> fields) {
+ private void writeLanguageFields(QualityProfile.Builder profileBuilder, QProfile profile) {
String languageKey = profile.language();
- if (shouldSetValue(FIELD_LANGUAGE, languageKey, fields)) {
+ if (isNotNull(languageKey)) {
profileBuilder.setLanguage(languageKey);
}
String languageName = languages.get(languageKey).getName();
- if (shouldSetValue(FIELD_LANGUAGE_NAME, languageName, fields)) {
+ if (isNotNull(languageName)) {
profileBuilder.setLanguageName(languageName);
}
}
- private static void writeParentFields(QualityProfile.Builder profileBuilder, QProfile profile, List<String> fields, Map<String, QProfile> profilesByKey) {
+ private static void writeParentFields(QualityProfile.Builder profileBuilder, QProfile profile, Map<String, QProfile> profilesByKey) {
String parentKey = profile.parent();
QProfile parent = parentKey == null ? null : profilesByKey.get(parentKey);
- if (shouldSetValue(FIELD_PARENT_KEY, parentKey, fields)) {
+ if (isNotNull(parentKey)) {
profileBuilder.setParentKey(parentKey);
}
- if (parent != null && shouldSetValue(FIELD_PARENT_NAME, parent.name(), fields)) {
+ if (isNotNull(parent) && isNotNull(parent.name())) {
profileBuilder.setParentName(parent.name());
}
}
- @CheckForNull
- private static <T> T valueIfFieldNeeded(String field, T value, @Nullable List<String> fields) {
- return fieldIsNeeded(field, fields) ? value : null;
- }
-
- private static <T> boolean shouldSetValue(String field, T value, List<String> fields) {
- return valueIfFieldNeeded(field, value, fields) != null;
+ private static <T> boolean isNotNull(T value) {
+ return value != null;
}
- private static boolean fieldIsNeeded(String field, @Nullable List<String> fields) {
- return fields == null || fields.contains(field);
+ private static class QProfileToKey implements Function<QProfile, String> {
+ @Override
+ public String apply(@Nonnull QProfile input) {
+ return input.key();
+ }
}
}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchData.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchData.java
new file mode 100644
index 00000000000..88d7660774d
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchData.java
@@ -0,0 +1,62 @@
+/*
+ * 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.ws;
+
+import java.util.List;
+import java.util.Map;
+import org.sonar.server.qualityprofile.QProfile;
+
+import static com.google.common.base.Objects.firstNonNull;
+import static com.google.common.collect.ImmutableList.copyOf;
+import static com.google.common.collect.ImmutableMap.copyOf;
+
+public class SearchData {
+ private List<QProfile> profiles;
+ private Map<String, Long> activeRuleCountByProfileKey;
+ private Map<String, Long> projectCountByProfileKey;
+
+ public List<QProfile> getProfiles() {
+ return profiles;
+ }
+
+ public SearchData setProfiles(List<QProfile> profiles) {
+ this.profiles = copyOf(profiles);
+ return this;
+ }
+
+ public SearchData setActiveRuleCountByProfileKey(Map<String, Long> activeRuleCountByProfileKey) {
+ this.activeRuleCountByProfileKey = copyOf(activeRuleCountByProfileKey);
+ return this;
+ }
+
+ public SearchData setProjectCountByProfileKey(Map<String, Long> projectCountByProfileKey) {
+ this.projectCountByProfileKey = copyOf(projectCountByProfileKey);
+ return this;
+ }
+
+ public long getActiveRuleCount(String profileKey) {
+ return firstNonNull(activeRuleCountByProfileKey.get(profileKey), 0L);
+ }
+
+ public long getProjectCount(String profileKey) {
+ return firstNonNull(projectCountByProfileKey.get(profileKey), 0L);
+ }
+}
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchDataLoader.java
new file mode 100644
index 00000000000..e0de16f8746
--- /dev/null
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualityprofile/ws/SearchDataLoader.java
@@ -0,0 +1,215 @@
+/*
+ * 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.ws;
+
+import com.google.common.base.Predicate;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import javax.annotation.Nullable;
+import org.apache.commons.lang.builder.CompareToBuilder;
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.server.ws.Request;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.qualityprofile.QualityProfileDto;
+import org.sonar.server.qualityprofile.QProfile;
+import org.sonar.server.qualityprofile.QProfileFactory;
+import org.sonar.server.qualityprofile.QProfileLoader;
+import org.sonar.server.qualityprofile.QProfileLookup;
+
+import static com.google.common.base.Preconditions.checkState;
+import static com.google.common.collect.FluentIterable.from;
+import static java.lang.String.format;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_DEFAULTS;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_LANGUAGE;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROFILE_NAME;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROJECT_KEY;
+import static org.sonar.server.ws.WsUtils.checkRequest;
+
+public class SearchDataLoader {
+ private final Languages languages;
+ private final QProfileLookup profileLookup;
+ private final QProfileLoader profileLoader;
+ private final QProfileFactory profileFactory;
+ private final DbClient dbClient;
+
+ public SearchDataLoader(Languages languages, QProfileLookup profileLookup, QProfileLoader profileLoader, QProfileFactory profileFactory, DbClient dbClient) {
+ this.languages = languages;
+ this.profileLookup = profileLookup;
+ this.profileLoader = profileLoader;
+ this.profileFactory = profileFactory;
+ this.dbClient = dbClient;
+ }
+
+ SearchData load(Request request) {
+ validateRequest(request);
+
+ return new SearchData()
+ .setProfiles(findProfiles(request))
+ .setActiveRuleCountByProfileKey(profileLoader.countAllActiveRules())
+ .setProjectCountByProfileKey(dbClient.qualityProfileDao().countProjectsByProfileKey());
+ }
+
+ private List<QProfile> findProfiles(Request request) {
+ List<QProfile> profiles;
+ if (askDefaultProfiles(request)) {
+ profiles = findDefaultProfiles();
+ } else if (hasComponentKey(request)) {
+ profiles = findProjectProfiles(request);
+ } else {
+ profiles = findAllProfiles(request);
+ }
+
+ return orderProfiles(profiles);
+ }
+
+ private static List<QProfile> orderProfiles(List<QProfile> profiles) {
+ return from(profiles)
+ .toSortedList(QProfileComparator.INSTANCE);
+ }
+
+ private List<QProfile> findAllProfiles(Request request) {
+ String language = request.param(PARAM_LANGUAGE);
+
+ List<QProfile> profiles = language != null ?
+ profileLookup.profiles(language)
+ : profileLookup.allProfiles();
+
+ return from(profiles)
+ .filter(new IsLanguageKnown())
+ .toList();
+ }
+
+ private List<QProfile> findProjectProfiles(Request request) {
+ String projectKey = request.param(PARAM_PROJECT_KEY);
+ String profileName = request.param(PARAM_PROFILE_NAME);
+
+ List<QProfile> profiles = new ArrayList<>();
+
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ for (Language language : languages.all()) {
+ String languageKey = language.getKey();
+ profiles.add(getProfile(dbSession, languageKey, projectKey, profileName));
+ }
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+
+ return profiles;
+ }
+
+ private List<QProfile> findDefaultProfiles() {
+ List<QProfile> profiles = new ArrayList<>();
+
+ DbSession dbSession = dbClient.openSession(false);
+ try {
+ for (Language language : languages.all()) {
+ profiles.add(getDefaultProfile(dbSession, language.getKey()));
+ }
+ } finally {
+ dbClient.closeSession(dbSession);
+ }
+
+ return profiles;
+ }
+
+ private static QProfile profileDtoToQProfile(QualityProfileDto dto) {
+ return new QProfile()
+ .setKey(dto.getKey())
+ .setName(dto.getName())
+ .setLanguage(dto.getLanguage())
+ .setDefault(dto.isDefault())
+ .setRulesUpdatedAt(dto.getRulesUpdatedAt());
+ }
+
+ /**
+ * First try to find a quality profile matching the given name (if provided) and current language
+ * If no profile found, try to find the quality profile set on the project (if provided)
+ * If still no profile found, try to find the default profile of the language
+ * <p/>
+ * Never return null because a default profile should always be set on each language
+ */
+ private QProfile getProfile(DbSession dbSession, String languageKey, @Nullable String projectKey, @Nullable String profileName) {
+ QualityProfileDto profileDto = profileName != null ? profileFactory.getByNameAndLanguage(dbSession, profileName, languageKey) : null;
+ if (profileDto == null && projectKey != null) {
+ profileDto = profileFactory.getByProjectAndLanguage(dbSession, projectKey, languageKey);
+ }
+ profileDto = profileDto != null ? profileDto : profileFactory.getDefault(dbSession, languageKey);
+ checkState(profileDto != null, format("No quality profile can been found on language '%s' for project '%s'", languageKey, projectKey));
+
+ return profileDtoToQProfile(profileDto);
+ }
+
+ private QProfile getDefaultProfile(DbSession dbSession, String languageKey) {
+ QualityProfileDto profile = profileFactory.getDefault(dbSession, languageKey);
+ checkState(profile != null, format("No quality profile can been found on language '%s'", languageKey));
+
+ return profileDtoToQProfile(profile);
+ }
+
+ private static void validateRequest(Request request) {
+ boolean hasLanguage = hasLanguage(request);
+ boolean isDefault = askDefaultProfiles(request);
+ boolean hasComponentKey = hasComponentKey(request);
+ boolean hasProfileName = hasProfileName(request);
+
+ checkRequest(!hasLanguage || (!hasComponentKey && !hasProfileName && !isDefault),
+ "The language parameter cannot be provided at the same time than the component key or profile name.");
+ checkRequest(!isDefault || (!hasComponentKey && !hasProfileName), "The default parameter cannot be provided at the same time than the component key or profile name");
+ }
+
+ private static boolean hasProfileName(Request request) {
+ return request.hasParam(PARAM_PROFILE_NAME);
+ }
+
+ private static boolean hasComponentKey(Request request) {
+ return request.hasParam(PARAM_PROJECT_KEY);
+ }
+
+ private static Boolean askDefaultProfiles(Request request) {
+ return request.paramAsBoolean(PARAM_DEFAULTS);
+ }
+
+ private static boolean hasLanguage(Request request) {
+ return request.hasParam(PARAM_LANGUAGE);
+ }
+
+ private enum QProfileComparator implements Comparator<QProfile> {
+ INSTANCE;
+ @Override
+ public int compare(QProfile o1, QProfile o2) {
+ return new CompareToBuilder()
+ .append(o1.language(), o2.language())
+ .append(o1.name(), o2.name())
+ .toComparison();
+ }
+ }
+
+ private class IsLanguageKnown implements Predicate<QProfile> {
+ @Override
+ public boolean apply(@Nullable QProfile profile) {
+ return languages.get(profile.language()) != null;
+ }
+ }
+}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java
index dc70a1eae9d..24362ac49c9 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectActionTest.java
@@ -22,10 +22,7 @@ package org.sonar.server.batch;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.runners.MockitoJUnitRunner;
import org.sonar.batch.protocol.input.ProjectRepositories;
import org.sonar.server.ws.WsTester;
@@ -33,11 +30,9 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-@RunWith(MockitoJUnitRunner.class)
public class ProjectActionTest {
- @Mock
- ProjectRepositoryLoader projectRepositoryLoader;
+ ProjectRepositoryLoader projectRepositoryLoader = mock(ProjectRepositoryLoader.class);
WsTester tester;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
index f2849863e44..6dde0afeffb 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectRepositoryLoaderMediumTest.java
@@ -41,6 +41,7 @@ import org.sonar.batch.protocol.input.QProfile;
import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
+import org.sonar.db.component.ComponentTesting;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.db.rule.RuleDto;
@@ -49,11 +50,9 @@ import org.sonar.db.rule.RuleTesting;
import org.sonar.db.source.FileSourceDao;
import org.sonar.db.source.FileSourceDto;
import org.sonar.db.source.FileSourceDto.Type;
-import org.sonar.db.component.ComponentTesting;
import org.sonar.server.db.DbClient;
import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.qualityprofile.QProfileName;
-import org.sonar.server.qualityprofile.QProfileTesting;
import org.sonar.server.qualityprofile.RuleActivation;
import org.sonar.server.qualityprofile.RuleActivator;
import org.sonar.server.tester.ServerTester;
@@ -62,6 +61,8 @@ import org.sonar.server.tester.UserSessionRule;
import static com.google.common.collect.Lists.newArrayList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;
+import static org.sonar.api.utils.DateUtils.formatDateTime;
+import static org.sonar.server.qualityprofile.QProfileTesting.newQProfileDto;
public class ProjectRepositoryLoaderMediumTest {
@@ -454,8 +455,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(ruleUpdatedAt));
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(ruleUpdatedAt));
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
tester.get(DbClient.class).qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profileDto.getKee(), dbSession);
@@ -478,8 +479,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(ruleUpdatedAt)).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
dbSession.commit();
@@ -501,8 +502,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(ruleUpdatedAt)).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
dbSession.commit();
@@ -521,8 +522,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
Date ruleUpdatedAt = DateUtils.parseDateTime("2014-01-14T13:00:00+0100");
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(ruleUpdatedAt)).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
dbSession.commit();
@@ -545,8 +546,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(ruleUpdatedAt));
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(ruleUpdatedAt));
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
tester.get(DbClient.class).qualityProfileDao().insertProjectProfileAssociation(project.uuid(), profileDto.getKee(), dbSession);
@@ -582,8 +583,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
RuleKey ruleKey = RuleKey.of("squid", "AvoidCycle");
@@ -624,8 +625,8 @@ public class ProjectRepositoryLoaderMediumTest {
RuleTesting.newDto(ruleKey2).setName("Avoid NPE").setLanguage(ServerTester.Xoo.KEY)
);
- QualityProfileDto profileDto1 = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd");
- QualityProfileDto profileDto2 = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "Another profile"), "efgh");
+ QualityProfileDto profileDto1 = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd");
+ QualityProfileDto profileDto2 = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "Another profile"), "efgh");
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto1, profileDto2);
// The first profile is the profile used but the project
@@ -655,8 +656,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd")
- .setRulesUpdatedAt(DateUtils.formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd")
+ .setRulesUpdatedAt(formatDateTime(DateUtils.parseDateTime("2014-01-14T13:00:00+0100"))).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
for (int i = 0; i < 20; i++) {
@@ -679,8 +680,8 @@ public class ProjectRepositoryLoaderMediumTest {
userSessionRule.login("john").setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION);
tester.get(DbClient.class).componentDao().insert(dbSession, project);
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(ruleUpdatedAt)).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(ruleUpdatedAt)).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
RuleKey ruleKey = RuleKey.of("squid", "ArchitecturalConstraint");
@@ -832,8 +833,8 @@ public class ProjectRepositoryLoaderMediumTest {
}
private void addDefaultProfile() {
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
- DateUtils.formatDateTime(new Date())).setDefault(true);
+ QualityProfileDto profileDto = newQProfileDto(QProfileName.createFor(ServerTester.Xoo.KEY, "SonarQube way"), "abcd").setRulesUpdatedAt(
+ formatDateTime(new Date())).setDefault(true);
tester.get(DbClient.class).qualityProfileDao().insert(dbSession, profileDto);
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java
index 4f679064967..b7e8c0fff41 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ActiveRuleBackendMediumTest.java
@@ -371,7 +371,7 @@ public class ActiveRuleBackendMediumTest {
List<String> profileKeys = newArrayList();
for (int i = 0; i < 30; i++) {
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor("xoo", "profile-" + i), "profile-" + i);
+ QualityProfileDto profileDto = QProfileTesting.newQProfileDto(QProfileName.createFor("xoo", "profile-" + i), "profile-" + i);
profileKeys.add(profileDto.getKey());
db.qualityProfileDao().insert(dbSession, profileDto);
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java
index b93717d10b0..7b875b2bcaf 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileExportersTest.java
@@ -129,7 +129,7 @@ public class QProfileExportersTest {
@Test
public void import_xml() {
- QualityProfileDto profileDto = QProfileTesting.newDto(QProfileName.createFor("xoo", "import_xml"), "import_xml");
+ QualityProfileDto profileDto = QProfileTesting.newQProfileDto(QProfileName.createFor("xoo", "import_xml"), "import_xml");
db.qualityProfileDao().insert(dbSession, profileDto);
dbSession.commit();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java
index f204c850702..cfde9ba3aff 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileFactoryMediumTest.java
@@ -334,7 +334,7 @@ public class QProfileFactoryMediumTest {
@Test
public void get_profile_by_name_and_language() {
- QualityProfileDto profileDto = QProfileTesting.newDto(new QProfileName("xoo", "SonarQube way"), "abcd");
+ QualityProfileDto profileDto = QProfileTesting.newQProfileDto(new QProfileName("xoo", "SonarQube way"), "abcd");
db.qualityProfileDao().insert(dbSession, profileDto);
dbSession.commit();
dbSession.clearCache();
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTest.java
index 4fb83dae022..1ae6949cb88 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTest.java
@@ -39,7 +39,7 @@ public class QProfileTest {
@Test
public void to_string() {
assertThat(new QProfile().setId(1).setName("Default").setLanguage("java").setParent("Parent").toString())
- .contains("[id=1,key=<null>,name=Default,language=java,parent=Parent,isDefault=false]");
+ .contains("[id=1,key=<null>,name=Default,language=java,parent=Parent,isDefault=false,rulesUpdatedAt=<null>]");
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java
index a74a5822491..0f13b76ecb2 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/QProfileTesting.java
@@ -33,19 +33,19 @@ public class QProfileTesting {
public static final QProfileName XOO_P3_NAME = new QProfileName("xoo", "P3");
public static final String XOO_P3_KEY = "XOO_P3";
- public static QualityProfileDto newDto(QProfileName name, String key) {
+ public static QualityProfileDto newQProfileDto(QProfileName name, String key) {
return QualityProfileDto.createFor(key).setName(name.getName()).setLanguage(name.getLanguage());
}
public static QualityProfileDto newXooP1() {
- return newDto(XOO_P1_NAME, XOO_P1_KEY);
+ return newQProfileDto(XOO_P1_NAME, XOO_P1_KEY);
}
public static QualityProfileDto newXooP2() {
- return newDto(XOO_P2_NAME, XOO_P2_KEY);
+ return newQProfileDto(XOO_P2_NAME, XOO_P2_KEY);
}
public static QualityProfileDto newXooP3() {
- return newDto(XOO_P3_NAME, XOO_P3_KEY);
+ return newQProfileDto(XOO_P3_NAME, XOO_P3_KEY);
}
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java
index 4754961c4ce..917f55c4b23 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/ChangeParentActionMediumTest.java
@@ -269,7 +269,7 @@ public class ChangeParentActionMediumTest {
}
private QualityProfileDto createProfile(String lang, String name) {
- QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), "p" + lang + "-" + name.toLowerCase());
+ QualityProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, name), "p" + lang + "-" + name.toLowerCase());
db.qualityProfileDao().insert(session, profile);
return profile;
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java
index 56df66cbde7..ebdfbdd0deb 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/CompareActionMediumTest.java
@@ -188,7 +188,7 @@ public class CompareActionMediumTest {
}
private QualityProfileDto createProfile(String lang, String name, String key) {
- QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), key);
+ QualityProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, name), key);
db.qualityProfileDao().insert(session, profile);
session.commit();
return profile;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java
index 5583e65f88b..9c25d7ba87c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/InheritanceActionMediumTest.java
@@ -115,7 +115,7 @@ public class InheritanceActionMediumTest {
}
private QualityProfileDto createProfile(String lang, String name, String key) {
- QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, name), key);
+ QualityProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, name), key);
db.qualityProfileDao().insert(session, profile);
session.commit();
return profile;
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java
index 8b9a2c94f96..a4b6f74c50c 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsMediumTest.java
@@ -549,7 +549,7 @@ public class QProfilesWsMediumTest {
}
private QualityProfileDto createProfile(String lang) {
- QualityProfileDto profile = QProfileTesting.newDto(new QProfileName(lang, "P" + lang), "p" + lang);
+ QualityProfileDto profile = QProfileTesting.newQProfileDto(new QProfileName(lang, "P" + lang), "p" + lang);
db.qualityProfileDao().insert(session, profile);
return profile;
}
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
index 56930f9d279..f7f120ed209 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/QProfilesWsTest.java
@@ -30,7 +30,6 @@ import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.server.ws.WebService;
-import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.ValidationMessages;
import org.sonar.server.language.LanguageTesting;
import org.sonar.server.qualityprofile.QProfileExporters;
@@ -68,7 +67,7 @@ public class QProfilesWsTest {
new CreateAction(null, null, null, languages, importers, userSessionRule),
new ImportersAction(importers),
new RestoreBuiltInAction(null),
- new SearchAction(languages, null, null, null),
+ new SearchAction(null, languages),
new SetDefaultAction(languages, null, null, userSessionRule),
new ProjectsAction(null, userSessionRule),
new BackupAction(null, null, null, languages),
@@ -82,7 +81,7 @@ public class QProfilesWsTest {
new ExportersAction(),
new InheritanceAction(null, null, null, null, languages),
new RenameAction(null, userSessionRule)
- )).controller(QProfilesWs.API_ENDPOINT);
+ )).controller(QProfilesWs.API_ENDPOINT);
}
private ProfileImporter[] createImporters(Languages languages) {
@@ -123,10 +122,8 @@ public class QProfilesWsTest {
WebService.Action search = controller.action("search");
assertThat(search).isNotNull();
assertThat(search.isPost()).isFalse();
- assertThat(search.params()).hasSize(2);
+ assertThat(search.params()).hasSize(4);
assertThat(search.param("language").possibleValues()).containsOnly(xoo1Key, xoo2Key);
- assertThat(search.param(Param.FIELDS).possibleValues())
- .containsOnly("key", "name", "language", "languageName", "isInherited", "parentKey", "parentName", "isDefault", "activeRuleCount", "projectCount");
}
@Test
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java
index 4fc7b8e9ffb..d83aac49b21 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualityprofile/ws/SearchActionTest.java
@@ -20,30 +20,42 @@
package org.sonar.server.qualityprofile.ws;
import com.google.common.collect.ImmutableMap;
+import java.util.Date;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
+import org.junit.experimental.categories.Category;
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
-import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.System2;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDao;
-import org.sonar.db.component.ComponentTesting;
+import org.sonar.db.component.ComponentDto;
import org.sonar.db.qualityprofile.QualityProfileDao;
+import org.sonar.db.qualityprofile.QualityProfileDbTester;
import org.sonar.db.qualityprofile.QualityProfileDto;
import org.sonar.server.language.LanguageTesting;
+import org.sonar.server.qualityprofile.QProfileFactory;
import org.sonar.server.qualityprofile.QProfileLoader;
import org.sonar.server.qualityprofile.QProfileLookup;
+import org.sonar.server.qualityprofile.db.ActiveRuleDao;
+import org.sonar.server.rule.db.RuleDao;
import org.sonar.server.ws.WsActionTester;
+import org.sonar.test.DbTests;
+import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import static org.sonar.db.component.ComponentTesting.newProjectDto;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_DEFAULTS;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROFILE_NAME;
+import static org.sonar.server.qualityprofile.ws.SearchAction.PARAM_PROJECT_KEY;
import static org.sonar.test.JsonAssert.assertJson;
+@Category(DbTests.class)
public class SearchActionTest {
@Rule
@@ -59,22 +71,29 @@ public class SearchActionTest {
private Language xoo2;
private DbSession dbSession;
private WsActionTester ws;
+ private QualityProfileDbTester qualityProfileDb;
@Before
public void setUp() {
- db.truncateTables();
dbClient = db.getDbClient();
- qualityProfileDao = dbClient.qualityProfileDao();
dbSession = db.getSession();
+ qualityProfileDao = dbClient.qualityProfileDao();
+ qualityProfileDb = new QualityProfileDbTester(db);
xoo1 = LanguageTesting.newLanguage("xoo1");
xoo2 = LanguageTesting.newLanguage("xoo2");
+ Languages languages = new Languages(xoo1, xoo2);
+ org.sonar.server.db.DbClient oldDbClient = new org.sonar.server.db.DbClient(
+ db.database(),
+ db.myBatis(),
+ dbClient.qualityProfileDao(),
+ new ActiveRuleDao(
+ dbClient.qualityProfileDao(),
+ new RuleDao(System2.INSTANCE),
+ System2.INSTANCE));
ws = new WsActionTester(new SearchAction(
- new Languages(xoo1, xoo2),
- new QProfileLookup(dbClient),
- profileLoader,
- qualityProfileDao));
+ new SearchDataLoader(languages, new QProfileLookup(dbClient), profileLoader, new QProfileFactory(oldDbClient), dbClient), languages));
}
@Test
@@ -91,8 +110,8 @@ public class SearchActionTest {
QualityProfileDto.createFor("sonar-way-other-666").setLanguage("other").setName("Sonar way").setDefault(true)
);
new ComponentDao().insert(dbSession,
- ComponentTesting.newProjectDto("project-uuid1"),
- ComponentTesting.newProjectDto("project-uuid2"));
+ newProjectDto("project-uuid1"),
+ newProjectDto("project-uuid2"));
qualityProfileDao.insertProjectProfileAssociation("project-uuid1", "sonar-way-xoo2-23456", dbSession);
qualityProfileDao.insertProjectProfileAssociation("project-uuid2", "sonar-way-xoo2-23456", dbSession);
commit();
@@ -103,29 +122,99 @@ public class SearchActionTest {
}
@Test
- public void search_with_fields() throws Exception {
+ public void search_for_language() throws Exception {
qualityProfileDao.insert(dbSession,
- QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way").setDefault(true),
- QualityProfileDto.createFor("sonar-way-xoo2-23456").setLanguage(xoo2.getKey()).setName("Sonar way"),
- QualityProfileDto.createFor("my-sonar-way-xoo2-34567").setLanguage(xoo2.getKey()).setName("My Sonar way").setParentKee("sonar-way-xoo2-23456")
+ QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way")
);
commit();
- String result = ws.newRequest().setParam(Param.FIELDS, "key,language").execute().getInput();
+ String result = ws.newRequest().setParam("language", xoo1.getKey()).execute().getInput();
- assertJson(result).isSimilarTo(getClass().getResource("SearchActionTest/search_fields.json"));
+ assertJson(result).isSimilarTo(getClass().getResource("SearchActionTest/search_xoo1.json"));
}
@Test
- public void search_for_language() throws Exception {
- qualityProfileDao.insert(dbSession,
- QualityProfileDto.createFor("sonar-way-xoo1-12345").setLanguage(xoo1.getKey()).setName("Sonar way")
- );
+ public void search_for_project_qp() {
+ QualityProfileDto qualityProfileOnXoo1 = QualityProfileDto.createFor("sonar-way-xoo1-12345")
+ .setLanguage(xoo1.getKey())
+ .setRulesUpdatedAtAsDate(new Date())
+ .setName("Sonar way");
+ QualityProfileDto qualityProfileOnXoo2 = QualityProfileDto.createFor("sonar-way-xoo2-12345")
+ .setLanguage(xoo2.getKey())
+ .setRulesUpdatedAtAsDate(new Date())
+ .setName("Sonar way");
+ QualityProfileDto anotherQualityProfileOnXoo1 = QualityProfileDto.createFor("sonar-way-xoo1-45678")
+ .setLanguage(xoo1.getKey())
+ .setRulesUpdatedAtAsDate(new Date())
+ .setName("Another way");
+ ComponentDto project = newProjectDto("project-uuid");
+ qualityProfileDb.insertQualityProfiles(qualityProfileOnXoo1, qualityProfileOnXoo2, anotherQualityProfileOnXoo1);
+ qualityProfileDb.insertProjectWithQualityProfileAssociations(project, qualityProfileOnXoo1, qualityProfileOnXoo2);
commit();
- String result = ws.newRequest().setParam("language", xoo1.getKey()).execute().getInput();
+ String result = ws.newRequest()
+ .setParam(PARAM_PROJECT_KEY, project.key())
+ .execute().getInput();
+
+ assertThat(result)
+ .contains("sonar-way-xoo1-12345", "sonar-way-xoo2-12345")
+ .doesNotContain("sonar-way-xoo1-45678");
+ }
+
+ @Test
+ public void search_for_default_qp() {
+ QualityProfileDto qualityProfileOnXoo1 = QualityProfileDto.createFor("sonar-way-xoo1-12345")
+ .setLanguage(xoo1.getKey())
+ .setName("Sonar way")
+ .setDefault(true);
+ QualityProfileDto qualityProfileOnXoo2 = QualityProfileDto.createFor("sonar-way-xoo2-12345")
+ .setLanguage(xoo2.getKey())
+ .setName("Sonar way")
+ .setDefault(true);
+ QualityProfileDto anotherQualityProfileOnXoo1 = QualityProfileDto.createFor("sonar-way-xoo1-45678")
+ .setLanguage(xoo1.getKey())
+ .setName("Sonar way")
+ .setDefault(false);
+ qualityProfileDb.insertQualityProfiles(qualityProfileOnXoo1, qualityProfileOnXoo2, anotherQualityProfileOnXoo1);
+ commit();
+
+ String result = ws.newRequest()
+ .setParam(PARAM_DEFAULTS, Boolean.TRUE.toString())
+ .execute().getInput();
+
+ assertThat(result)
+ .contains("sonar-way-xoo1-12345", "sonar-way-xoo2-12345")
+ .doesNotContain("sonar-way-xoo1-45678");
+ }
+
+ @Test
+ public void search_by_profile_name() {
+ QualityProfileDto qualityProfileOnXoo1 = QualityProfileDto.createFor("sonar-way-xoo1-12345")
+ .setLanguage(xoo1.getKey())
+ .setRulesUpdatedAtAsDate(new Date())
+ .setName("Sonar way");
+ QualityProfileDto qualityProfileOnXoo2 = QualityProfileDto.createFor("sonar-way-xoo2-12345")
+ .setLanguage(xoo2.getKey())
+ .setRulesUpdatedAtAsDate(new Date())
+ .setName("Sonar way");
+ QualityProfileDto anotherQualityProfileOnXoo1 = QualityProfileDto.createFor("sonar-way-xoo1-45678")
+ .setLanguage(xoo1.getKey())
+ .setRulesUpdatedAtAsDate(new Date())
+ .setName("Another way");
+ ComponentDto project = newProjectDto("project-uuid");
+ qualityProfileDb.insertQualityProfiles(qualityProfileOnXoo1, qualityProfileOnXoo2, anotherQualityProfileOnXoo1);
+ dbClient.componentDao().insert(dbSession, project);
+ commit();
+
+ String result = ws.newRequest()
+ .setParam(PARAM_PROJECT_KEY, project.key())
+ .setParam(PARAM_PROFILE_NAME, "Sonar way")
+ .execute().getInput();
+
+ assertThat(result)
+ .contains("sonar-way-xoo1-12345", "sonar-way-xoo2-12345")
+ .doesNotContain("sonar-way-xoo1-45678");
- assertJson(result).isSimilarTo(getClass().getResource("SearchActionTest/search_xoo1.json"));
}
private void commit() {
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json b/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json
deleted file mode 100644
index 143625c201f..00000000000
--- a/server/sonar-server/src/test/resources/org/sonar/server/qualityprofile/ws/SearchActionTest/search_fields.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
- "profiles": [
- {
- "key": "sonar-way-xoo1-12345",
- "language": "xoo1"
- },
- {
- "key": "my-sonar-way-xoo2-34567",
- "language": "xoo2"
- },
- {
- "key": "sonar-way-xoo2-23456",
- "language": "xoo2"
- }
- ]
-} \ No newline at end of file
diff --git a/sonar-db/src/test/java/org/sonar/db/DbTester.java b/sonar-db/src/test/java/org/sonar/db/DbTester.java
index 5ed9728972c..86545936b9b 100644
--- a/sonar-db/src/test/java/org/sonar/db/DbTester.java
+++ b/sonar-db/src/test/java/org/sonar/db/DbTester.java
@@ -109,6 +109,10 @@ public class DbTester extends ExternalResource {
return session;
}
+ public void commit() {
+ getSession().commit();
+ }
+
public void truncateTables() {
db.truncateTables();
}
diff --git a/sonar-db/src/test/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java b/sonar-db/src/test/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java
new file mode 100644
index 00000000000..963814f7b10
--- /dev/null
+++ b/sonar-db/src/test/java/org/sonar/db/qualityprofile/QualityProfileDbTester.java
@@ -0,0 +1,48 @@
+/*
+ * 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.db.qualityprofile;
+
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+
+public class QualityProfileDbTester {
+ private final DbClient dbClient;
+ private final DbSession dbSession;
+
+ public QualityProfileDbTester(DbTester db) {
+ this.dbClient = db.getDbClient();
+ this.dbSession = db.getSession();
+ }
+
+ public void insertQualityProfiles(QualityProfileDto qualityProfile, QualityProfileDto... qualityProfiles) {
+ dbClient.qualityProfileDao().insert(dbSession, qualityProfile, qualityProfiles);
+ }
+
+ public void insertProjectWithQualityProfileAssociations(ComponentDto project, QualityProfileDto... qualityProfiles) {
+ dbClient.componentDao().insert(dbSession, project);
+ for (QualityProfileDto qualityProfile : qualityProfiles) {
+ dbClient.qualityProfileDao().insertProjectProfileAssociation(project.uuid(), qualityProfile.getKey(), dbSession);
+ }
+ }
+
+}