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