001/* 002 * SonarQube 003 * Copyright (C) 2009-2018 SonarSource SA 004 * mailto:info 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 java.util.HashMap; 024import java.util.Map; 025import javax.annotation.Nullable; 026import javax.annotation.concurrent.Immutable; 027 028import static java.util.Objects.requireNonNull; 029import static org.apache.commons.lang.StringUtils.isEmpty; 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 = new HashMap<>(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 requireNonNull(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 requireNonNull(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 requireNonNull(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 requireNonNull(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 String qualifier; 160 private String iconPath; 161 private boolean hasSourceCode = false; 162 private final Map<String, String> properties = new HashMap<>(); 163 164 /** 165 * Creates a new {@link Builder} 166 */ 167 public Builder(String qualifier) { 168 this.qualifier = qualifier; 169 } 170 171 /** 172 * Relative path of the icon used to represent the resource type. 173 * 174 * @param iconPath path to icon, relative to context of web-application (e.g. "/images/q/DIR.png") 175 */ 176 public Builder setIconPath(@Nullable String iconPath) { 177 this.iconPath = iconPath; 178 return this; 179 } 180 181 /** 182 * @deprecated since 3.0. Use {@link #setProperty(String, String)} with "supportsMeasureFilters" set to "true". 183 */ 184 @Deprecated 185 public Builder availableForFilters() { 186 return this; 187 } 188 189 /** 190 * Tells that the resources of this type will have source code. 191 */ 192 public Builder hasSourceCode() { 193 this.hasSourceCode = true; 194 return this; 195 } 196 197 /** 198 * Sets a property on the resource type. See the description of {@link ResourceType} class for more information. 199 * 200 * @since 3.0 201 */ 202 public Builder setProperty(String key, String value) { 203 requireNonNull(key); 204 requireNonNull(value); 205 properties.put(key, value); 206 return this; 207 } 208 209 /** 210 * @since 3.2 211 */ 212 public Builder setProperty(String key, boolean value) { 213 return setProperty(key, String.valueOf(value)); 214 } 215 216 /** 217 * Creates an instance of {@link ResourceType} based on all information given to the builder. 218 */ 219 public ResourceType build() { 220 if (isEmpty(iconPath)) { 221 iconPath = "/images/q/" + qualifier + ".png"; 222 } 223 return new ResourceType(this); 224 } 225 } 226}