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 */
020package org.sonar.api.qualitymodel;
021
022import com.google.common.collect.Lists;
023import org.apache.commons.lang.ObjectUtils;
024import org.apache.commons.lang.StringUtils;
025import org.apache.commons.lang.builder.ToStringBuilder;
026import org.apache.commons.lang.builder.ToStringStyle;
027import org.sonar.api.rules.Rule;
028
029import javax.persistence.*;
030import java.util.List;
031
032/**
033 * @since 2.3
034 */
035@Entity
036@Table(name = "quality_models")
037public final class Model implements Comparable<Model> {
038
039  @Id
040  @Column(name = "id")
041  @GeneratedValue
042  private Integer id;
043
044  @Column(name = "name", nullable = false, unique = true, length = 100)
045  private String name;
046
047  @OneToMany(mappedBy = "model", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
048  private List<Characteristic> characteristics = Lists.newArrayList();
049
050  /**
051   * Use the factory method <code>Model</code>
052   */
053  Model() {
054  }
055
056  public static Model create() {
057    return new Model();
058  }
059
060  public static Model createByName(String s) {
061    return new Model().setName(s);
062  }
063
064  public Characteristic createCharacteristicByName(String name) {
065    Characteristic c = new Characteristic().setName(name, true);
066    return addCharacteristic(c);
067  }
068
069  public Characteristic createCharacteristicByKey(String key, String name) {
070    Characteristic c = new Characteristic().setKey(key).setName(name, false);
071    return addCharacteristic(c);
072  }
073
074  public Characteristic createCharacteristicByRule(Rule rule) {
075    Characteristic c = new Characteristic().setRule(rule);
076    return addCharacteristic(c);
077  }
078
079  public Integer getId() {
080    return id;
081  }
082
083  Model setId(Integer id) {
084    this.id = id;
085    return this;
086  }
087
088  public String getName() {
089    return name;
090  }
091
092  public List<Characteristic> getRootCharacteristics() {
093    return getCharacteristicsByDepth(Characteristic.ROOT_DEPTH);
094  }
095
096  public Model setName(String name) {
097    this.name = StringUtils.trim(name);
098    return this;
099  }
100
101  public Characteristic addCharacteristic(Characteristic c) {
102    c.setModel(this);
103    c.setOrder(characteristics.size() + 1);
104    characteristics.add(c);
105    return c;
106  }
107
108  /**
109   * @return enabled characteristics
110   */
111  public List<Characteristic> getCharacteristics() {
112    return getCharacteristics(true);
113  }
114
115  public List<Characteristic> getCharacteristics(boolean onlyEnabled) {
116    if (!onlyEnabled) {
117      return characteristics;
118    }
119    List<Characteristic> result = Lists.newArrayList();
120    for (Characteristic characteristic : characteristics) {
121      if (characteristic.getEnabled()) {
122        result.add(characteristic);
123      }
124    }
125    return result;
126  }
127
128  /**
129   * Search for an ENABLED characteristic by its key.
130   */
131  public Characteristic getCharacteristicByKey(String key) {
132    for (Characteristic characteristic : characteristics) {
133      if (characteristic.getEnabled() && StringUtils.equals(key, characteristic.getKey())) {
134        return characteristic;
135      }
136    }
137    return null;
138  }
139
140  /**
141   * Search for an ENABLED characteristic with the specified rule.
142   */
143  public Characteristic getCharacteristicByRule(Rule rule) {
144    if (rule != null) {
145      for (Characteristic characteristic : characteristics) {
146        if (characteristic.getEnabled() && ObjectUtils.equals(rule, characteristic.getRule())) {
147          return characteristic;
148        }
149      }
150    }
151    return null;
152  }
153
154  /**
155   * Search for ENABLED characteristics by their depth.
156   */
157  public List<Characteristic> getCharacteristicsByDepth(int depth) {
158    List<Characteristic> result = Lists.newArrayList();
159    for (Characteristic c : characteristics) {
160      if (c.getEnabled() && c.getDepth() == depth) {
161        result.add(c);
162      }
163    }
164    return result;
165  }
166
167  /**
168   * Search for an ENABLED characteristic by its name.
169   */
170  public Characteristic getCharacteristicByName(String name) {
171    for (Characteristic characteristic : characteristics) {
172      if (characteristic.getEnabled() && StringUtils.equals(name, characteristic.getName())) {
173        return characteristic;
174      }
175    }
176    return null;
177  }
178
179  public Model removeCharacteristic(Characteristic characteristic) {
180    if (characteristic.getId() == null) {
181      characteristics.remove(characteristic);
182      for (Characteristic parent : characteristic.getParents()) {
183        parent.removeChild(characteristic);
184      }
185    } else {
186      characteristic.setEnabled(false);
187    }
188    for (Characteristic child : characteristic.getChildren()) {
189      removeCharacteristic(child);
190    }
191    return this;
192  }
193
194  @Override
195  public boolean equals(Object o) {
196    if (this == o) {
197      return true;
198    }
199    if (o == null || getClass() != o.getClass()) {
200      return false;
201    }
202
203    Model model = (Model) o;
204    if (name != null ? !name.equals(model.name) : model.name != null) {
205      return false;
206    }
207    return true;
208  }
209
210  @Override
211  public int hashCode() {
212    return name != null ? name.hashCode() : 0;
213  }
214
215  @Override
216  public String toString() {
217    return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
218        .append("id", id)
219        .append("name", name)
220        .toString();
221  }
222
223  public int compareTo(Model o) {
224    return getName().compareTo(o.getName());
225  }
226
227}