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