Skip to content

Commit

Permalink
Implement voting
Browse files Browse the repository at this point in the history
Fixes #200
  • Loading branch information
1-alex98 committed Apr 10, 2018
1 parent 8b2c06c commit 2caa6af
Show file tree
Hide file tree
Showing 15 changed files with 457 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/main/java/com/faforever/api/data/domain/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.Setter;
import org.hibernate.annotations.BatchSize;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
Expand All @@ -30,6 +31,7 @@ public class Player extends Login {
private List<ClanMembership> clanMemberships;
private List<NameRecord> names;
private List<AvatarAssignment> avatarAssignments;
private List<Vote> votes;

@OneToOne(mappedBy = "player", fetch = FetchType.LAZY)
@BatchSize(size = 1000)
Expand Down Expand Up @@ -78,4 +80,10 @@ public List<AvatarAssignment> getAvatarAssignments() {
public String toString() {
return "Player(" + getId() + ", " + getLogin() + ")";
}

@Transient
@OneToMany(mappedBy = "player", cascade = CascadeType.ALL, orphanRemoval = true)
public List<Vote> getVotes() {
return votes;
}
}
46 changes: 46 additions & 0 deletions src/main/java/com/faforever/api/data/domain/Vote.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.faforever.api.data.domain;

import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.ReadPermission;
import lombok.Setter;
import org.hibernate.validator.constraints.NotEmpty;

import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import java.util.List;

@Entity
@Table(name = "vote")
@Include(type = Vote.TYPE_NAME)
@ReadPermission(expression = "Prefab.Role.None")
@Setter
public class Vote extends AbstractEntity {
public static final String TYPE_NAME = "vote";

private Player player;
private VotingSubject votingSubject;
private List<VotingAnswer> votingAnswers;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "player_id")
public Player getPlayer() {
return player;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "voting_subject_id")
public VotingSubject getVotingSubject() {
return votingSubject;
}

@NotEmpty(message = "At least one answer must be given, other wise vote is senseless")
@OneToMany(mappedBy = "vote", cascade = CascadeType.ALL, orphanRemoval = true)
public List<VotingAnswer> getVotingAnswers() {
return votingAnswers;
}
}
42 changes: 42 additions & 0 deletions src/main/java/com/faforever/api/data/domain/VotingAnswer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.faforever.api.data.domain;

import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.ReadPermission;
import lombok.Setter;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "voting_answer")
@Include(type = VotingAnswer.TYPE_NAME)
@ReadPermission(expression = "Prefab.Role.None")
@Setter
public class VotingAnswer extends AbstractEntity {
public static final String TYPE_NAME = "votingAnswer";

private VotingQuestion votingQuestion;
private Vote vote;
private VotingChoice votingChoice;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "voting_question_id")
public VotingQuestion getVotingQuestion() {
return votingQuestion;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "vote_id")
public Vote getVote() {
return vote;
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "voting_choice_id")
public VotingChoice getVotingChoice() {
return votingChoice;
}
}
62 changes: 62 additions & 0 deletions src/main/java/com/faforever/api/data/domain/VotingChoice.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.faforever.api.data.domain;

import com.faforever.api.data.checks.permission.IsModerator;
import com.yahoo.elide.annotation.CreatePermission;
import com.yahoo.elide.annotation.DeletePermission;
import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.ReadPermission;
import com.yahoo.elide.annotation.SharePermission;
import com.yahoo.elide.annotation.UpdatePermission;
import lombok.Setter;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import java.util.List;

@Entity
@Table(name = "voting_choice")
@ReadPermission(expression = "Prefab.Role.All")
@SharePermission(expression = IsModerator.EXPRESSION)
@DeletePermission(expression = IsModerator.EXPRESSION)
@UpdatePermission(expression = IsModerator.EXPRESSION)
@CreatePermission(expression = IsModerator.EXPRESSION)
@Include(rootLevel = true, type = VotingChoice.TYPE_NAME)
@Setter
public class VotingChoice extends AbstractEntity {
public static final String TYPE_NAME = "votingChoice";
private String name;
private String description;
private VotingQuestion votingQuestion;
private List<VotingAnswer> votingAnswers;

@NotNull
@Column(name = "name", nullable = false)
public String getName() {
return name;
}

@Column(name = "description")
public String getDescription() {
return description;
}

@JoinColumn(name = "voting_question_id")
@ManyToOne(fetch = FetchType.LAZY)
public VotingQuestion getVotingQuestion() {
return votingQuestion;
}

@Transient
@OneToMany(mappedBy = "votingChoice", cascade = CascadeType.ALL, orphanRemoval = true)
public List<VotingAnswer> getVotingAnswers() {
return votingAnswers;
}
}
66 changes: 66 additions & 0 deletions src/main/java/com/faforever/api/data/domain/VotingQuestion.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.faforever.api.data.domain;

import com.faforever.api.data.checks.permission.IsModerator;
import com.yahoo.elide.annotation.CreatePermission;
import com.yahoo.elide.annotation.DeletePermission;
import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.ReadPermission;
import com.yahoo.elide.annotation.SharePermission;
import com.yahoo.elide.annotation.UpdatePermission;
import lombok.Setter;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import java.util.List;

@Entity
@Table(name = "voting_question")
@ReadPermission(expression = "Prefab.Role.All")
@SharePermission(expression = IsModerator.EXPRESSION)
@DeletePermission(expression = IsModerator.EXPRESSION)
@UpdatePermission(expression = IsModerator.EXPRESSION)
@CreatePermission(expression = IsModerator.EXPRESSION)
@Include(rootLevel = true, type = VotingQuestion.TYPE_NAME)
@Setter
public class VotingQuestion extends AbstractEntity {
public static final String TYPE_NAME = "votingQuestion";
private VotingSubject votingSubject;
private String question;
private String description;
private int maxAnswers;
private List<VotingChoice> votingChoices;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "voting_subject_id")
public VotingSubject getVotingSubject() {
return votingSubject;
}

@NotNull
@Column(name = "question", nullable = false)
public String getQuestion() {
return question;
}

@Column(name = "description")
public String getDescription() {
return description;
}

@Column(name = "max_answers")
public int getMaxAnswers() {
return maxAnswers;
}

@OneToMany(mappedBy = "votingQuestion", cascade = CascadeType.ALL, orphanRemoval = true)
public List<VotingChoice> getVotingChoices() {
return votingChoices;
}
}
90 changes: 90 additions & 0 deletions src/main/java/com/faforever/api/data/domain/VotingSubject.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.faforever.api.data.domain;

import com.faforever.api.data.checks.permission.IsModerator;
import com.yahoo.elide.annotation.CreatePermission;
import com.yahoo.elide.annotation.DeletePermission;
import com.yahoo.elide.annotation.Include;
import com.yahoo.elide.annotation.ReadPermission;
import com.yahoo.elide.annotation.SharePermission;
import com.yahoo.elide.annotation.UpdatePermission;
import lombok.Setter;
import org.hibernate.validator.constraints.NotEmpty;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.DecimalMin;
import javax.validation.constraints.NotNull;
import java.time.OffsetDateTime;
import java.util.List;

@Entity
@Table(name = "voting_subject")
@Include(rootLevel = true, type = VotingSubject.TYPE_NAME)
@ReadPermission(expression = "Prefab.Role.All")
@SharePermission(expression = IsModerator.EXPRESSION)
@DeletePermission(expression = IsModerator.EXPRESSION)
@UpdatePermission(expression = IsModerator.EXPRESSION)
@CreatePermission(expression = IsModerator.EXPRESSION)
@Setter
public class VotingSubject extends AbstractEntity {
public static final String TYPE_NAME = "votingSubject";

private String name;
private String topicUrl;
private OffsetDateTime beginOfVoteTime;
private OffsetDateTime endOfVoteTime;
private int minGamesToVote;
private String description;
private List<Vote> votes;
private List<VotingQuestion> votingQuestions;

@Column(name = "name")
@NotNull
public String getName() {
return name;
}

@NotNull
@Column(name = "begin_of_vote_time")
public OffsetDateTime getBeginOfVoteTime() {
return beginOfVoteTime;
}

@NotNull
@Column(name = "end_of_vote_time")
public OffsetDateTime getEndOfVoteTime() {
return endOfVoteTime;
}

@DecimalMin("0")
@Column(name = "min_games_to_vote")
public int getMinGamesToVote() {
return minGamesToVote;
}

@Column(name = "description")
public String getDescription() {
return description;
}

@Column(name = "topic_url")
public String getTopicUrl() {
return topicUrl;
}

@Transient
@OneToMany(mappedBy = "votingSubject", cascade = CascadeType.ALL, orphanRemoval = true)
public List<Vote> getVotes() {
return votes;
}

@NotEmpty(message = "A subject needs at least one Question")
@OneToMany(mappedBy = "votingSubject", cascade = CascadeType.ALL, orphanRemoval = true)
public List<VotingQuestion> getVotingQuestions() {
return votingQuestions;
}
}
5 changes: 4 additions & 1 deletion src/main/java/com/faforever/api/error/ErrorCode.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,10 @@ public enum ErrorCode {
AVATAR_NAME_CONFLICT(168, "Invalid avatar file name", "Avatar file name ''{0}'' already exists."),
AVATAR_IN_USE(169, "Avatar in use", "Could not delete avatar {0, number}. Avatar still in use."),
ENTITY_NOT_FOUND(170, "Entity not found", "Entity with id: {0} not found."),
INVALID_AVATAR_DIMENSION(171, "Invalid avatar dimensions", "Avatar dimensions must be {0, number}x{1, number}, was: {2, number}x{3, number}.");
INVALID_AVATAR_DIMENSION(171, "Invalid avatar dimensions", "Avatar dimensions must be {0, number}x{1, number}, was: {2, number}x{3, number}."),
VOTED_TWICE(172, "You can not vote twice", "There was a vote found for your user and this subject"),
NOT_ENOUGH_GAMES(173, "You have not got enough games to vote", "You have '{0}' games but you need '{1}'"),
TOO_MANY_ANSWERS(174, "You have to much answers selected in question", "You selected '{0}' but you can only select '{1}'");

private final int code;
private final String title;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.faforever.api.game;

import com.faforever.api.data.domain.GamePlayerStats;
import com.faforever.api.data.domain.Player;
import org.springframework.data.jpa.repository.JpaRepository;

public interface GamePlayerStatsRepository extends JpaRepository<GamePlayerStats, Integer> {
int countByPlayer(Player player);
}
5 changes: 4 additions & 1 deletion src/main/java/com/faforever/api/security/OAuthScope.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ public enum OAuthScope {
UPLOAD_MOD(OAuthScope._UPLOAD_MOD, "Upload mods"),
UPLOAD_AVATAR(OAuthScope._UPLOAD_AVATAR, "Upload avatars"),
WRITE_ACCOUNT_DATA(OAuthScope._WRITE_ACCOUNT_DATA, "Edit account data"),
EDIT_CLAN_DATA(OAuthScope._EDIT_CLAN_DATA, "Edit clan data");
EDIT_CLAN_DATA(OAuthScope._EDIT_CLAN_DATA, "Edit clan data"),
VOTE(OAuthScope._Vote, "Vote");


public static final String _PUBLIC_PROFILE = "public_profile";
public static final String _READ_ACHIEVEMENTS = "read_achievements";
Expand All @@ -27,6 +29,7 @@ public enum OAuthScope {
public static final String _UPLOAD_AVATAR = "upload_avatar";
public static final String _WRITE_ACCOUNT_DATA = "write_account_data";
public static final String _EDIT_CLAN_DATA = "edit_clan_data";
public static final String _Vote = "vote";

private static final Map<String, OAuthScope> fromString;

Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/faforever/api/voting/VoteRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.faforever.api.voting;

import com.faforever.api.data.domain.Player;
import com.faforever.api.data.domain.Vote;
import com.faforever.api.data.domain.VotingSubject;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface VoteRepository extends JpaRepository<Vote, Integer> {
Optional<Vote> findByPlayerAndVotingSubject(Player player, VotingSubject votingSubject);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.faforever.api.voting;

import com.faforever.api.data.domain.VotingAnswer;
import org.springframework.data.jpa.repository.JpaRepository;

public interface VotingAnswerRepository extends JpaRepository<VotingAnswer, Integer> {
}
Loading

0 comments on commit 2caa6af

Please sign in to comment.