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.profiles;
021    
022    import org.apache.commons.collections.CollectionUtils;
023    import org.apache.commons.collections.Transformer;
024    import org.apache.commons.lang.builder.EqualsBuilder;
025    import org.apache.commons.lang.builder.HashCodeBuilder;
026    import org.sonar.api.database.BaseIdentifiable;
027    import org.sonar.api.database.model.ResourceModel;
028    import org.sonar.api.rules.ActiveRule;
029    import org.sonar.api.rules.Rule;
030    import org.sonar.api.rules.RulePriority;
031    
032    import java.util.ArrayList;
033    import java.util.List;
034    import javax.persistence.*;
035    
036    /**
037     * Class to map rules profile with hibernate model
038     */
039    @Entity
040    @Table(name = "rules_profiles")
041    public class RulesProfile extends BaseIdentifiable implements Cloneable {
042    
043      /**
044       * The profile key for the embedded profile Sonar Way
045       */
046      public static final String SONAR_WAY_NAME = "Sonar way";
047    
048      /**
049       * The profile key for the embedded profile Sonar Way with Findbugs
050       */
051      public static final String SONAR_WAY_FINDBUGS_NAME = "Sonar way with Findbugs";
052    
053      /**
054       * The profile key for the embedded profile Sun checks
055       */
056      public static final String SUN_CONVENTIONS_NAME = "Sun checks";
057    
058      @Column(name = "name", updatable = true, nullable = false)
059      private String name;
060    
061      @Column(name = "default_profile", updatable = true, nullable = false)
062      private Boolean defaultProfile = Boolean.FALSE;
063    
064      @Column(name = "provided", updatable = true, nullable = false)
065      private Boolean provided = Boolean.FALSE;
066    
067      @Column(name = "language", updatable = true, nullable = false)
068      private String language;
069    
070      @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
071      private List<ActiveRule> activeRules;
072    
073      @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
074      private List<Alert> alerts;
075    
076      @OneToMany(mappedBy = "rulesProfile", fetch = FetchType.LAZY)
077      private List<ResourceModel> projects;
078    
079      /**
080       * Default constructor
081       */
082      public RulesProfile() {
083      }
084    
085      /**
086       * <p>Creates a profile of rules with empty active rules, empty alerts and empty project lists.</p>
087       *
088       * @param name the name to be used to access the profile, will be used as a key and display name
089       * @param language the language to which this profile applies
090       */
091      public RulesProfile(String name, String language) {
092        this.name = name;
093        this.language = language;
094        this.activeRules = new ArrayList<ActiveRule>();
095        this.alerts = new ArrayList<Alert>();
096        this.projects = new ArrayList<ResourceModel>();
097      }
098    
099      /**
100       * <p>Creates a profile of rules with empty active rules, empty alerts and empty project lists.</p>
101       *
102       * @param name the name to be used to access the profile, will be used as a key and display name
103       * @param language the language to which this profile applies
104       * @param defaultProfile whether this is the default profile for the language
105       * @param provided whether the profile is embarked in core Sonar
106       */
107      public RulesProfile(String name, String language, boolean defaultProfile, boolean provided) {
108        this(name, language);
109        this.defaultProfile = defaultProfile;
110        this.provided = provided;
111      }
112    
113      /**
114       * @return the name of the profile
115       */
116      public String getName() {
117        return name;
118      }
119    
120      /**
121       * Sets the name of the profile
122       */
123      public void setName(String name) {
124        this.name = name;
125      }
126    
127      /**
128       * @return the list of active rules
129       */
130      public List<ActiveRule> getActiveRules() {
131        return activeRules;
132      }
133    
134      /**
135       * Sets the list of active rules
136       */
137      public void setActiveRules(List<ActiveRule> activeRules) {
138        this.activeRules = activeRules;
139      }
140    
141      /**
142       * @return whether this is the default profile for the language
143       */
144      public Boolean getDefaultProfile() {
145        return defaultProfile;
146      }
147    
148      /**
149       * Sets whether this is the default profile for the language
150       */
151      public void setDefaultProfile(Boolean defaultProfile) {
152        this.defaultProfile = defaultProfile;
153      }
154    
155      /**
156       * @return whether the profile ships with Sonar core
157       */
158      public Boolean getProvided() {
159        return provided;
160      }
161    
162      /**
163       * Sets wether the profile ships with Sonar core
164       */
165      public void setProvided(Boolean provided) {
166        this.provided = provided;
167      }
168    
169      /**
170       * @return the language of the profile
171       */
172      public String getLanguage() {
173        return language;
174      }
175    
176      /**
177       * Sets the language for the profile
178       */
179      public void setLanguage(String language) {
180        this.language = language;
181      }
182    
183      /**
184       * @return the list of alerts defined in the profile
185       */
186      public List<Alert> getAlerts() {
187        return alerts;
188      }
189    
190      /**
191       * Sets the list of alerts for the profile
192       */
193      public void setAlerts(List<Alert> alerts) {
194        this.alerts = alerts;
195      }
196    
197      /**
198       * @return the list of projects attached to the profile
199       */
200      public List<ResourceModel> getProjects() {
201        return projects;
202      }
203    
204      /**
205       * Sets the list of projects attached to the profile
206       */
207      public void setProjects(List<ResourceModel> projects) {
208        this.projects = projects;
209      }
210    
211      /**
212       * @return the list of active rules for a given priority
213       */
214      public List<ActiveRule> getActiveRules(RulePriority priority) {
215        List<ActiveRule> result = new ArrayList<ActiveRule>();
216        for (ActiveRule activeRule : getActiveRules()) {
217          if (activeRule.getPriority().equals(priority)) {
218            result.add(activeRule);
219          }
220        }
221        return result;
222      }
223    
224      /**
225       * @return the list of active rules for a given plugin
226       */
227      public List<ActiveRule> getActiveRulesByPlugin(String pluginKey) {
228        List<ActiveRule> result = new ArrayList<ActiveRule>();
229        for (ActiveRule activeRule : getActiveRules()) {
230          if (pluginKey.equals(activeRule.getPluginName())) {
231            result.add(activeRule);
232          }
233        }
234        return result;
235      }
236    
237      /**
238       * @return an active rule from a plugin key and a rule key if the rule is activated, null otherwise
239       */
240      public ActiveRule getActiveRule(String pluginKey, String ruleKey) {
241        for (ActiveRule activeRule : getActiveRules()) {
242          if (activeRule != null && activeRule.getRuleKey().equals(ruleKey) && activeRule.getPluginName().equals(pluginKey)) {
243            return activeRule;
244          }
245        }
246        return null;
247      }
248    
249      /**
250       * THIS METHOD SHOULD NOT BE USED AS CURRENTLY THE PLUGIN KEY CAN NOT BE DETERMINED
251       *
252       * @return an active rule from a rule key if the rule is activated, null otherwise
253       */
254      public ActiveRule getActiveRule(Rule rule) {
255        return getActiveRule(rule.getPluginName(), rule.getKey());
256      }
257    
258      @Override
259      public boolean equals(Object obj) {
260        if (!(obj instanceof RulesProfile)) {
261          return false;
262        }
263        if (this == obj) {
264          return true;
265        }
266        RulesProfile other = (RulesProfile) obj;
267        return new EqualsBuilder().append(language, other.getLanguage()).append(name, other.getName()).isEquals();
268      }
269    
270      @Override
271      public int hashCode() {
272        return new HashCodeBuilder(17, 37).append(language).append(name).toHashCode();
273      }
274    
275      @Override
276      public Object clone() {
277        RulesProfile clone = new RulesProfile(getName(), getLanguage(), getDefaultProfile(), getProvided());
278        if (CollectionUtils.isNotEmpty(getActiveRules())) {
279          clone.setActiveRules(new ArrayList<ActiveRule>(CollectionUtils.collect(getActiveRules(), new Transformer() {
280            public Object transform(Object input) {
281              return ((ActiveRule) input).clone();
282            }
283          })));
284        }
285        if (CollectionUtils.isNotEmpty(getAlerts())) {
286          clone.setAlerts(new ArrayList<Alert>(CollectionUtils.collect(getAlerts(), new Transformer() {
287            public Object transform(Object input) {
288              return ((Alert) input).clone();
289            }
290          })));
291        }
292        if (CollectionUtils.isNotEmpty(getProjects())) {
293          clone.setProjects(new ArrayList<ResourceModel>(CollectionUtils.collect(getProjects(), new Transformer() {
294            public Object transform(Object input) {
295              return ((ResourceModel) input).clone();
296            }
297          })));
298        }
299        return clone;
300      }
301    
302      @Override
303      public String toString() {
304        return new StringBuilder().append(name).append(", language=").append(language).toString();
305      }
306    }