3 * Copyright (C) 2009-2019 SonarSource SA
4 * mailto:info AT sonarsource DOT com
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 3 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 package org.sonar.server.qualityprofile.ws;
22 import java.util.Arrays;
23 import java.util.Optional;
24 import javax.annotation.Nullable;
25 import org.sonar.api.resources.Language;
26 import org.sonar.api.resources.Languages;
27 import org.sonar.api.server.ws.Request;
28 import org.sonar.api.server.ws.WebService;
29 import org.sonar.core.util.stream.MoreCollectors;
31 import static com.google.common.base.Preconditions.checkArgument;
32 import static com.google.common.base.Preconditions.checkState;
33 import static java.util.Objects.requireNonNull;
34 import static org.apache.commons.lang.StringUtils.isEmpty;
35 import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
36 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
37 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_KEY;
38 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_LANGUAGE;
39 import static org.sonarqube.ws.client.qualityprofile.QualityProfileWsParameters.PARAM_QUALITY_PROFILE;
42 * Reference to a Quality profile as defined by requests to web services api/qualityprofiles.
43 * The two exclusive options to reference a profile are:
45 * <li>by its id (to be deprecated)</li>
46 * <li>by the tuple {organizationKey, language, name}</li>
49 public class QProfileReference {
55 private final Type type;
56 private final String key;
57 private final String organizationKey;
58 private final String language;
59 private final String name;
61 private QProfileReference(Type type, @Nullable String key, @Nullable String organizationKey, @Nullable String language, @Nullable String name) {
63 if (type == Type.KEY) {
64 this.key = requireNonNull(key);
65 this.organizationKey = null;
70 this.organizationKey = organizationKey;
71 this.language = requireNonNull(language);
72 this.name = requireNonNull(name);
77 * @return {@code true} if key is defined and {@link #getKey()} can be called. If {@code false}, then
78 * the couple {language, name} is defined and the methods {@link #getLanguage()}/{@link #getName()}
81 public boolean hasKey() {
82 return type == Type.KEY;
86 * @return non-null key
87 * @throws IllegalStateException if {@link #hasKey()} does not return {@code true}
89 public String getKey() {
90 checkState(key != null, "Key is not defined. Please call hasKey().");
95 * @return key of organization. It is empty when {@link #hasKey()} is {@code true} or if {@link #hasKey()} is
96 * {@code false} and the default organization must be used.
98 public Optional<String> getOrganizationKey() {
99 checkState(type == Type.NAME, "Organization is not defined. Please call hasKey().");
100 return Optional.ofNullable(organizationKey);
104 * @return non-null language
105 * @throws IllegalStateException if {@link #hasKey()} does not return {@code false}
107 public String getLanguage() {
108 checkState(type == Type.NAME, "Language is not defined. Please call hasKey().");
113 * @return non-null name
114 * @throws IllegalStateException if {@link #hasKey()} does not return {@code false}
116 public String getName() {
117 checkState(type == Type.NAME, "Name is not defined. Please call hasKey().");
122 public boolean equals(Object o) {
126 if (o == null || getClass() != o.getClass()) {
129 QProfileReference that = (QProfileReference) o;
130 if (key != null ? !key.equals(that.key) : (that.key != null)) {
133 if (organizationKey != null ? !organizationKey.equals(that.organizationKey) : (that.organizationKey != null)) {
136 if (language != null ? !language.equals(that.language) : (that.language != null)) {
139 return name != null ? name.equals(that.name) : (that.name == null);
144 public int hashCode() {
145 int result = key != null ? key.hashCode() : 0;
146 result = 31 * result + (organizationKey != null ? organizationKey.hashCode() : 0);
147 result = 31 * result + (language != null ? language.hashCode() : 0);
148 result = 31 * result + (name != null ? name.hashCode() : 0);
152 public static QProfileReference from(Request request) {
153 String key = request.param(PARAM_KEY);
154 String organizationKey = request.param(PARAM_ORGANIZATION);
155 String lang = request.param(PARAM_LANGUAGE);
156 String name = request.param(PARAM_QUALITY_PROFILE);
157 return from(key, organizationKey, lang, name);
160 public static QProfileReference from(@Nullable String key, @Nullable String organizationKey, @Nullable String lang, @Nullable String name) {
162 checkArgument(isEmpty(organizationKey) && isEmpty(lang) && isEmpty(name),
163 "When a quality profile key is set, '%s' '%s' and '%s' can't be set", PARAM_ORGANIZATION, PARAM_LANGUAGE, PARAM_QUALITY_PROFILE);
166 checkArgument(!isEmpty(lang) && !isEmpty(name),
167 "If '%s' is not specified, '%s' and '%s' must be set", PARAM_KEY, PARAM_QUALITY_PROFILE, PARAM_LANGUAGE);
168 return fromName(organizationKey, lang, name);
171 public static QProfileReference fromKey(String key) {
172 return new QProfileReference(Type.KEY, key, null, null, null);
175 public static QProfileReference fromName(@Nullable String organizationKey, String lang, String name) {
176 return new QProfileReference(Type.NAME, null, organizationKey, requireNonNull(lang), requireNonNull(name));
179 public static void defineParams(WebService.NewAction action, Languages languages) {
180 action.createParam(PARAM_KEY)
181 .setDescription("Quality profile key. Mandatory unless 'qualityProfile' and 'language' are specified.")
182 .setDeprecatedKey("profileKey", "6.5")
183 .setDeprecatedSince("6.6")
184 .setExampleValue(UUID_EXAMPLE_01);
186 action.createParam(PARAM_QUALITY_PROFILE)
187 .setDescription("Quality profile name. Mandatory if 'key' is not set.")
188 .setDeprecatedKey("profileName", "6.6")
189 .setExampleValue("Sonar way");
191 action.createParam(PARAM_LANGUAGE)
192 .setDescription("Quality profile language. Mandatory if 'key' is not set.")
193 .setPossibleValues(Arrays.stream(languages.all()).map(Language::getKey).collect(MoreCollectors.toSet()));