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 private final String qualifier; 057 private final String iconPath; 058 private final boolean hasSourceCode; 059 private Map<String, String> properties; 060 061 private ResourceType(Builder builder) { 062 this.qualifier = builder.qualifier; 063 this.iconPath = builder.iconPath; 064 this.hasSourceCode = builder.hasSourceCode; 065 this.properties = Maps.newHashMap(builder.properties); 066 } 067 068 /** 069 * Qualifier is the unique key. 070 * 071 * @return the qualifier 072 */ 073 public String getQualifier() { 074 return qualifier; 075 } 076 077 /** 078 * Returns the relative path of the icon used to represent the resource type 079 * 080 * @return the relative path. 081 */ 082 public String getIconPath() { 083 return iconPath; 084 } 085 086 /** 087 * Tells whether resources of this type has source code or not. 088 * 089 * @return true if the type has source code 090 */ 091 public boolean hasSourceCode() { 092 return hasSourceCode; 093 } 094 095 public boolean hasProperty(String key) { 096 Preconditions.checkNotNull(key); 097 return properties.containsKey(key); 098 } 099 100 /** 101 * Returns the value of the property for this resource type. 102 * 103 * @return the String value of the property, or NULL if the property hasn't been set. 104 * @since 3.0 105 */ 106 public String getStringProperty(String key) { 107 Preconditions.checkNotNull(key); 108 return properties.get(key); 109 } 110 111 /** 112 * Returns the value of the property for this resource type. 113 * 114 * @return the Boolean value of the property. If the property hasn't been set, False is returned. 115 * @since 3.0 116 */ 117 public boolean getBooleanProperty(String key) { 118 Preconditions.checkNotNull(key); 119 String value = properties.get(key); 120 return value != null && Boolean.parseBoolean(value); 121 } 122 123 @Override 124 public boolean equals(Object o) { 125 if (this == o) { 126 return true; 127 } 128 if (o == null || getClass() != o.getClass()) { 129 return false; 130 } 131 132 ResourceType that = (ResourceType) o; 133 return qualifier.equals(that.qualifier); 134 } 135 136 @Override 137 public int hashCode() { 138 return qualifier.hashCode(); 139 } 140 141 @Override 142 public String toString() { 143 return qualifier; 144 } 145 146 /** 147 * Creates a new {@link Builder} 148 */ 149 public static Builder builder(String qualifier) { 150 Preconditions.checkNotNull(qualifier); 151 Preconditions.checkArgument(qualifier.length() <= 10, "Qualifier is limited to 10 characters"); 152 return new Builder(qualifier); 153 } 154 155 /** 156 * Builder used to create {@link ResourceType} objects. 157 */ 158 public static class Builder { 159 private static final String SUPPORTS_MEASURE_FILTERS = "supportsMeasureFilters"; 160 private String qualifier; 161 private String iconPath; 162 private boolean hasSourceCode = false; 163 private final Map<String, String> properties = Maps.newHashMap(); 164 165 /** 166 * Creates a new {@link Builder} 167 */ 168 public Builder(String qualifier) { 169 this.qualifier = qualifier; 170 } 171 172 /** 173 * Relative path of the icon used to represent the resource type. 174 * 175 * @param iconPath path to icon, relative to context of web-application (e.g. "/images/q/DIR.png") 176 */ 177 public Builder setIconPath(@Nullable String iconPath) { 178 this.iconPath = iconPath; 179 return this; 180 } 181 182 /** 183 * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "supportsMeasureFilters" set to "true". 184 */ 185 @Deprecated 186 public Builder availableForFilters() { 187 setProperty(SUPPORTS_MEASURE_FILTERS, "true"); 188 return this; 189 } 190 191 /** 192 * Tells that the resources of this type will have source code. 193 */ 194 public Builder hasSourceCode() { 195 this.hasSourceCode = true; 196 return this; 197 } 198 199 /** 200 * Sets a property on the resource type. See the description of {@link ResourceType} class for more information. 201 * 202 * @since 3.0 203 */ 204 public Builder setProperty(String key, String value) { 205 Preconditions.checkNotNull(key); 206 Preconditions.checkNotNull(value); 207 properties.put(key, value); 208 209 // for backward-compatibility since version 3.4 210 if ("availableForFilters".equals(key)) { 211 properties.put(SUPPORTS_MEASURE_FILTERS, value); 212 } 213 return this; 214 } 215 216 /** 217 * @since 3.2 218 */ 219 public Builder setProperty(String key, boolean value) { 220 return setProperty(key, String.valueOf(value)); 221 } 222 223 /** 224 * Creates an instance of {@link ResourceType} based on all information given to the builder. 225 */ 226 public ResourceType build() { 227 if (Strings.isNullOrEmpty(iconPath)) { 228 iconPath = "/images/q/" + qualifier + ".png"; 229 } 230 return new ResourceType(this); 231 } 232 } 233}