001/* 002 * SonarQube 003 * Copyright (C) 2009-2016 SonarSource SA 004 * mailto:contact AT sonarsource DOT com 005 * 006 * This program 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 * This program 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 */ 020package org.sonar.api.resources; 021 022import com.google.common.base.Preconditions; 023import com.google.common.base.Strings; 024import com.google.common.collect.Maps; 025 026import javax.annotation.Nullable; 027import javax.annotation.concurrent.Immutable; 028 029import java.util.Map; 030 031/** 032 * <p>Experimental extension to declare types of resources. 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 * 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 054public 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}