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