001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2013 SonarSource
004 * mailto:contact AT sonarsource DOT com
005 *
006 * SonarQube 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 * SonarQube 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 License
017 * along with this program; if not, write to the Free Software Foundation,
018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019 */
020package org.sonar.api.database.model;
021
022import org.apache.commons.lang.builder.EqualsBuilder;
023import org.apache.commons.lang.builder.HashCodeBuilder;
024import org.apache.commons.lang.builder.ReflectionToStringBuilder;
025import org.apache.commons.lang.builder.ToStringStyle;
026import org.sonar.api.database.BaseIdentifiable;
027import org.sonar.api.database.DatabaseSession;
028
029import javax.persistence.Column;
030import javax.persistence.Entity;
031import javax.persistence.Table;
032import javax.persistence.Temporal;
033import javax.persistence.TemporalType;
034
035import java.io.Serializable;
036import java.util.Date;
037
038/**
039 * A class to map a snapshot with its hibernate model
040 */
041@Entity
042@Table(name = "snapshots")
043public class Snapshot extends BaseIdentifiable implements Serializable {
044
045  /**
046   * This status is set on the snapshot at the beginning of the batch
047   */
048  public static final String STATUS_UNPROCESSED = "U";
049
050  /**
051   * This status is set on the snapshot at the end of the batch
052   */
053  public static final String STATUS_PROCESSED = "P";
054
055  @Column(name = "project_id", updatable = true, nullable = true)
056  private Integer resourceId;
057
058  @Temporal(TemporalType.TIMESTAMP)
059  @Column(name = "build_date", updatable = true, nullable = true)
060  private Date buildDate;
061
062  @Temporal(TemporalType.TIMESTAMP)
063  @Column(name = "created_at", updatable = true, nullable = true)
064  private Date createdAt;
065
066  @Column(name = "version", updatable = true, nullable = true, length = 500)
067  private String version;
068
069  @Column(name = "islast")
070  private Boolean last = Boolean.FALSE;
071
072  @Column(name = "status")
073  private String status = STATUS_UNPROCESSED;
074
075  @Column(name = "purge_status", updatable = true, nullable = true)
076  private Integer purgeStatus;
077
078  @Column(name = "scope", updatable = true, nullable = true, length = 3)
079  private String scope;
080
081  @Column(name = "path", updatable = true, nullable = true, length = 500)
082  private String path;
083
084  @Column(name = "depth", updatable = true, nullable = true)
085  private Integer depth;
086
087  @Column(name = "qualifier", updatable = true, nullable = true, length = 10)
088  private String qualifier;
089
090  @Column(name = "root_snapshot_id", updatable = true, nullable = true)
091  private Integer rootId;
092
093  @Column(name = "parent_snapshot_id", updatable = true, nullable = true)
094  private Integer parentId;
095
096  @Column(name = "root_project_id", updatable = true, nullable = true)
097  private Integer rootProjectId;
098
099  @Column(name = "period1_mode", updatable = true, nullable = true, length = 100)
100  private String period1Mode;
101
102  @Column(name = "period2_mode", updatable = true, nullable = true, length = 100)
103  private String period2Mode;
104
105  @Column(name = "period3_mode", updatable = true, nullable = true, length = 100)
106  private String period3Mode;
107
108  @Column(name = "period4_mode", updatable = true, nullable = true, length = 100)
109  private String period4Mode;
110
111  @Column(name = "period5_mode", updatable = true, nullable = true, length = 100)
112  private String period5Mode;
113
114  @Column(name = "period1_param", updatable = true, nullable = true, length = 100)
115  private String period1Param;
116
117  @Column(name = "period2_param", updatable = true, nullable = true, length = 100)
118  private String period2Param;
119
120  @Column(name = "period3_param", updatable = true, nullable = true, length = 100)
121  private String period3Param;
122
123  @Column(name = "period4_param", updatable = true, nullable = true, length = 100)
124  private String period4Param;
125
126  @Column(name = "period5_param", updatable = true, nullable = true, length = 100)
127  private String period5Param;
128
129  @Column(name = "period1_date", updatable = true, nullable = true)
130  private Date period1Date;
131
132  @Column(name = "period2_date", updatable = true, nullable = true)
133  private Date period2Date;
134
135  @Column(name = "period3_date", updatable = true, nullable = true)
136  private Date period3Date;
137
138  @Column(name = "period4_date", updatable = true, nullable = true)
139  private Date period4Date;
140
141  @Column(name = "period5_date", updatable = true, nullable = true)
142  private Date period5Date;
143
144  public Snapshot() {
145
146  }
147
148  public Snapshot(ResourceModel resource, Snapshot parent) {
149    this.resourceId = resource.getId();
150    this.qualifier = resource.getQualifier();
151    this.scope = resource.getScope();
152
153    if (parent == null) {
154      path = "";
155      depth = 0;
156      this.createdAt = new Date();
157
158    } else {
159      this.parentId = parent.getId();
160      this.rootId = (parent.getRootId() == null ? parent.getId() : parent.getRootId());
161      this.createdAt = parent.getCreatedAt();
162      this.depth = parent.getDepth() + 1;
163      this.path = new StringBuilder()
164          .append(parent.getPath())
165          .append(parent.getId())
166          .append(".")
167          .toString();
168    }
169    this.rootProjectId = guessRootProjectId(resource, parent);
170  }
171
172  private static Integer guessRootProjectId(ResourceModel resource, Snapshot parent) {
173    Integer result;
174    if (parent == null) {
175      result = resource.getId();
176    } else {
177      result = (parent.getRootProjectId() == null ? parent.getResourceId() : parent.getRootProjectId());
178    }
179    return result;
180  }
181
182  public Snapshot save(DatabaseSession session) {
183    return session.save(this);
184  }
185
186  public Snapshot(ResourceModel resource, boolean last, String status, Date date) {
187    this();
188    setResource(resource);
189    this.status = status;
190    this.last = last;
191    this.createdAt = date;
192  }
193
194  /**
195   * Insertion date (technical)
196   *
197   * @since 2.14
198   */
199  public Date getBuildDate() {
200    return buildDate;
201  }
202
203  /**
204   * Insertion date (technical)
205   *
206   * @since 2.14
207   */
208  public Snapshot setBuildDate(Date d) {
209    this.buildDate = d;
210    return this;
211  }
212
213  public Date getCreatedAt() {
214    return createdAt;
215  }
216
217  public Snapshot setCreatedAt(Date createdAt) {
218    this.createdAt = createdAt;
219    return this;
220  }
221
222  public Integer getResourceId() {
223    return resourceId;
224  }
225
226  public Snapshot setResourceId(Integer resourceId) {
227    this.resourceId = resourceId;
228    return this;
229  }
230
231  public final Snapshot setResource(ResourceModel resource) {
232    this.resourceId = resource.getId();
233    this.scope = resource.getScope();
234    this.qualifier = resource.getQualifier();
235    return this;
236  }
237
238  public String getVersion() {
239    return version;
240  }
241
242  public Snapshot setVersion(String version) {
243    this.version = version;
244    return this;
245  }
246
247  public Integer getParentId() {
248    return parentId;
249  }
250
251  public Snapshot setParentId(Integer i) {
252    this.parentId = i;
253    return this;
254  }
255
256  public Boolean getLast() {
257    return last;
258  }
259
260  public Snapshot setLast(Boolean last) {
261    this.last = last;
262    return this;
263  }
264
265  public String getStatus() {
266    return status;
267  }
268
269  public Snapshot setStatus(String status) {
270    this.status = status;
271    return this;
272  }
273
274  /**
275   * @since 2.14
276   */
277  public Integer getPurgeStatus() {
278    return purgeStatus;
279  }
280
281  /**
282     * @since 2.14
283     */
284  public Snapshot setPurgeStatus(Integer i) {
285    this.purgeStatus = i;
286    return this;
287  }
288
289  public String getScope() {
290    return scope;
291  }
292
293  public Snapshot setScope(String scope) {
294    this.scope = scope;
295    return this;
296  }
297
298  public String getQualifier() {
299    return qualifier;
300  }
301
302  public Snapshot setQualifier(String qualifier) {
303    this.qualifier = qualifier;
304    return this;
305  }
306
307  public Integer getRootId() {
308    return rootId;
309  }
310
311  public Snapshot setRootId(Integer i) {
312    this.rootId = i;
313    return this;
314  }
315
316  public String getPath() {
317    return path;
318  }
319
320  public Snapshot setPath(String path) {
321    this.path = path;
322    return this;
323  }
324
325  public Integer getDepth() {
326    return depth;
327  }
328
329  public Integer getRootProjectId() {
330    return rootProjectId;
331  }
332
333  public Snapshot setRootProjectId(Integer rootProjectId) {
334    this.rootProjectId = rootProjectId;
335    return this;
336  }
337
338  /**
339   * Sets the depth of the snapshot
340   *
341   * @throws IllegalArgumentException when depth is negative
342   */
343  public void setDepth(Integer depth) {
344    if (depth != null && depth < 0) {
345      throw new IllegalArgumentException("depth can not be negative : " + depth);
346    }
347    this.depth = depth;
348  }
349
350  public String getPeriod1Mode() {
351    return period1Mode;
352  }
353
354  /**
355   * For internal use.
356   *
357   * @since 2.5
358   */
359  public Snapshot setPeriod1Mode(String s) {
360    this.period1Mode = s;
361    return this;
362  }
363
364  public String getPeriod2Mode() {
365    return period2Mode;
366  }
367
368  /**
369   * For internal use.
370   *
371   * @since 2.5
372   */
373  public Snapshot setPeriod2Mode(String s) {
374    this.period2Mode = s;
375    return this;
376  }
377
378  public String getPeriod3Mode() {
379    return period3Mode;
380  }
381
382  /**
383   * For internal use.
384   *
385   * @since 2.5
386   */
387  public Snapshot setPeriod3Mode(String s) {
388    this.period3Mode = s;
389    return this;
390  }
391
392  public String getPeriod4Mode() {
393    return period4Mode;
394  }
395
396  /**
397   * For internal use.
398   *
399   * @since 2.5
400   */
401  public Snapshot setPeriod4Mode(String s) {
402    this.period4Mode = s;
403    return this;
404  }
405
406  public String getPeriod5Mode() {
407    return period5Mode;
408  }
409
410  /**
411   * For internal use.
412   *
413   * @since 2.5
414   */
415  public Snapshot setPeriod5Mode(String s) {
416    this.period5Mode = s;
417    return this;
418  }
419
420  public String getPeriod1Param() {
421    return period1Param;
422  }
423
424  /**
425   * For internal use.
426   *
427   * @since 2.5
428   */
429  public Snapshot setPeriod1Param(String s) {
430    this.period1Param = s;
431    return this;
432  }
433
434  public String getPeriod2Param() {
435    return period2Param;
436  }
437
438  /**
439   * For internal use.
440   *
441   * @since 2.5
442   */
443  public Snapshot setPeriod2Param(String s) {
444    this.period2Param = s;
445    return this;
446  }
447
448  public String getPeriod3Param() {
449    return period3Param;
450  }
451
452  /**
453   * For internal use.
454   *
455   * @since 2.5
456   */
457  public Snapshot setPeriod3Param(String s) {
458    this.period3Param = s;
459    return this;
460  }
461
462  public String getPeriod4Param() {
463    return period4Param;
464  }
465
466  /**
467   * For internal use.
468   *
469   * @since 2.5
470   */
471  public Snapshot setPeriod4Param(String s) {
472    this.period4Param = s;
473    return this;
474  }
475
476  public String getPeriod5Param() {
477    return period5Param;
478  }
479
480  /**
481   * For internal use.
482   *
483   * @since 2.5
484   */
485  public Snapshot setPeriod5Param(String s) {
486    this.period5Param = s;
487    return this;
488  }
489
490  public Date getPeriod1Date() {
491    return period1Date;
492  }
493
494  /**
495   * For internal use.
496   *
497   * @since 2.5
498   */
499  public Snapshot setPeriod1Date(Date period1Date) {
500    this.period1Date = period1Date;
501    return this;
502  }
503
504  public Date getPeriod2Date() {
505    return period2Date;
506  }
507
508  /**
509   * For internal use.
510   *
511   * @since 2.5
512   */
513  public Snapshot setPeriod2Date(Date period2Date) {
514    this.period2Date = period2Date;
515    return this;
516  }
517
518  public Date getPeriod3Date() {
519    return period3Date;
520  }
521
522  /**
523   * For internal use.
524   *
525   * @since 2.5
526   */
527  public Snapshot setPeriod3Date(Date period3Date) {
528    this.period3Date = period3Date;
529    return this;
530  }
531
532  public Date getPeriod4Date() {
533    return period4Date;
534  }
535
536  /**
537   * For internal use.
538   *
539   * @since 2.5
540   */
541  public Snapshot setPeriod4Date(Date period4Date) {
542    this.period4Date = period4Date;
543    return this;
544  }
545
546  public Date getPeriod5Date() {
547    return period5Date;
548  }
549
550  /**
551   * For internal use.
552   *
553   * @since 2.5
554   */
555  public Snapshot setPeriod5Date(Date period5Date) {
556    this.period5Date = period5Date;
557    return this;
558  }
559
560  /**
561   * For internal use.
562   *
563   * @since 2.5
564   */
565  public Snapshot setPeriodMode(int periodIndex, String s) {
566    switch (periodIndex) {
567      case 1:
568        period1Mode = s;
569        break;
570      case 2:
571        period2Mode = s;
572        break;
573      case 3:
574        period3Mode = s;
575        break;
576      case 4:
577        period4Mode = s;
578        break;
579      case 5:
580        period5Mode = s;
581        break;
582      default:
583        throw new IndexOutOfBoundsException("Index of Snapshot.periodMode is between 1 and 5");
584    }
585    return this;
586  }
587
588  public String getPeriodMode(int index) {
589    switch (index) {
590      case 1:
591        return period1Mode;
592      case 2:
593        return period2Mode;
594      case 3:
595        return period3Mode;
596      case 4:
597        return period4Mode;
598      case 5:
599        return period5Mode;
600      default:
601        throw new IndexOutOfBoundsException("Index of Snapshot.periodMode is between 1 and 5");
602    }
603  }
604
605  /**
606   * For internal use.
607   *
608   * @since 2.5
609   */
610  public Snapshot setPeriodModeParameter(int periodIndex, String s) {
611    switch (periodIndex) {
612      case 1:
613        period1Param = s;
614        break;
615      case 2:
616        period2Param = s;
617        break;
618      case 3:
619        period3Param = s;
620        break;
621      case 4:
622        period4Param = s;
623        break;
624      case 5:
625        period5Param = s;
626        break;
627      default:
628        throw new IndexOutOfBoundsException("Index of Snapshot.periodModeParameter is between 1 and 5");
629    }
630    return this;
631  }
632
633  public String getPeriodModeParameter(int periodIndex) {
634    switch (periodIndex) {
635      case 1:
636        return period1Param;
637      case 2:
638        return period2Param;
639      case 3:
640        return period3Param;
641      case 4:
642        return period4Param;
643      case 5:
644        return period5Param;
645      default:
646        throw new IndexOutOfBoundsException("Index of Snapshot.periodModeParameter is between 1 and 5");
647    }
648  }
649
650  /**
651   * For internal use.
652   *
653   * @since 2.5
654   */
655  public Snapshot setPeriodDate(int periodIndex, Date d) {
656    switch (periodIndex) {
657      case 1:
658        period1Date = d;
659        break;
660      case 2:
661        period2Date = d;
662        break;
663      case 3:
664        period3Date = d;
665        break;
666      case 4:
667        period4Date = d;
668        break;
669      case 5:
670        period5Date = d;
671        break;
672      default:
673        throw new IndexOutOfBoundsException("Index of Snapshot.periodDate is between 1 and 5");
674    }
675    return this;
676  }
677
678  public Date getPeriodDate(int periodIndex) {
679    switch (periodIndex) {
680      case 1:
681        return period1Date;
682      case 2:
683        return period2Date;
684      case 3:
685        return period3Date;
686      case 4:
687        return period4Date;
688      case 5:
689        return period5Date;
690      default:
691        throw new IndexOutOfBoundsException("Index of Snapshot.periodDate is between 1 and 5");
692    }
693  }
694
695  @Override
696  public boolean equals(Object obj) {
697    if (!(obj instanceof Snapshot)) {
698      return false;
699    }
700    if (this == obj) {
701      return true;
702    }
703    Snapshot other = (Snapshot) obj;
704    return new EqualsBuilder()
705        .append(resourceId, other.getResourceId())
706        .append(createdAt, other.getCreatedAt())
707        .isEquals();
708  }
709
710  @Override
711  public int hashCode() {
712    return new HashCodeBuilder(17, 37)
713        .append(resourceId)
714        .append(createdAt)
715        .toHashCode();
716  }
717
718  @Override
719  public String toString() {
720    return new ReflectionToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).toString();
721  }
722}