001 /* 002 * Sonar, open source software quality management tool. 003 * Copyright (C) 2009 SonarSource SA 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 */ 020 package org.sonar.api.profiles; 021 022 import org.apache.commons.collections.CollectionUtils; 023 import org.apache.commons.collections.Transformer; 024 import org.apache.commons.lang.StringUtils; 025 import org.apache.commons.lang.builder.EqualsBuilder; 026 import org.apache.commons.lang.builder.HashCodeBuilder; 027 import org.sonar.api.database.model.ResourceModel; 028 import org.sonar.api.rules.ActiveRule; 029 import org.sonar.api.rules.Rule; 030 import org.sonar.api.rules.RulePriority; 031 032 import javax.persistence.*; 033 import java.util.ArrayList; 034 import java.util.List; 035 036 /** 037 * This class is badly named. It should be "QualityProfile". Indeed it does not relate only to rules but to metric 038 * thresholds too. 039 */ 040 @Entity 041 @Table(name = "rules_profiles") 042 public class RulesProfile implements Cloneable { 043 044 /** 045 * Name of the default profile "Sonar Way" 046 */ 047 public static final String SONAR_WAY_NAME = "Sonar way"; 048 049 /** 050 * Name of the default java profile "Sonar way with Findbugs" 051 */ 052 public static final String SONAR_WAY_FINDBUGS_NAME = "Sonar way with Findbugs"; 053 054 /** 055 * Name of the default java profile "Sun checks" 056 */ 057 public static final String SUN_CONVENTIONS_NAME = "Sun checks"; 058 059 @Id 060 @Column(name = "id") 061 @GeneratedValue 062 private Integer id; 063 064 @Column(name = "name", updatable = true, nullable = false) 065 private String name; 066 067 @Column(name = "default_profile", updatable = true, nullable = false) 068 private Boolean defaultProfile = Boolean.FALSE; 069 070 @Column(name = "provided", updatable = true, nullable = false) 071 private Boolean provided = Boolean.FALSE; 072 073 @Column(name = "language", updatable = true, nullable = false) 074 private String language; 075 076 @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) 077 private List<ActiveRule> activeRules = new ArrayList<ActiveRule>(); 078 079 @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}) 080 private List<Alert> alerts = new ArrayList<Alert>(); 081 082 @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY) 083 private List<ResourceModel> projects = new ArrayList<ResourceModel>(); 084 085 /** 086 * @deprecated use the factory method create() 087 */ 088 @Deprecated 089 public RulesProfile() { 090 } 091 092 /** 093 * @deprecated since 2.3. Use the factory method create() 094 */ 095 @Deprecated 096 public RulesProfile(String name, String language) { 097 this.name = name; 098 this.language = language; 099 this.activeRules = new ArrayList<ActiveRule>(); 100 this.alerts = new ArrayList<Alert>(); 101 this.projects = new ArrayList<ResourceModel>(); 102 } 103 104 /** 105 * @deprecated since 2.3. Use the factory method create() 106 */ 107 @Deprecated 108 public RulesProfile(String name, String language, boolean defaultProfile, boolean provided) { 109 this(name, language); 110 this.defaultProfile = defaultProfile; 111 this.provided = provided; 112 } 113 114 public Integer getId() { 115 return id; 116 } 117 118 /** 119 * @return the profile name, unique by language. 120 */ 121 public String getName() { 122 return name; 123 } 124 125 /** 126 * Set the profile name. 127 */ 128 public RulesProfile setName(String s) { 129 this.name = s; 130 return this; 131 } 132 133 /** 134 * @return the list of active rules 135 */ 136 public List<ActiveRule> getActiveRules() { 137 return activeRules; 138 } 139 140 /** 141 * Set the list of active rules 142 */ 143 public void setActiveRules(List<ActiveRule> activeRules) { 144 this.activeRules = activeRules; 145 } 146 147 /** 148 * @return whether this is the default profile for the language 149 */ 150 public Boolean getDefaultProfile() { 151 return defaultProfile; 152 } 153 154 /** 155 * Set whether this is the default profile for the language. The default profile is used when none is explicitly 156 * defined when auditing a project. 157 */ 158 public void setDefaultProfile(Boolean b) { 159 this.defaultProfile = b; 160 } 161 162 /** 163 * @return whether the profile is defined in a plugin. Provided profiles are automatically restored during 164 * server startup and can not be updated by end users. 165 */ 166 public Boolean getProvided() { 167 return provided; 168 } 169 170 /** 171 * Set whether the profile is provided by a plugin 172 */ 173 public void setProvided(Boolean b) { 174 this.provided = b; 175 } 176 177 /** 178 * @return the profile language 179 */ 180 public String getLanguage() { 181 return language; 182 } 183 184 /** 185 * Set the profile language 186 */ 187 public RulesProfile setLanguage(String s) { 188 this.language = s; 189 return this; 190 } 191 192 /** 193 * @return the list of alerts defined in the profile 194 */ 195 public List<Alert> getAlerts() { 196 return alerts; 197 } 198 199 /** 200 * Sets the list of alerts for the profile 201 */ 202 public void setAlerts(List<Alert> alerts) { 203 this.alerts = alerts; 204 } 205 206 /** 207 * @return the list of projects attached to the profile 208 */ 209 public List<ResourceModel> getProjects() { 210 return projects; 211 } 212 213 /** 214 * Sets the list of projects attached to the profile 215 */ 216 public void setProjects(List<ResourceModel> projects) { 217 this.projects = projects; 218 } 219 220 /** 221 * @return the list of active rules for a given priority 222 */ 223 public List<ActiveRule> getActiveRules(RulePriority priority) { 224 List<ActiveRule> result = new ArrayList<ActiveRule>(); 225 for (ActiveRule activeRule : getActiveRules()) { 226 if (activeRule.getPriority().equals(priority)) { 227 result.add(activeRule); 228 } 229 } 230 return result; 231 } 232 233 /** 234 * @deprecated since 2.3. Use getActiveRulesByRepository(). 235 */ 236 @Deprecated 237 public List<ActiveRule> getActiveRulesByPlugin(String repositoryKey) { 238 return getActiveRulesByRepository(repositoryKey); 239 } 240 241 public List<ActiveRule> getActiveRulesByRepository(String repositoryKey) { 242 List<ActiveRule> result = new ArrayList<ActiveRule>(); 243 for (ActiveRule activeRule : getActiveRules()) { 244 if (repositoryKey.equals(activeRule.getPluginName())) { 245 result.add(activeRule); 246 } 247 } 248 return result; 249 } 250 251 /** 252 * @return an active rule from a plugin key and a rule key if the rule is activated, null otherwise 253 */ 254 public ActiveRule getActiveRule(String repositoryKey, String ruleKey) { 255 for (ActiveRule activeRule : getActiveRules()) { 256 if (StringUtils.equals(activeRule.getRepositoryKey(), repositoryKey) && StringUtils.equals(activeRule.getRuleKey(), ruleKey)) { 257 return activeRule; 258 } 259 } 260 return null; 261 } 262 263 public ActiveRule getActiveRuleByConfigKey(String repositoryKey, String configKey) { 264 for (ActiveRule activeRule : getActiveRules()) { 265 if (StringUtils.equals(activeRule.getRepositoryKey(), repositoryKey) && StringUtils.equals(activeRule.getConfigKey(), configKey)) { 266 return activeRule; 267 } 268 } 269 return null; 270 } 271 272 public ActiveRule getActiveRule(Rule rule) { 273 return getActiveRule(rule.getRepositoryKey(), rule.getKey()); 274 } 275 276 /** 277 * 278 * @param rule 279 * @param optionalPriority if null, then the default rule priority is used 280 * @return 281 */ 282 public ActiveRule activateRule(Rule rule, RulePriority optionalPriority) { 283 ActiveRule activeRule = new ActiveRule(); 284 activeRule.setRule(rule); 285 activeRule.setRulesProfile(this); 286 activeRule.setPriority(optionalPriority==null ? rule.getPriority() : optionalPriority); 287 activeRules.add(activeRule); 288 return activeRule; 289 } 290 291 @Override 292 public boolean equals(Object obj) { 293 if (!(obj instanceof RulesProfile)) { 294 return false; 295 } 296 if (this == obj) { 297 return true; 298 } 299 RulesProfile other = (RulesProfile) obj; 300 return new EqualsBuilder().append(language, other.getLanguage()).append(name, other.getName()).isEquals(); 301 } 302 303 @Override 304 public int hashCode() { 305 return new HashCodeBuilder(17, 37).append(language).append(name).toHashCode(); 306 } 307 308 @Override 309 public Object clone() { 310 RulesProfile clone = RulesProfile.create(getName(), getLanguage()); 311 clone.setDefaultProfile(getDefaultProfile()); 312 clone.setProvided(getProvided()); 313 if (CollectionUtils.isNotEmpty(getActiveRules())) { 314 clone.setActiveRules(new ArrayList<ActiveRule>(CollectionUtils.collect(getActiveRules(), new Transformer() { 315 public Object transform(Object input) { 316 return ((ActiveRule) input).clone(); 317 } 318 }))); 319 } 320 if (CollectionUtils.isNotEmpty(getAlerts())) { 321 clone.setAlerts(new ArrayList<Alert>(CollectionUtils.collect(getAlerts(), new Transformer() { 322 public Object transform(Object input) { 323 return ((Alert) input).clone(); 324 } 325 }))); 326 } 327 if (CollectionUtils.isNotEmpty(getProjects())) { 328 clone.setProjects(new ArrayList<ResourceModel>(CollectionUtils.collect(getProjects(), new Transformer() { 329 public Object transform(Object input) { 330 return ((ResourceModel) input).clone(); 331 } 332 }))); 333 } 334 return clone; 335 } 336 337 @Override 338 public String toString() { 339 return new StringBuilder().append("[name=").append(name).append(",language=").append(language).append("]").toString(); 340 } 341 342 public static RulesProfile create(String name, String language) { 343 return new RulesProfile().setName(name).setLanguage(language); 344 } 345 346 public static RulesProfile create() { 347 return new RulesProfile(); 348 } 349 }