PageRenderTime 50ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/betterrev/app/models/Contribution.java

https://bitbucket.org/danielbryant_uk/betterrev
Java | 237 lines | 173 code | 49 blank | 15 comment | 16 complexity | e785a08477c99735f413bb1129edf11d MD5 | raw file
  1. package models;
  2. import com.avaje.ebean.validation.NotNull;
  3. import com.google.common.base.Objects;
  4. import org.joda.time.DateTime;
  5. import play.data.validation.Constraints.Required;
  6. import play.db.ebean.Model;
  7. import play.utils.dao.BasicModel;
  8. import utils.BetterrevConfiguration;
  9. import utils.FetchDiffFilesString;
  10. import javax.annotation.Nonnull;
  11. import javax.persistence.CascadeType;
  12. import javax.persistence.Entity;
  13. import javax.persistence.EnumType;
  14. import javax.persistence.Enumerated;
  15. import javax.persistence.GeneratedValue;
  16. import javax.persistence.Id;
  17. import javax.persistence.ManyToMany;
  18. import javax.persistence.ManyToOne;
  19. import javax.persistence.OneToMany;
  20. import java.io.File;
  21. import java.util.ArrayList;
  22. import java.util.Collection;
  23. import java.util.HashSet;
  24. import java.util.List;
  25. import java.util.Set;
  26. import static javax.persistence.GenerationType.IDENTITY;
  27. import static utils.FilenameExtractor.extractFilenamesFromPullRequestDiffText;
  28. /**
  29. * Contribution entity that is in essence a BetterRev enhanced version of a DVCS
  30. * pullrequest.<br/>
  31. * <br/>
  32. * For information here that corresponds to bitbucket information the bitbucket
  33. * pullrequest is the canonical source. e.g. createdOn is the creation date of
  34. * the pull request, not this object.
  35. */
  36. @Entity
  37. public class Contribution extends Model implements BasicModel<Long> {
  38. private static final long serialVersionUID = 188525469548289315L;
  39. private static String owner = BetterrevConfiguration.INST.owner();
  40. public static Model.Finder<Long, Contribution> find = new Model.Finder<>(Long.class, Contribution.class);
  41. @GeneratedValue(strategy = IDENTITY)
  42. @Id
  43. public Long id;
  44. @NotNull
  45. @Required
  46. public String repositoryId;
  47. @NotNull
  48. @Required
  49. public String pullRequestId;
  50. @NotNull
  51. @Required
  52. public String name;
  53. public String description;
  54. @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
  55. public List<ContributionEvent> contributionEvents = new ArrayList<>();
  56. @NotNull
  57. @Enumerated(EnumType.STRING)
  58. public State state;
  59. @ManyToMany(cascade = CascadeType.ALL)
  60. public Set<Tag> tags = new HashSet<>();
  61. @ManyToOne
  62. public User requester;
  63. @ManyToMany(cascade = CascadeType.ALL)
  64. public Set<Mentor> mentors = new HashSet<>();
  65. @NotNull
  66. public DateTime createdOn;
  67. @NotNull
  68. public DateTime updatedOn;
  69. @NotNull
  70. public String branchName;
  71. public Contribution(String repositoryId, String pullRequestId, String name, String description, User requester,
  72. DateTime createdOn, DateTime updatedOn, String branchName) {
  73. this.repositoryId = repositoryId;
  74. this.pullRequestId = pullRequestId;
  75. this.name = name;
  76. this.description = description;
  77. this.requester = requester;
  78. this.createdOn = createdOn;
  79. this.updatedOn = updatedOn;
  80. this.branchName = branchName;
  81. this.state = State.NULL;
  82. String diffFilesString = FetchDiffFilesString.from(pullRequestUrlForOwner());
  83. this.mentors = evaluateMentorsFrom(diffFilesString);
  84. }
  85. public boolean wasUpdatedBefore(DateTime updated) {
  86. return this.updatedOn.isBefore(updated);
  87. }
  88. public boolean hasContributionEventWith(@Nonnull ContributionEventType contributionEventType) {
  89. boolean eventFound = false;
  90. for (ContributionEvent contributionEvent : contributionEvents) {
  91. if (contributionEventType.equals(contributionEvent.contributionEventType)) {
  92. eventFound = true;
  93. break;
  94. }
  95. }
  96. return eventFound;
  97. }
  98. @Override
  99. public int hashCode() {
  100. return Objects.hashCode(pullRequestId, repositoryId);
  101. }
  102. @Override
  103. public boolean equals(Object obj) {
  104. if (this == obj) {
  105. return true;
  106. }
  107. if (!super.equals(obj)) {
  108. return false;
  109. }
  110. if (getClass() != obj.getClass()) {
  111. return false;
  112. }
  113. Contribution other = (Contribution) obj;
  114. return Objects.equal(pullRequestId, other.pullRequestId) && Objects.equal(repositoryId, other.repositoryId);
  115. }
  116. // https://bitbucket.org/api/2.0/repositories/AdoptOpenJDK/better-test-repo/pullrequests/1/diff
  117. public final String pullRequestUrlForOwner() {
  118. return String.format("https://bitbucket.org/api/2.0/repositories/%s/%s/pullrequests/%s/diff",
  119. owner, repositoryId, pullRequestId);
  120. }
  121. // https://bitbucket.org/api/2.0/repositories/richardwarburton/better-test-repo/pullrequests/1/diff
  122. public String pullRequestUrl() {
  123. return String.format("https://bitbucket.org/api/2.0/repositories/%s/%s/pullrequests/%s/diff",
  124. requester.bitbucketUserName, repositoryId, pullRequestId);
  125. }
  126. public final Set<Mentor> evaluateMentorsFrom(String inDiffFileString) {
  127. Set<String> filesChanged = extractFilenamesFromPullRequestDiffText(inDiffFileString);
  128. Set<Mentor> results = new HashSet<>();
  129. results.addAll(Mentor.findRelevantMentors(repositoryId, filesChanged));
  130. return results;
  131. }
  132. public String mentorEmailsUrl() {
  133. StringBuilder mentorEmailsUrlBuilder = new StringBuilder().append("mailto:");
  134. int numberOfEmailsAdded = 0;
  135. int numberOfMentors = mentors.size();
  136. for (Mentor mentor : mentors) {
  137. mentorEmailsUrlBuilder.append(mentor.email);
  138. numberOfEmailsAdded++;
  139. if (numberOfEmailsAdded < numberOfMentors) {
  140. mentorEmailsUrlBuilder.append(",");
  141. }
  142. }
  143. return mentorEmailsUrlBuilder.toString();
  144. }
  145. public String requestersRepositoryUrl() {
  146. return String.format("ssh://hg@bitbucket.org/%s/%s", requester.bitbucketUserName, repositoryId);
  147. }
  148. /**
  149. * Eg: 'corba', 'hotspot', '.'
  150. */
  151. public String openJdkRepoName() {
  152. String[] split = repositoryId.split("-");
  153. // Subrepo case
  154. if (split.length == 2) {
  155. return split[1];
  156. }
  157. // Top level repo case
  158. return ".";
  159. }
  160. public static Contribution findByBitbucketIds(String repositoryId, String requestId) {
  161. return find.where().eq("repositoryId", repositoryId).eq("pullRequestId", requestId).findUnique();
  162. }
  163. public File webrevLocation() {
  164. String relativePath = String.format("public/webrevs/webrev-%s-%s/", repositoryId, pullRequestId);
  165. return new File(relativePath).getAbsoluteFile();
  166. }
  167. public boolean isDefaultBranch() {
  168. return "default".equals(branchName);
  169. }
  170. @Override
  171. public Long getKey() {
  172. return id;
  173. }
  174. @Override
  175. public void setKey(Long key) {
  176. id = key;
  177. }
  178. public Collection<ContributionEvent> getContributionEventWithType(ContributionEventType contributionEventType) {
  179. List<ContributionEvent> filteredContributionEvents = new ArrayList<>();
  180. for (ContributionEvent contributionEvent : contributionEvents) {
  181. if (contributionEvent.contributionEventType != null
  182. && contributionEvent.contributionEventType.equals(contributionEventType)) {
  183. filteredContributionEvents.add(contributionEvent);
  184. }
  185. }
  186. return filteredContributionEvents;
  187. }
  188. }