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     */
020    package org.sonar.api.database.model;
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.BatchSize;
027    import org.sonar.api.database.BaseIdentifiable;
028    import org.sonar.api.profiles.RulesProfile;
029    import org.sonar.api.resources.ProjectLink;
030    import org.sonar.api.resources.Resource;
031    
032    import javax.persistence.*;
033    import java.util.ArrayList;
034    import java.util.List;
035    
036    /**
037     * Class to map resource with hibernate model
038     */
039    @Entity
040    @Table(name = "projects")
041    public 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    }