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.builder.EqualsBuilder;
023 import org.apache.commons.lang.builder.HashCodeBuilder;
024 import org.apache.commons.lang.builder.ToStringBuilder;
025 import org.sonar.api.database.BaseIdentifiable;
026 import org.sonar.api.database.DatabaseSession;
027
028 import java.util.Date;
029 import javax.persistence.*;
030
031 /**
032 * A class to map a snapshot with its hibernate model
033 */
034 @Entity
035 @Table(name = "snapshots")
036 public class Snapshot extends BaseIdentifiable {
037
038 /**
039 * This status is set on the snapshot at the beginning of the batch
040 */
041 public final static String STATUS_UNPROCESSED = "U";
042
043 /**
044 * This status is set on the snapshot at the end of the batch
045 */
046 public final static String STATUS_PROCESSED = "P";
047
048 @Column(name = "project_id", updatable = true, nullable = true)
049 private Integer resourceId;
050
051 @Temporal(TemporalType.TIMESTAMP)
052 @Column(name = "created_at", updatable = true, nullable = true)
053 private Date createdAt;
054
055 @Column(name = "version", updatable = true, nullable = true, length = 32)
056 private String version;
057
058 @Column(name = "islast")
059 private Boolean last = Boolean.FALSE;
060
061 @Column(name = "status")
062 private String status = STATUS_UNPROCESSED;
063
064 @Column(name = "scope", updatable = true, nullable = true, length = 3)
065 private String scope;
066
067 @Column(name = "path", updatable = true, nullable = true, length = 96)
068 private String path;
069
070 @Column(name = "depth", updatable = true, nullable = true)
071 private Integer depth;
072
073 @Column(name = "qualifier", updatable = true, nullable = true, length = 3)
074 private String qualifier;
075
076 @Column(name = "root_snapshot_id", updatable = true, nullable = true)
077 private Integer rootId;
078
079 @Column(name = "parent_snapshot_id", updatable = true, nullable = true)
080 private Integer parentId;
081
082 @Column(name = "root_project_id", updatable = true, nullable = true)
083 private Integer rootProjectId;
084
085 public Snapshot() {
086
087 }
088
089 public Snapshot(ResourceModel resource, Snapshot parent) {
090 this.resourceId = resource.getId();
091
092 if (resource != null) {
093 this.qualifier = resource.getQualifier();
094 this.scope = resource.getScope();
095 }
096
097 if (parent == null) {
098 path = "";
099 depth = 0;
100
101 } else {
102 this.parentId = parent.getId();
103 this.rootId = (parent.getRootId() == null ? parent.getId() : parent.getRootId());
104 this.createdAt = parent.getCreatedAt();
105 this.depth = parent.getDepth() + 1;
106 this.path = new StringBuilder()
107 .append(parent.getPath())
108 .append(parent.getId())
109 .append(".")
110 .toString();
111 }
112 this.rootProjectId = guessRootProjectId(resource, parent);
113 }
114
115 private static Integer guessRootProjectId(ResourceModel resource, Snapshot parent) {
116 Integer result;
117
118 // design problem : constants are defined in the Resource class, that should not be used by this class...
119 if ("TRK".equals(resource.getQualifier()) || "VW".equals(resource.getQualifier()) || "SVW".equals(resource.getQualifier())) {
120 result = resource.getCopyResourceId() != null ? resource.getCopyResourceId() : resource.getId();
121
122 } else if (parent == null) {
123 result = resource.getCopyResourceId() != null ? resource.getCopyResourceId() : resource.getId();
124
125 } else {
126 result = (parent.getRootProjectId() == null ? parent.getResourceId() : parent.getRootProjectId());
127 }
128 return result;
129 }
130
131 public Snapshot save(DatabaseSession session) {
132 return session.save(this);
133 }
134
135 public Snapshot(ResourceModel resource, boolean last, String status, Date date) {
136 this();
137 setResource(resource);
138 this.status = status;
139 this.last = last;
140 this.createdAt = date;
141 }
142
143 public Date getCreatedAt() {
144 return createdAt;
145 }
146
147 public void setCreatedAt(Date createdAt) {
148 this.createdAt = createdAt;
149 }
150
151 public Integer getResourceId() {
152 return resourceId;
153 }
154
155 public void setResourceId(Integer resourceId) {
156 this.resourceId = resourceId;
157 }
158
159 public final void setResource(ResourceModel resource) {
160 this.resourceId = resource.getId();
161 this.scope = resource.getScope();
162 this.qualifier = resource.getQualifier();
163 }
164
165 public String getVersion() {
166 return version;
167 }
168
169 public void setVersion(String version) {
170 this.version = version;
171 }
172
173 public Integer getParentId() {
174 return parentId;
175 }
176
177 public void setParentId(Integer i) {
178 this.parentId = i;
179 }
180
181 public Boolean getLast() {
182 return last;
183 }
184
185 public void setLast(Boolean last) {
186 this.last = last;
187 }
188
189 public String getStatus() {
190 return status;
191 }
192
193 public void setStatus(String status) {
194 this.status = status;
195 }
196
197 public String getScope() {
198 return scope;
199 }
200
201 public void setScope(String scope) {
202 this.scope = scope;
203 }
204
205 public String getQualifier() {
206 return qualifier;
207 }
208
209 public void setQualifier(String qualifier) {
210 this.qualifier = qualifier;
211 }
212
213 public Integer getRootId() {
214 return rootId;
215 }
216
217 public void setRootId(Integer i) {
218 this.rootId = i;
219 }
220
221 public String getPath() {
222 return path;
223 }
224
225 public void setPath(String path) {
226 this.path = path;
227 }
228
229 public Integer getDepth() {
230 return depth;
231 }
232
233 public Integer getRootProjectId() {
234 return rootProjectId;
235 }
236
237 public void setRootProjectId(Integer rootProjectId) {
238 this.rootProjectId = rootProjectId;
239 }
240
241 /**
242 * Sets the depth of the snapshot
243 *
244 * @throws IllegalArgumentException when depth is negative
245 */
246 public void setDepth(Integer depth) {
247 if (depth != null && depth < 0) {
248 throw new IllegalArgumentException("depth can not be negative : " + depth);
249 }
250 this.depth = depth;
251 }
252
253
254 @Override
255 public boolean equals(Object obj) {
256 if (!(obj instanceof Snapshot)) {
257 return false;
258 }
259 if (this == obj) {
260 return true;
261 }
262 Snapshot other = (Snapshot) obj;
263 return new EqualsBuilder()
264 .append(resourceId, other.getResourceId())
265 .append(createdAt, other.getCreatedAt())
266 .isEquals();
267 }
268
269 @Override
270 public int hashCode() {
271 return new HashCodeBuilder(17, 37)
272 .append(resourceId)
273 .append(createdAt)
274 .toHashCode();
275 }
276
277 @Override
278 public String toString() {
279 return new ToStringBuilder(this)
280 .append("id", getId())
281 .append("resourceId", resourceId)
282 .append("scope", scope)
283 .append("qualifier", qualifier)
284 .append("version", version)
285 .append("last", last)
286 .append("createdAt", createdAt)
287 .append("status", status)
288 .append("path", path)
289 .append("rootId", rootId)
290 .append("rootProjectId", rootProjectId)
291 .append("parentId", parentId)
292 .toString();
293 }
294 }