001 /*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2014 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 3 of the License, or (at your option) any later version.
010 *
011 * SonarQube is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * You should have received a copy of the GNU Lesser General Public License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
019 */
020 package org.sonar.api.resources;
021
022 import com.google.common.base.Preconditions;
023 import com.google.common.base.Strings;
024 import com.google.common.collect.Maps;
025
026 import javax.annotation.Nullable;
027 import javax.annotation.concurrent.Immutable;
028
029 import java.util.Map;
030
031 /**
032 * <p>Experimental extension to declare types of resources.</p>
033 * <p>
034 * Since 3.0, ResourceType object can declare properties that give information about the capabilities of the
035 * resource type. Those properties may be used, of instance, to adapt the Web UI according to the type of
036 * the resource being displayed.
037 * <br>
038 * Currently, the following properties can be defined:
039 * </p>
040 * <ul>
041 * <li>"deletable": if set to "true", then this resource can be deleted/purged.</li>
042 * <li>"supportsMeasureFilters": if set to "true", then this resource can be displayed in measure filters</li>
043 * <li>"modifiable_history": if set to "true", then the history of this resource may be modified (deletion of snapshots, modification of events, ...)</li>
044 * <li>"updatable_key" (since 3.2): if set to "true", then it is possible to update the key of this resource</li>
045 * <li>"supportsGlobalDashboards" (since 3.2): if true, this resource can be displayed in global dashboards</li>
046 * <li>"hasRolePolicy" : if true, roles configuration is available in sidebar</li>
047 * <li>"comparable" (since 3.4) : if true, the resource can be compared to other resources</li>
048 * <li>"configurable" (since 3.6) : if true, the settings page can be displayed on the resource</li>
049 * </ul>
050 *
051 * @since 2.14
052 */
053 @Immutable
054 public class ResourceType {
055
056 /**
057 * Builder used to create {@link ResourceType} objects.
058 */
059 public static class Builder {
060 private static final String SUPPORTS_MEASURE_FILTERS = "supportsMeasureFilters";
061 private String qualifier;
062 private String iconPath;
063 private boolean hasSourceCode = false;
064 private final Map<String, String> properties = Maps.newHashMap();
065
066 /**
067 * Creates a new {@link Builder}
068 *
069 * @param qualifier
070 */
071 public Builder(String qualifier) {
072 this.qualifier = qualifier;
073 }
074
075 /**
076 * Relative path of the icon used to represent the resource type.
077 *
078 * @param iconPath path to icon, relative to context of web-application (e.g. "/images/q/DIR.png")
079 */
080 public Builder setIconPath(@Nullable String iconPath) {
081 this.iconPath = iconPath;
082 return this;
083 }
084
085 /**
086 * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "supportsMeasureFilters" set to "true".
087 */
088 @Deprecated
089 public Builder availableForFilters() {
090 setProperty(SUPPORTS_MEASURE_FILTERS, "true");
091 return this;
092 }
093
094 /**
095 * Tells that the resources of this type will have source code.
096 */
097 public Builder hasSourceCode() {
098 this.hasSourceCode = true;
099 return this;
100 }
101
102 /**
103 * Sets a property on the resource type. See the description of {@link ResourceType} class for more information.
104 *
105 * @since 3.0
106 */
107 public Builder setProperty(String key, String value) {
108 Preconditions.checkNotNull(key);
109 Preconditions.checkNotNull(value);
110 properties.put(key, value);
111
112 // for backward-compatibility since version 3.4
113 if ("availableForFilters".equals(key)) {
114 properties.put(SUPPORTS_MEASURE_FILTERS, value);
115 }
116 return this;
117 }
118
119 /**
120 * @since 3.2
121 */
122 public Builder setProperty(String key, boolean value) {
123 return setProperty(key, String.valueOf(value));
124 }
125
126 /**
127 * Creates an instance of {@link ResourceType} based on all information given to the builder.
128 */
129 public ResourceType build() {
130 if (Strings.isNullOrEmpty(iconPath)) {
131 iconPath = "/images/q/" + qualifier + ".png";
132 }
133 return new ResourceType(this);
134 }
135 }
136
137 /**
138 * Creates a new {@link Builder}
139 *
140 * @param qualifier
141 */
142 public static Builder builder(String qualifier) {
143 Preconditions.checkNotNull(qualifier);
144 Preconditions.checkArgument(qualifier.length() <= 10, "Qualifier is limited to 10 characters");
145 return new Builder(qualifier);
146 }
147
148 private final String qualifier;
149 private final String iconPath;
150 private final boolean hasSourceCode;
151 private Map<String, String> properties;
152
153 private ResourceType(Builder builder) {
154 this.qualifier = builder.qualifier;
155 this.iconPath = builder.iconPath;
156 this.hasSourceCode = builder.hasSourceCode;
157 this.properties = Maps.newHashMap(builder.properties);
158 }
159
160 /**
161 * Qualifier is the unique key.
162 *
163 * @return the qualifier
164 */
165 public String getQualifier() {
166 return qualifier;
167 }
168
169 /**
170 * Returns the relative path of the icon used to represent the resource type
171 *
172 * @return the relative path.
173 */
174 public String getIconPath() {
175 return iconPath;
176 }
177
178 /**
179 * Tells whether resources of this type has source code or not.
180 *
181 * @return true if the type has source code
182 */
183 public boolean hasSourceCode() {
184 return hasSourceCode;
185 }
186
187 public boolean hasProperty(String key) {
188 Preconditions.checkNotNull(key);
189 return properties.containsKey(key);
190 }
191
192 /**
193 * Returns the value of the property for this resource type.
194 *
195 * @return the String value of the property, or NULL if the property hasn't been set.
196 * @since 3.0
197 */
198 public String getStringProperty(String key) {
199 Preconditions.checkNotNull(key);
200 return properties.get(key);
201 }
202
203 /**
204 * Returns the value of the property for this resource type.
205 *
206 * @return the Boolean value of the property. If the property hasn't been set, False is returned.
207 * @since 3.0
208 */
209 public boolean getBooleanProperty(String key) {
210 Preconditions.checkNotNull(key);
211 String value = properties.get(key);
212 return value != null && Boolean.parseBoolean(value);
213 }
214
215 @Override
216 public boolean equals(Object o) {
217 if (this == o) {
218 return true;
219 }
220 if (o == null || getClass() != o.getClass()) {
221 return false;
222 }
223
224 ResourceType that = (ResourceType) o;
225 return qualifier.equals(that.qualifier);
226 }
227
228 @Override
229 public int hashCode() {
230 return qualifier.hashCode();
231 }
232
233 @Override
234 public String toString() {
235 return qualifier;
236 }
237 }