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.database.model;
021
022import org.apache.commons.lang.StringUtils;
023import org.apache.commons.lang.builder.EqualsBuilder;
024import org.apache.commons.lang.builder.HashCodeBuilder;
025import org.apache.commons.lang.builder.ToStringBuilder;
026import org.hibernate.annotations.BatchSize;
027import org.sonar.api.database.BaseIdentifiable;
028import org.sonar.api.profiles.RulesProfile;
029import org.sonar.api.resources.ProjectLink;
030import org.sonar.api.resources.Resource;
031
032import javax.persistence.*;
033import java.util.ArrayList;
034import java.util.List;
035
036/**
037 * Class to map resource with hibernate model
038 */
039@Entity
040@Table(name = "projects")
041public class ResourceModel extends BaseIdentifiable implements Cloneable {
042
043  public static final String SCOPE_PROJECT = "PRJ";
044  public static final String QUALIFIER_PROJECT_TRUNK = "TRK";
045
046  public static final int DESCRIPTION_COLUMN_SIZE = 2000;
047  public static final int NAME_COLUMN_SIZE = 256;
048  public static final int KEY_SIZE = 400;
049
050  @Column(name = "name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE)
051  private String name;
052
053  @Column(name = "long_name", updatable = true, nullable = true, length = NAME_COLUMN_SIZE)
054  private String longName;
055
056  @Column(name = "description", updatable = true, nullable = true, length = DESCRIPTION_COLUMN_SIZE)
057  private String description;
058
059  @Column(name = "enabled", updatable = true, nullable = false)
060  private Boolean enabled = Boolean.TRUE;
061
062  @Column(name = "scope", updatable = true, nullable = false, length = 3)
063  private String scope;
064
065  @Column(name = "qualifier", updatable = true, nullable = false, length = 10)
066  private String qualifier;
067
068  @Column(name = "kee", updatable = false, nullable = false, length = KEY_SIZE)
069  private String key;
070
071  @Column(name = "language", updatable = true, nullable = true, length = 5)
072  private String languageKey;
073
074  @Column(name = "root_id", updatable = true, nullable = true)
075  private Integer rootId;
076
077  @Column(name = "copy_resource_id", updatable = true, nullable = true)
078  private Integer copyResourceId;
079
080  @Column(name = "person_id", updatable = true, nullable = true)
081  private Integer personId;
082
083  @OneToMany(mappedBy = "resource", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
084  @BatchSize(size = 8)
085  private List<ProjectLink> projectLinks = new ArrayList<ProjectLink>();
086
087  @ManyToOne(fetch = FetchType.LAZY)
088  @JoinColumn(name = "profile_id", updatable = true, nullable = true)
089  private RulesProfile rulesProfile;
090
091  /**
092   * Default constructor
093   */
094  public ResourceModel() {
095  }
096
097  /**
098   * <p>Creates a resource model</p>
099   *
100   * @param scope     the scope the rule will apply on
101   * @param key       the rule key. This is the name of the resource, including the path
102   * @param qualifier the resource qualifier
103   * @param rootId    the rootId for the resource
104   * @param name      the short name of the resource
105   */
106  public ResourceModel(String scope, String key, String qualifier, Integer rootId, String name) {
107    this.scope = scope;
108    this.key = key;
109    this.rootId = rootId;
110    this.name = name;
111    this.qualifier = qualifier;
112  }
113
114  /**
115   * Only available at project level.
116   */
117  public List<ProjectLink> getProjectLinks() {
118    return projectLinks;
119  }
120
121  public void setProjectLinks(List<ProjectLink> projectLinks) {
122    this.projectLinks = projectLinks;
123  }
124
125  /**
126   * @return a project link given its key if exists, null otherwise
127   */
128  public ProjectLink getProjectLink(String key) {
129    for (ProjectLink projectLink : projectLinks) {
130      if (key.equals(projectLink.getKey())) {
131        return projectLink;
132      }
133    }
134    return null;
135  }
136
137  /**
138   * Only available at project level.
139   */
140  public String getDescription() {
141    return description;
142  }
143
144  /**
145   * Sets the resource description, truncated to DESCRIPTION_COLUMN_SIZE
146   */
147  public void setDescription(String description) {
148    this.description = StringUtils.abbreviate(description, DESCRIPTION_COLUMN_SIZE);
149  }
150
151  public String getName() {
152    return name;
153  }
154
155  /**
156   * Sets the resource name, truncated to NAME_COLUMN_SIZE
157   */
158  public void setName(String name) {
159    this.name = StringUtils.abbreviate(name, NAME_COLUMN_SIZE);
160    if (this.longName == null) {
161      this.longName = this.name;
162    }
163  }
164
165  public String getLongName() {
166    return longName;
167  }
168
169  /**
170   * Sets the long name of the resource, truncated to NAME_COLUMN_SIZE
171   */
172  public void setLongName(String s) {
173    if (StringUtils.isBlank(s)) {
174      this.longName = name;
175    } else {
176      this.longName = StringUtils.abbreviate(s, NAME_COLUMN_SIZE);
177    }
178  }
179
180  public Boolean getEnabled() {
181    return enabled;
182  }
183
184  public void setEnabled(Boolean enabled) {
185    this.enabled = enabled;
186  }
187
188  public String getScope() {
189    return scope;
190  }
191
192  public void setScope(String scope) {
193    this.scope = scope;
194  }
195
196  public String getKey() {
197    return key;
198  }
199
200  public String getLanguageKey() {
201    return languageKey;
202  }
203
204  public void setLanguageKey(String lang) {
205    this.languageKey = lang;
206  }
207
208  public Integer getCopyResourceId() {
209    return copyResourceId;
210  }
211
212  public void setCopyResourceId(Integer i) {
213    this.copyResourceId = i;
214  }
215
216  /**
217   * @since 2.14
218   */
219  public Integer getPersonId() {
220    return personId;
221  }
222
223  /**
224   * @since 2.14
225   */
226  public ResourceModel setPersonId(Integer i) {
227    this.personId = i;
228    return this;
229  }
230
231  /**
232   * @throws IllegalArgumentException if the key is longer than KEY_SIZE
233   */
234  public void setKey(String key) {
235    if (key.length() > KEY_SIZE) {
236      throw new IllegalArgumentException("Resource key is too long, max is " + KEY_SIZE + " characters. Got : " + key);
237    }
238    this.key = key;
239  }
240
241  public Integer getRootId() {
242    return rootId;
243  }
244
245  public void setRootId(Integer rootId) {
246    this.rootId = rootId;
247  }
248
249  public RulesProfile getRulesProfile() {
250    return rulesProfile;
251  }
252
253  public void setRulesProfile(RulesProfile rulesProfile) {
254    this.rulesProfile = rulesProfile;
255  }
256
257  public String getQualifier() {
258    return qualifier;
259  }
260
261  public void setQualifier(String qualifier) {
262    this.qualifier = qualifier;
263  }
264
265  @Override
266  public boolean equals(Object obj) {
267    if (!(obj instanceof ResourceModel)) {
268      return false;
269    }
270    if (this == obj) {
271      return true;
272    }
273    ResourceModel other = (ResourceModel) obj;
274    return new EqualsBuilder()
275      .append(key, other.key)
276      .append(enabled, other.enabled)
277      .append(rootId, other.rootId)
278      .isEquals();
279  }
280
281  @Override
282  public int hashCode() {
283    return new HashCodeBuilder(17, 37)
284      .append(key)
285      .append(enabled)
286      .append(rootId)
287      .toHashCode();
288  }
289
290  @Override
291  public String toString() {
292    return new ToStringBuilder(this)
293      .append("id", getId())
294      .append("key", key)
295      .append("scope", scope)
296      .append("qualifier", qualifier)
297      .append("name", name)
298      .append("longName", longName)
299      .append("lang", languageKey)
300      .append("enabled", enabled)
301      .append("rootId", rootId)
302      .append("copyResourceId", copyResourceId)
303      .append("personId", personId)
304      .toString();
305  }
306
307  @Override
308  public Object clone() {
309    ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getName());
310    clone.setDescription(getDescription());
311    clone.setEnabled(getEnabled());
312    clone.setProjectLinks(getProjectLinks());
313    clone.setRulesProfile(getRulesProfile());
314    clone.setLanguageKey(getLanguageKey());
315    clone.setCopyResourceId(getCopyResourceId());
316    clone.setLongName(getLongName());
317    clone.setPersonId(getPersonId());
318    return clone;
319  }
320
321  /**
322   * Maps a resource to a resource model and returns the resource
323   */
324  public static ResourceModel build(Resource resource) {
325    ResourceModel model = new ResourceModel();
326    model.setEnabled(Boolean.TRUE);
327    model.setDescription(resource.getDescription());
328    model.setKey(resource.getKey());
329    if (resource.getLanguage() != null) {
330      model.setLanguageKey(resource.getLanguage().getKey());
331    }
332    if (StringUtils.isNotBlank(resource.getName())) {
333      model.setName(resource.getName());
334    } else {
335      model.setName(resource.getKey());
336    }
337    model.setLongName(resource.getLongName());
338    model.setQualifier(resource.getQualifier());
339    model.setScope(resource.getScope());
340    return model;
341  }
342
343}