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