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.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 java.util.ArrayList;
033    import java.util.List;
034    import javax.persistence.*;
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 = 3)
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      @OneToMany(mappedBy = "resource", fetch = FetchType.LAZY, cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE})
081      @BatchSize(size = 8)
082      private List<ProjectLink> projectLinks = new ArrayList<ProjectLink>();
083    
084      @ManyToOne(fetch = FetchType.LAZY)
085      @JoinColumn(name = "profile_id", updatable = true, nullable = true)
086      private RulesProfile rulesProfile;
087    
088      /**
089       * Default constructor
090       */
091      public ResourceModel() {
092      }
093    
094      /**
095       * <p>Creates a resource model</p>
096       *
097       * @param scope the scope the rule will apply on
098       * @param key the rule key. This is the name of the resource, including the path
099       * @param qualifier the resource qualifier
100       * @param rootId the rootId for the resource
101       * @param name the short name of the resource
102       */
103      public ResourceModel(String scope, String key, String qualifier, Integer rootId, String name) {
104        this.scope = scope;
105        this.key = key;
106        this.rootId = rootId;
107        this.name = name;
108        this.qualifier = qualifier;
109      }
110    
111      /**
112       * Only available at project level.
113       */
114      public List<ProjectLink> getProjectLinks() {
115        return projectLinks;
116      }
117    
118      public void setProjectLinks(List<ProjectLink> projectLinks) {
119        this.projectLinks = projectLinks;
120      }
121    
122      /**
123       * @return a project link given its key if exists, null otherwise
124       */
125      public ProjectLink getProjectLink(String key) {
126        for (ProjectLink projectLink : projectLinks) {
127          if (key.equals(projectLink.getKey())) {
128            return projectLink;
129          }
130        }
131        return null;
132      }
133    
134      /**
135       * Only available at project level.
136       */
137      public String getDescription() {
138        return description;
139      }
140    
141      /**
142       * Sets the resource description, truncated to DESCRIPTION_COLUMN_SIZE
143       */
144      public void setDescription(String description) {
145        this.description = StringUtils.abbreviate(description, DESCRIPTION_COLUMN_SIZE);
146      }
147    
148      public String getName() {
149        return name;
150      }
151    
152      /**
153       * Sets the resource name, truncated to NAME_COLUMN_SIZE
154       */
155      public void setName(String name) {
156        this.name = StringUtils.abbreviate(name, NAME_COLUMN_SIZE);
157      }
158    
159      public String getLongName() {
160        return longName;
161      }
162    
163      /**
164       * Sets the long name of the resource, truncated to NAME_COLUMN_SIZE
165       */
166      public void setLongName(String s) {
167        this.longName = StringUtils.abbreviate(s, NAME_COLUMN_SIZE);
168      }
169    
170      public Boolean getEnabled() {
171        return enabled;
172      }
173    
174      public void setEnabled(Boolean enabled) {
175        this.enabled = enabled;
176      }
177    
178      public String getScope() {
179        return scope;
180      }
181    
182      public void setScope(String scope) {
183        this.scope = scope;
184      }
185    
186      public String getKey() {
187        return key;
188      }
189    
190      public String getLanguageKey() {
191        return languageKey;
192      }
193    
194      public void setLanguageKey(String lang) {
195        this.languageKey = lang;
196      }
197    
198      public Integer getCopyResourceId() {
199        return copyResourceId;
200      }
201    
202      public void setCopyResourceId(Integer copyResourceId) {
203        this.copyResourceId = copyResourceId;
204      }
205    
206      /**
207       * @throws IllegalArgumentException if the key is longer than KEY_SIZE
208       */
209      public void setKey(String key) {
210        if (key.length() > KEY_SIZE) {
211          throw new IllegalArgumentException("Resource key is too long, max is " + KEY_SIZE + " characters. Got : " + key);
212        }
213        this.key = key;
214      }
215    
216      public Integer getRootId() {
217        return rootId;
218      }
219    
220      public void setRootId(Integer rootId) {
221        this.rootId = rootId;
222      }
223    
224      public RulesProfile getRulesProfile() {
225        return rulesProfile;
226      }
227    
228      public void setRulesProfile(RulesProfile rulesProfile) {
229        this.rulesProfile = rulesProfile;
230      }
231    
232      public String getQualifier() {
233        return qualifier;
234      }
235    
236      public void setQualifier(String qualifier) {
237        this.qualifier = qualifier;
238      }
239    
240      @Override
241      public boolean equals(Object obj) {
242        if (!(obj instanceof ResourceModel)) {
243          return false;
244        }
245        if (this == obj) {
246          return true;
247        }
248        ResourceModel other = (ResourceModel) obj;
249        return new EqualsBuilder()
250            .append(key, other.key)
251            .append(enabled, other.enabled)
252            .append(rootId, other.rootId)
253            .isEquals();
254      }
255    
256      @Override
257      public int hashCode() {
258        return new HashCodeBuilder(17, 37)
259            .append(key)
260            .append(enabled)
261            .append(rootId)
262            .toHashCode();
263      }
264    
265      @Override
266      public String toString() {
267        return new ToStringBuilder(this)
268            .append("id", getId())
269            .append("key", key)
270            .append("scope", scope)
271            .append("qualifier", qualifier)
272            .append("name", name)
273            .append("longName", longName)
274            .append("lang", languageKey)
275            .append("enabled", enabled)
276            .append("rootId", rootId)
277            .append("copyResourceId", copyResourceId)
278            .toString();
279      }
280    
281      @Override
282      public Object clone() {
283        ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getName());
284        clone.setDescription(getDescription());
285        clone.setEnabled(getEnabled());
286        clone.setProjectLinks(getProjectLinks());
287        clone.setRulesProfile(getRulesProfile());
288        clone.setLanguageKey(getLanguageKey());
289        clone.setCopyResourceId(getCopyResourceId());
290        clone.setLongName(getLongName());
291        return clone;
292      }
293    
294      /**
295       * Maps a resource to a resource model and returns the resource
296       */
297      public static ResourceModel build(Resource resource) {
298        ResourceModel model = new ResourceModel();
299        model.setEnabled(Boolean.TRUE);
300        model.setDescription(resource.getDescription());
301        model.setKey(resource.getKey());
302        if (resource.getLanguage() != null) {
303          model.setLanguageKey(resource.getLanguage().getKey());
304        }
305        model.setName(resource.getName());
306        model.setLongName(resource.getLongName());
307        model.setQualifier(resource.getQualifier());
308        model.setScope(resource.getScope());
309        return model;
310      }
311    
312    }