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