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