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.hibernate.annotations.Cache;
027    import org.hibernate.annotations.CacheConcurrencyStrategy;
028    import org.sonar.api.database.BaseIdentifiable;
029    import org.sonar.api.database.DatabaseProperties;
030    
031    import java.util.ArrayList;
032    import java.util.List;
033    import javax.persistence.*;
034    
035    /**
036     * A class to map rules with Hibernate model
037     */
038    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
039    @Entity
040    @Table(name = "rules")
041    public class Rule extends BaseIdentifiable {
042    
043      /**
044       * The default priority given to a rule if not explicitely set
045       */
046      public static final RulePriority DEFAULT_PRIORITY = RulePriority.MAJOR;
047    
048      @Column(name = "name", updatable = true, nullable = false)
049      private String name;
050    
051      @Column(name = "plugin_rule_key", updatable = false, nullable = true)
052      private String key;
053    
054      @Column(name = "plugin_config_key", updatable = true, nullable = true)
055      private String configKey;
056    
057      @ManyToOne(fetch = FetchType.EAGER)
058      @JoinColumn(name = "rules_category_id", updatable = true, nullable = true)
059      private RulesCategory rulesCategory;
060    
061      @Column(name = "priority", updatable = true, nullable = true)
062      @Enumerated(EnumType.ORDINAL)
063      private RulePriority priority = DEFAULT_PRIORITY;
064    
065      @Column(name = "description", updatable = true, nullable = true, length = DatabaseProperties.MAX_TEXT_SIZE)
066      private String description;
067    
068      @Column(name = "plugin_name", updatable = true, nullable = true)
069      private String pluginName;
070    
071      @OneToMany(mappedBy = "rule", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
072      private List<RuleParam> params = new ArrayList<RuleParam>();
073    
074      public Rule() {
075      }
076    
077      /**
078       * Creates rule with minimum set of info
079       *
080       * @param pluginName the plugin name indicates which plugin the rule belongs to
081       * @param key the key should be unique within a plugin, but it is even more careful for the time being that it is unique
082       * across the application
083       */
084      public Rule(String pluginName, String key) {
085        this.pluginName = pluginName;
086        this.key = key;
087        this.configKey = key;
088      }
089    
090      /**
091       * Creates a fully qualified rule
092       *
093       * @param pluginKey the plugin the rule belongs to
094       * @param key the key should be unique within a plugin, but it is even more careful for the time being that it is unique
095       * across the application
096       * @param name the name displayed in the UI
097       * @param rulesCategory the ISO category the rule belongs to
098       * @param priority this is the priority associated to the rule
099       */
100      public Rule(String pluginKey, String key, String name, RulesCategory rulesCategory, RulePriority priority) {
101        setName(name);
102        this.key = key;
103        this.configKey = key;
104        this.rulesCategory = rulesCategory;
105        this.priority = priority;
106        this.pluginName = pluginKey;
107      }
108    
109      @Deprecated
110      public Rule(String name, String key, RulesCategory rulesCategory, String pluginName, String description) {
111        this();
112        setName(name);
113        this.key = key;
114        this.configKey = key;
115        this.rulesCategory = rulesCategory;
116        this.pluginName = pluginName;
117        this.description = description;
118      }
119    
120      @Deprecated
121      public Rule(String name, String key, String configKey, RulesCategory rulesCategory, String pluginName, String description) {
122        this();
123        setName(name);
124        this.key = key;
125        this.configKey = configKey;
126        this.rulesCategory = rulesCategory;
127        this.pluginName = pluginName;
128        this.description = description;
129      }
130    
131      public String getName() {
132        return name;
133      }
134    
135      /**
136       * Sets the rule name
137       */
138      public final Rule setName(String name) {
139        this.name = removeNewLineCharacters(name);
140        return this;
141      }
142    
143      public String getKey() {
144        return key;
145      }
146    
147      /**
148       * Sets the rule key
149       */
150      public Rule setKey(String key) {
151        this.key = key;
152        return this;
153      }
154    
155      /**
156       * @return the rule category
157       */
158      public RulesCategory getRulesCategory() {
159        return rulesCategory;
160      }
161    
162      /**
163       * Sets the rule category
164       */
165      public Rule setRulesCategory(RulesCategory rulesCategory) {
166        this.rulesCategory = rulesCategory;
167        return this;
168      }
169    
170      public String getPluginName() {
171        return pluginName;
172      }
173    
174      /**
175       * Sets the plugin name the rule belongs to
176       */
177      public Rule setPluginName(String pluginName) {
178        this.pluginName = pluginName;
179        return this;
180      }
181    
182      public String getConfigKey() {
183        return configKey;
184      }
185    
186      /**
187       * Sets the configuration key
188       */
189      public Rule setConfigKey(String configKey) {
190        this.configKey = configKey;
191        return this;
192      }
193    
194      public String getDescription() {
195        return description;
196      }
197    
198      /**
199       * Sets the rule description
200       */
201      public Rule setDescription(String description) {
202        this.description = StringUtils.strip(description);
203        return this;
204      }
205    
206      public List<RuleParam> getParams() {
207        return params;
208      }
209    
210      /**
211       * Sets the rule parameters
212       */
213      public Rule setParams(List<RuleParam> params) {
214        this.params = params;
215        return this;
216      }
217    
218      public Integer getCategoryId() {
219        if (rulesCategory != null) {
220          return rulesCategory.getId();
221        }
222        return null;
223      }
224    
225      public RulePriority getPriority() {
226        return priority;
227      }
228    
229      /**
230       * Sets the rule priority. If null, uses the default priority
231       */
232      public Rule setPriority(RulePriority priority) {
233        if (priority == null) {
234          this.priority = DEFAULT_PRIORITY;
235        } else {
236          this.priority = priority;
237        }
238    
239        return this;
240      }
241    
242      @Override
243      public boolean equals(Object obj) {
244        if (!(obj instanceof Rule)) {
245          return false;
246        }
247        if (this == obj) {
248          return true;
249        }
250        Rule other = (Rule) obj;
251        return new EqualsBuilder()
252            .append(pluginName, other.getPluginName())
253            .append(key, other.getKey())
254            .isEquals();
255      }
256    
257      @Override
258      public int hashCode() {
259        return new HashCodeBuilder(17, 37)
260            .append(pluginName)
261            .append(key)
262            .toHashCode();
263      }
264    
265      @Override
266      public String toString() {
267        return new ToStringBuilder(this)
268            .append("id", getId())
269            .append("name", name)
270            .append("key", key)
271            .append("configKey", configKey)
272            .append("categ", rulesCategory)
273            .append("plugin", pluginName)
274            .append("params", params)
275            .toString();
276      }
277    
278      private String removeNewLineCharacters(String text) {
279        String removedCRLF = StringUtils.remove(text, "\n");
280        removedCRLF = StringUtils.remove(removedCRLF, "\r");
281        removedCRLF = StringUtils.remove(removedCRLF, "\n\r");
282        removedCRLF = StringUtils.remove(removedCRLF, "\r\n");
283        return removedCRLF;
284      }
285    }