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 = 60) 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 }