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 */ 020 package org.sonar.api.rules; 021 022 import org.apache.commons.lang.StringUtils; 023 import org.apache.commons.lang.builder.EqualsBuilder; 024 import org.apache.commons.lang.builder.HashCodeBuilder; 025 import org.apache.commons.lang.builder.ToStringBuilder; 026 import org.apache.commons.lang.builder.ToStringStyle; 027 import org.sonar.api.database.DatabaseProperties; 028 import org.sonar.check.Cardinality; 029 030 import javax.persistence.*; 031 032 import java.util.ArrayList; 033 import java.util.List; 034 035 @Entity 036 @Table(name = "rules") 037 public final class Rule { 038 039 private static final RulesCategory NONE = new RulesCategory("none"); 040 041 @Id 042 @Column(name = "id") 043 @GeneratedValue 044 private Integer id; 045 046 /** 047 * The default priority given to a rule if not explicitly set 048 */ 049 public static final RulePriority DEFAULT_PRIORITY = RulePriority.MAJOR; 050 051 @Column(name = "name", updatable = true, nullable = true, length = 200) 052 private String name; 053 054 @Column(name = "plugin_rule_key", updatable = false, nullable = true, length = 200) 055 private String key; 056 057 @Column(name = "enabled", updatable = true, nullable = true) 058 private Boolean enabled = Boolean.TRUE; 059 060 @Column(name = "plugin_config_key", updatable = true, nullable = true, length = 500) 061 private String configKey; 062 063 // Godin: This field should be named priority, otherwise StandardRulesXmlParserTest fails 064 @Column(name = "priority", updatable = true, nullable = true) 065 @Enumerated(EnumType.ORDINAL) 066 private RulePriority priority = DEFAULT_PRIORITY; 067 068 @Column(name = "description", updatable = true, nullable = true, length = DatabaseProperties.MAX_TEXT_SIZE) 069 private String description; 070 071 @Column(name = "plugin_name", updatable = true, nullable = false) 072 private String pluginName; 073 074 @Enumerated(EnumType.STRING) 075 @Column(name = "cardinality", updatable = true, nullable = false) 076 private Cardinality cardinality = Cardinality.SINGLE; 077 078 @ManyToOne(fetch = FetchType.EAGER) 079 @JoinColumn(name = "parent_id", updatable = true, nullable = true) 080 private Rule parent = null; 081 082 @org.hibernate.annotations.Cascade({org.hibernate.annotations.CascadeType.ALL, org.hibernate.annotations.CascadeType.DELETE_ORPHAN}) 083 @OneToMany(mappedBy = "rule") 084 private List<RuleParam> params = new ArrayList<RuleParam>(); 085 086 /** 087 * @deprecated since 2.3. Use the factory method {@link #create()} 088 */ 089 @Deprecated 090 public Rule() { 091 // TODO reduce visibility to package 092 } 093 094 /** 095 * Creates rule with minimum set of info 096 * 097 * @param pluginName the plugin name indicates which plugin the rule belongs to 098 * @param key the key should be unique within a plugin, but it is even more careful for the time being that it is unique across the 099 * application 100 * @deprecated since 2.3. Use the factory method {@link #create()} 101 */ 102 @Deprecated 103 public Rule(String pluginName, String key) { 104 this.pluginName = pluginName; 105 this.key = key; 106 this.configKey = key; 107 } 108 109 /** 110 * Creates a fully qualified rule 111 * 112 * @param pluginKey the plugin the rule belongs to 113 * @param key the key should be unique within a plugin, but it is even more careful for the time being that it is unique across the 114 * application 115 * @param name the name displayed in the UI 116 * @param rulesCategory the ISO category the rule belongs to 117 * @param severity this is the severity associated to the rule 118 * @deprecated since 2.3. Use the factory method {@link #create()} 119 */ 120 @Deprecated 121 public Rule(String pluginKey, String key, String name, RulesCategory rulesCategory, RulePriority severity) { 122 setName(name); 123 this.key = key; 124 this.configKey = key; 125 this.priority = severity; 126 this.pluginName = pluginKey; 127 } 128 129 /** 130 * @deprecated since 2.3. Use the factory method {@link #create()} 131 */ 132 @Deprecated 133 public Rule(String name, String key, RulesCategory rulesCategory, String pluginName, String description) { 134 this(); 135 setName(name); 136 this.key = key; 137 this.configKey = key; 138 this.pluginName = pluginName; 139 this.description = description; 140 } 141 142 /** 143 * @deprecated since 2.3. Use the factory method {@link #create()} 144 */ 145 @Deprecated 146 public Rule(String name, String key, String configKey, RulesCategory rulesCategory, String pluginName, String description) { 147 this(); 148 setName(name); 149 this.key = key; 150 this.configKey = configKey; 151 this.pluginName = pluginName; 152 this.description = description; 153 } 154 155 public Integer getId() { 156 return id; 157 } 158 159 /** 160 * @deprecated since 2.3. visibility should be decreased to protected or package 161 */ 162 @Deprecated 163 public void setId(Integer id) { 164 this.id = id; 165 } 166 167 public String getName() { 168 return name; 169 } 170 171 /** 172 * Sets the rule name 173 */ 174 public Rule setName(String name) { 175 this.name = removeNewLineCharacters(name); 176 return this; 177 } 178 179 public String getKey() { 180 return key; 181 } 182 183 /** 184 * Sets the rule key 185 */ 186 public Rule setKey(String key) { 187 this.key = key; 188 return this; 189 } 190 191 /** 192 * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007 193 */ 194 @Deprecated 195 public RulesCategory getRulesCategory() { 196 return NONE; 197 } 198 199 /** 200 * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007 201 */ 202 @Deprecated 203 public Rule setRulesCategory(RulesCategory rulesCategory) { 204 return this; 205 } 206 207 /** 208 * @deprecated since 2.5 use {@link #getRepositoryKey()} instead 209 */ 210 @Deprecated 211 public String getPluginName() { 212 return pluginName; 213 } 214 215 /** 216 * @deprecated since 2.5 use {@link #setRepositoryKey(String)} instead 217 */ 218 @Deprecated 219 public Rule setPluginName(String pluginName) { 220 this.pluginName = pluginName; 221 return this; 222 } 223 224 public String getConfigKey() { 225 return configKey; 226 } 227 228 /** 229 * Sets the configuration key 230 */ 231 public Rule setConfigKey(String configKey) { 232 this.configKey = configKey; 233 return this; 234 } 235 236 public String getDescription() { 237 return description; 238 } 239 240 /** 241 * Sets the rule description 242 */ 243 public Rule setDescription(String description) { 244 this.description = StringUtils.strip(description); 245 return this; 246 } 247 248 public Boolean isEnabled() { 249 return enabled; 250 } 251 252 /** 253 * Do not call. Used only by sonar. 254 */ 255 public Rule setEnabled(Boolean b) { 256 this.enabled = b; 257 return this; 258 } 259 260 public List<RuleParam> getParams() { 261 return params; 262 } 263 264 public RuleParam getParam(String key) { 265 for (RuleParam param : params) { 266 if (StringUtils.equals(key, param.getKey())) { 267 return param; 268 } 269 } 270 return null; 271 } 272 273 /** 274 * Sets the rule parameters 275 */ 276 public Rule setParams(List<RuleParam> params) { 277 this.params.clear(); 278 for (RuleParam param : params) { 279 param.setRule(this); 280 this.params.add(param); 281 } 282 return this; 283 } 284 285 public RuleParam createParameter() { 286 RuleParam parameter = new RuleParam() 287 .setRule(this); 288 params.add(parameter); 289 return parameter; 290 } 291 292 public RuleParam createParameter(String key) { 293 RuleParam parameter = new RuleParam() 294 .setKey(key) 295 .setRule(this); 296 params.add(parameter); 297 return parameter; 298 } 299 300 /** 301 * @deprecated since 2.5 See http://jira.codehaus.org/browse/SONAR-2007 302 */ 303 @Deprecated 304 public Integer getCategoryId() { 305 return null; 306 } 307 308 /** 309 * @since 2.5 310 */ 311 public RulePriority getSeverity() { 312 return priority; 313 } 314 315 /** 316 * @param severity severity to set, if null, uses the default priority. 317 * @since 2.5 318 */ 319 public Rule setSeverity(RulePriority severity) { 320 if (severity == null) { 321 this.priority = DEFAULT_PRIORITY; 322 } else { 323 this.priority = severity; 324 } 325 return this; 326 } 327 328 /** 329 * @deprecated since 2.5 use {@link #getSeverity()} instead. See http://jira.codehaus.org/browse/SONAR-1829 330 */ 331 @Deprecated 332 public RulePriority getPriority() { 333 return priority; 334 } 335 336 /** 337 * Sets the rule priority. If null, uses the default priority 338 * 339 * @deprecated since 2.5 use {@link #setSeverity(RulePriority)} instead. See http://jira.codehaus.org/browse/SONAR-1829 340 */ 341 @Deprecated 342 public Rule setPriority(RulePriority priority) { 343 return setSeverity(priority); 344 } 345 346 public String getRepositoryKey() { 347 return pluginName; 348 } 349 350 public Rule setRepositoryKey(String s) { 351 this.pluginName = s; 352 return this; 353 } 354 355 public Rule setUniqueKey(String repositoryKey, String key) { 356 return setRepositoryKey(repositoryKey).setKey(key).setConfigKey(key); 357 } 358 359 public Cardinality getCardinality() { 360 return cardinality; 361 } 362 363 public Rule setCardinality(Cardinality c) { 364 this.cardinality = c; 365 return this; 366 } 367 368 public Rule getParent() { 369 return parent; 370 } 371 372 public Rule setParent(Rule parent) { 373 this.parent = parent; 374 return this; 375 } 376 377 @Override 378 public boolean equals(Object obj) { 379 if (!(obj instanceof Rule)) { 380 return false; 381 } 382 if (this == obj) { 383 return true; 384 } 385 Rule other = (Rule) obj; 386 return new EqualsBuilder() 387 .append(pluginName, other.getRepositoryKey()) 388 .append(key, other.getKey()) 389 .isEquals(); 390 } 391 392 @Override 393 public int hashCode() { 394 return new HashCodeBuilder(17, 37) 395 .append(pluginName) 396 .append(key) 397 .toHashCode(); 398 } 399 400 @Override 401 public String toString() { 402 // Note that ReflectionToStringBuilder will not work here - see SONAR-3077 403 return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE) 404 .append("id", id) 405 .append("name", name) 406 .append("key", key) 407 .append("configKey", configKey) 408 .append("plugin", pluginName) 409 .append("enabled", enabled) 410 .append("severity", priority) 411 .append("cardinality", cardinality) 412 .toString(); 413 } 414 415 private String removeNewLineCharacters(String text) { 416 String removedCRLF = StringUtils.remove(text, "\n"); 417 removedCRLF = StringUtils.remove(removedCRLF, "\r"); 418 removedCRLF = StringUtils.remove(removedCRLF, "\n\r"); 419 removedCRLF = StringUtils.remove(removedCRLF, "\r\n"); 420 return removedCRLF; 421 } 422 423 public static Rule create() { 424 return new Rule(); 425 } 426 427 /** 428 * Create with all required fields 429 */ 430 public static Rule create(String repositoryKey, String key, String name) { 431 return new Rule().setUniqueKey(repositoryKey, key).setName(name); 432 } 433 434 /** 435 * Create with all required fields 436 * 437 * @since 2.10 438 */ 439 public static Rule create(String repositoryKey, String key) { 440 return new Rule().setUniqueKey(repositoryKey, key); 441 } 442 }