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 this.qualifier = resource.getQualifier(); 092 this.scope = resource.getScope(); 093 094 if (parent == null) { 095 path = ""; 096 depth = 0; 097 this.createdAt = new Date(); 098 099 } else { 100 this.parentId = parent.getId(); 101 this.rootId = (parent.getRootId() == null ? parent.getId() : parent.getRootId()); 102 this.createdAt = parent.getCreatedAt(); 103 this.depth = parent.getDepth() + 1; 104 this.path = new StringBuilder() 105 .append(parent.getPath()) 106 .append(parent.getId()) 107 .append(".") 108 .toString(); 109 } 110 this.rootProjectId = guessRootProjectId(resource, parent); 111 } 112 113 private static Integer guessRootProjectId(ResourceModel resource, Snapshot parent) { 114 Integer result; 115 116 // design problem : constants are defined in the Resource class, that should not be used by this class... 117 if ("TRK".equals(resource.getQualifier()) || "VW".equals(resource.getQualifier()) || "SVW".equals(resource.getQualifier())) { 118 result = resource.getCopyResourceId() != null ? resource.getCopyResourceId() : resource.getId(); 119 120 } else if (parent == null) { 121 result = resource.getCopyResourceId() != null ? resource.getCopyResourceId() : resource.getId(); 122 123 } else { 124 result = (parent.getRootProjectId() == null ? parent.getResourceId() : parent.getRootProjectId()); 125 } 126 return result; 127 } 128 129 public Snapshot save(DatabaseSession session) { 130 return session.save(this); 131 } 132 133 public Snapshot(ResourceModel resource, boolean last, String status, Date date) { 134 this(); 135 setResource(resource); 136 this.status = status; 137 this.last = last; 138 this.createdAt = date; 139 } 140 141 public Date getCreatedAt() { 142 return createdAt; 143 } 144 145 public void setCreatedAt(Date createdAt) { 146 this.createdAt = createdAt; 147 } 148 149 public Integer getResourceId() { 150 return resourceId; 151 } 152 153 public void setResourceId(Integer resourceId) { 154 this.resourceId = resourceId; 155 } 156 157 public final void setResource(ResourceModel resource) { 158 this.resourceId = resource.getId(); 159 this.scope = resource.getScope(); 160 this.qualifier = resource.getQualifier(); 161 } 162 163 public String getVersion() { 164 return version; 165 } 166 167 public void setVersion(String version) { 168 this.version = version; 169 } 170 171 public Integer getParentId() { 172 return parentId; 173 } 174 175 public void setParentId(Integer i) { 176 this.parentId = i; 177 } 178 179 public Boolean getLast() { 180 return last; 181 } 182 183 public void setLast(Boolean last) { 184 this.last = last; 185 } 186 187 public String getStatus() { 188 return status; 189 } 190 191 public void setStatus(String status) { 192 this.status = status; 193 } 194 195 public String getScope() { 196 return scope; 197 } 198 199 public void setScope(String scope) { 200 this.scope = scope; 201 } 202 203 public String getQualifier() { 204 return qualifier; 205 } 206 207 public void setQualifier(String qualifier) { 208 this.qualifier = qualifier; 209 } 210 211 public Integer getRootId() { 212 return rootId; 213 } 214 215 public void setRootId(Integer i) { 216 this.rootId = i; 217 } 218 219 public String getPath() { 220 return path; 221 } 222 223 public void setPath(String path) { 224 this.path = path; 225 } 226 227 public Integer getDepth() { 228 return depth; 229 } 230 231 public Integer getRootProjectId() { 232 return rootProjectId; 233 } 234 235 public void setRootProjectId(Integer rootProjectId) { 236 this.rootProjectId = rootProjectId; 237 } 238 239 /** 240 * Sets the depth of the snapshot 241 * 242 * @throws IllegalArgumentException when depth is negative 243 */ 244 public void setDepth(Integer depth) { 245 if (depth != null && depth < 0) { 246 throw new IllegalArgumentException("depth can not be negative : " + depth); 247 } 248 this.depth = depth; 249 } 250 251 252 @Override 253 public boolean equals(Object obj) { 254 if (!(obj instanceof Snapshot)) { 255 return false; 256 } 257 if (this == obj) { 258 return true; 259 } 260 Snapshot other = (Snapshot) obj; 261 return new EqualsBuilder() 262 .append(resourceId, other.getResourceId()) 263 .append(createdAt, other.getCreatedAt()) 264 .isEquals(); 265 } 266 267 @Override 268 public int hashCode() { 269 return new HashCodeBuilder(17, 37) 270 .append(resourceId) 271 .append(createdAt) 272 .toHashCode(); 273 } 274 275 @Override 276 public String toString() { 277 return new ToStringBuilder(this) 278 .append("id", getId()) 279 .append("resourceId", resourceId) 280 .append("scope", scope) 281 .append("qualifier", qualifier) 282 .append("version", version) 283 .append("last", last) 284 .append("createdAt", createdAt) 285 .append("status", status) 286 .append("path", path) 287 .append("rootId", rootId) 288 .append("rootProjectId", rootProjectId) 289 .append("parentId", parentId) 290 .toString(); 291 } 292 }