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 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 = 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 if (this.longName==null) {
158 this.longName = this.name;
159 }
160 }
161
162 public String getLongName() {
163 return longName;
164 }
165
166 /**
167 * Sets the long name of the resource, truncated to NAME_COLUMN_SIZE
168 */
169 public void setLongName(String s) {
170 if (StringUtils.isBlank(s)) {
171 this.longName = name;
172 } else {
173 this.longName = StringUtils.abbreviate(s, NAME_COLUMN_SIZE);
174 }
175 }
176
177 public Boolean getEnabled() {
178 return enabled;
179 }
180
181 public void setEnabled(Boolean enabled) {
182 this.enabled = enabled;
183 }
184
185 public String getScope() {
186 return scope;
187 }
188
189 public void setScope(String scope) {
190 this.scope = scope;
191 }
192
193 public String getKey() {
194 return key;
195 }
196
197 public String getLanguageKey() {
198 return languageKey;
199 }
200
201 public void setLanguageKey(String lang) {
202 this.languageKey = lang;
203 }
204
205 public Integer getCopyResourceId() {
206 return copyResourceId;
207 }
208
209 public void setCopyResourceId(Integer copyResourceId) {
210 this.copyResourceId = copyResourceId;
211 }
212
213 /**
214 * @throws IllegalArgumentException if the key is longer than KEY_SIZE
215 */
216 public void setKey(String key) {
217 if (key.length() > KEY_SIZE) {
218 throw new IllegalArgumentException("Resource key is too long, max is " + KEY_SIZE + " characters. Got : " + key);
219 }
220 this.key = key;
221 }
222
223 public Integer getRootId() {
224 return rootId;
225 }
226
227 public void setRootId(Integer rootId) {
228 this.rootId = rootId;
229 }
230
231 public RulesProfile getRulesProfile() {
232 return rulesProfile;
233 }
234
235 public void setRulesProfile(RulesProfile rulesProfile) {
236 this.rulesProfile = rulesProfile;
237 }
238
239 public String getQualifier() {
240 return qualifier;
241 }
242
243 public void setQualifier(String qualifier) {
244 this.qualifier = qualifier;
245 }
246
247 @Override
248 public boolean equals(Object obj) {
249 if (!(obj instanceof ResourceModel)) {
250 return false;
251 }
252 if (this == obj) {
253 return true;
254 }
255 ResourceModel other = (ResourceModel) obj;
256 return new EqualsBuilder()
257 .append(key, other.key)
258 .append(enabled, other.enabled)
259 .append(rootId, other.rootId)
260 .isEquals();
261 }
262
263 @Override
264 public int hashCode() {
265 return new HashCodeBuilder(17, 37)
266 .append(key)
267 .append(enabled)
268 .append(rootId)
269 .toHashCode();
270 }
271
272 @Override
273 public String toString() {
274 return new ToStringBuilder(this)
275 .append("id", getId())
276 .append("key", key)
277 .append("scope", scope)
278 .append("qualifier", qualifier)
279 .append("name", name)
280 .append("longName", longName)
281 .append("lang", languageKey)
282 .append("enabled", enabled)
283 .append("rootId", rootId)
284 .append("copyResourceId", copyResourceId)
285 .toString();
286 }
287
288 @Override
289 public Object clone() {
290 ResourceModel clone = new ResourceModel(getScope(), getKey(), getQualifier(), getRootId(), getName());
291 clone.setDescription(getDescription());
292 clone.setEnabled(getEnabled());
293 clone.setProjectLinks(getProjectLinks());
294 clone.setRulesProfile(getRulesProfile());
295 clone.setLanguageKey(getLanguageKey());
296 clone.setCopyResourceId(getCopyResourceId());
297 clone.setLongName(getLongName());
298 return clone;
299 }
300
301 /**
302 * Maps a resource to a resource model and returns the resource
303 */
304 public static ResourceModel build(Resource resource) {
305 ResourceModel model = new ResourceModel();
306 model.setEnabled(Boolean.TRUE);
307 model.setDescription(resource.getDescription());
308 model.setKey(resource.getKey());
309 if (resource.getLanguage() != null) {
310 model.setLanguageKey(resource.getLanguage().getKey());
311 }
312 if (StringUtils.isNotBlank(resource.getName())) {
313 model.setName(resource.getName());
314 } else {
315 model.setName(resource.getKey());
316 }
317 model.setLongName(resource.getLongName());
318 model.setQualifier(resource.getQualifier());
319 model.setScope(resource.getScope());
320 return model;
321 }
322
323 }