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