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